Skip to content

编译资源 (Mix)

介绍

Laravel Mix 是由 Laracasts 创始人 Jeffrey Way 开发的一个包,它为定义 Laravel 应用程序的 webpack 构建步骤提供了一个流畅的 API,使用了几种常见的 CSS 和 JavaScript 预处理器。

换句话说,Mix 使得编译和压缩应用程序的 CSS 和 JavaScript 文件变得轻而易举。通过简单的方法链,您可以流畅地定义您的资源管道。例如:

php
mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css');

如果您曾经对如何开始使用 webpack 和资源编译感到困惑和不知所措,您会喜欢 Laravel Mix。然而,在开发应用程序时,您并不需要使用它;您可以自由选择任何资源管道工具,甚至可以不使用任何工具。

lightbulb

如果您需要一个使用 Laravel 和 Tailwind CSS 构建应用程序的快速入门,请查看我们的 应用程序启动套件

安装与设置

安装 Node

在运行 Mix 之前,您必须首先确保您的机器上安装了 Node.js 和 NPM:

php
node -v
npm -v

您可以通过 Node 官方网站 的简单图形安装程序轻松安装最新版本的 Node 和 NPM。或者,如果您使用 Laravel Sail,您可以通过 Sail 调用 Node 和 NPM:

php
./sail node -v
./sail npm -v

安装 Laravel Mix

剩下的唯一步骤是安装 Laravel Mix。在 Laravel 的全新安装中,您会在目录结构的根目录中找到一个 package.json 文件。默认的 package.json 文件已经包含了开始使用 Laravel Mix 所需的一切。可以将此文件视为 composer.json 文件,但它定义的是 Node 依赖项而不是 PHP 依赖项。您可以通过运行以下命令安装它引用的依赖项:

php
npm install

运行 Mix

Mix 是 webpack 之上的一个配置层,因此要运行您的 Mix 任务,您只需执行默认 Laravel package.json 文件中包含的 NPM 脚本之一。当您运行 devproduction 脚本时,所有应用程序的 CSS 和 JavaScript 资源将被编译并放置在应用程序的 public 目录中:

php
// 运行所有 Mix 任务...
npm run dev

// 运行所有 Mix 任务并压缩输出...
npm run prod

监视资源的更改

npm run watch 命令将在您的终端中继续运行,并监视所有相关的 CSS 和 JavaScript 文件的更改。当检测到这些文件之一的更改时,Webpack 将自动重新编译您的资源:

php
npm run watch

在某些本地开发环境中,Webpack 可能无法检测到您的文件更改。如果您的系统上出现这种情况,请考虑使用 watch-poll 命令:

php
npm run watch-poll

处理样式表

应用程序的 webpack.mix.js 文件是所有资源编译的入口点。可以将其视为 webpack 之上的轻量配置包装器。Mix 任务可以链接在一起,以定义资源应如何编译。

Tailwind CSS

Tailwind CSS 是一个现代的、以实用为先的框架,用于在不离开 HTML 的情况下构建出色的网站。让我们深入了解如何在 Laravel 项目中使用 Laravel Mix 开始使用它。首先,我们应该使用 NPM 安装 Tailwind 并生成我们的 Tailwind 配置文件:

php
npm install

npm install -D tailwindcss

npx tailwindcss init

init 命令将生成一个 tailwind.config.js 文件。此文件的 content 部分允许您配置所有 HTML 模板、JavaScript 组件和任何其他包含 Tailwind 类名的源文件的路径,以便在生产 CSS 构建中删除未在这些文件中使用的任何 CSS 类:

js
content: [
    './storage/framework/views/*.php',
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
],

接下来,您应该将 Tailwind 的每个“层”添加到应用程序的 resources/css/app.css 文件中:

css
@tailwind base;
@tailwind components;
@tailwind utilities;

一旦您配置了 Tailwind 的层,您就可以更新应用程序的 webpack.mix.js 文件以编译您的 Tailwind 驱动的 CSS:

js
mix.js('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        require('tailwindcss'),
    ]);

最后,您应该在应用程序的主布局模板中引用您的样式表。许多应用程序选择将此模板存储在 resources/views/layouts/app.blade.php 中。此外,请确保添加响应式视口 meta 标签(如果尚未存在):

html
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link href="/css/app.css" rel="stylesheet">
</head>

PostCSS

PostCSS 是一个强大的 CSS 转换工具,Laravel Mix 开箱即用地包含了它。默认情况下,Mix 利用流行的 Autoprefixer 插件自动应用所有必要的 CSS3 供应商前缀。然而,您可以自由添加任何适合您应用程序的其他插件。

首先,通过 NPM 安装所需的插件,并在调用 Mix 的 postCss 方法时将其包含在插件数组中。postCss 方法接受 CSS 文件的路径作为第一个参数,并接受编译文件应放置的目录作为第二个参数:

php
mix.postCss('resources/css/app.css', 'public/css', [
    require('postcss-custom-properties')
]);

或者,您可以在没有其他插件的情况下执行 postCss 以实现简单的 CSS 编译和压缩:

php
mix.postCss('resources/css/app.css', 'public/css');

Sass

sass 方法允许您将 Sass 编译为浏览器可以理解的 CSS。sass 方法接受 Sass 文件的路径作为第一个参数,并接受编译文件应放置的目录作为第二个参数:

php
mix.sass('resources/sass/app.scss', 'public/css');

您可以将多个 Sass 文件编译为各自的 CSS 文件,甚至可以通过多次调用 sass 方法自定义生成的 CSS 的输出目录:

php
mix.sass('resources/sass/app.sass', 'public/css')
    .sass('resources/sass/admin.sass', 'public/css/admin');

URL 处理

由于 Laravel Mix 构建在 webpack 之上,因此了解一些 webpack 概念很重要。对于 CSS 编译,webpack 将重写和优化样式表中的任何 url() 调用。虽然这听起来可能有些奇怪,但它是一个非常强大的功能。想象一下,我们想要编译包含相对 URL 的图像的 Sass:

php
.example {
    background: url('../images/example.png');
}
exclamation

任何给定 url() 的绝对路径将被排除在 URL 重写之外。例如,url('/images/thing.png')url('http://example.com/images/thing.png') 不会被修改。

默认情况下,Laravel Mix 和 webpack 将找到 example.png,将其复制到您的 public/images 文件夹中,然后重写生成的样式表中的 url()。因此,编译后的 CSS 将是:

php
.example {
    background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
}

尽管此功能可能非常有用,但您的现有文件夹结构可能已经配置为您喜欢的方式。如果是这种情况,您可以像这样禁用 url() 重写:

php
mix.sass('resources/sass/app.scss', 'public/css').options({
    processCssUrls: false
});

通过在 webpack.mix.js 文件中添加此项,Mix 将不再匹配任何 url() 或将资源复制到您的公共目录。换句话说,编译后的 CSS 将看起来就像您最初输入的那样:

php
.example {
    background: url("../images/thing.png");
}

源映射

虽然默认情况下禁用,但可以通过在 webpack.mix.js 文件中调用 mix.sourceMaps() 方法来激活源映射。尽管这会带来编译/性能成本,但这将为您在使用编译资源时提供额外的调试信息:

php
mix.js('resources/js/app.js', 'public/js')
    .sourceMaps();

源映射的样式

Webpack 提供了多种 源映射样式。默认情况下,Mix 的源映射样式设置为 eval-source-map,这提供了快速的重建时间。如果您想更改映射样式,可以使用 sourceMaps 方法:

php
let productionSourceMaps = false;

mix.js('resources/js/app.js', 'public/js')
    .sourceMaps(productionSourceMaps, 'source-map');

处理 JavaScript

Mix 提供了多种功能来帮助您处理 JavaScript 文件,例如编译现代 ECMAScript、模块打包、压缩和连接普通 JavaScript 文件。更好的是,这一切都可以无缝工作,无需任何自定义配置:

php
mix.js('resources/js/app.js', 'public/js');

通过这一行代码,您现在可以利用:

  • 最新的 EcmaScript 语法。
  • 模块
  • 生产环境的压缩。

Vue

使用 vue 方法时,Mix 将自动安装支持 Vue 单文件组件编译所需的 Babel 插件。无需进一步配置:

php
mix.js('resources/js/app.js', 'public/js')
   .vue();

一旦您的 JavaScript 编译完成,您可以在应用程序中引用它:

html
<head>
    <!-- ... -->

    <script src="/js/app.js"></script>
</head>

React

Mix 可以自动安装支持 React 所需的 Babel 插件。要开始,请添加对 react 方法的调用:

php
mix.js('resources/js/app.jsx', 'public/js')
   .react();

在后台,Mix 将下载并包含适当的 babel-preset-react Babel 插件。一旦您的 JavaScript 编译完成,您可以在应用程序中引用它:

html
<head>
    <!-- ... -->

    <script src="/js/app.js"></script>
</head>

供应商提取

将所有应用程序特定的 JavaScript 与供应商库(如 React 和 Vue)捆绑在一起的一个潜在缺点是,它使长期缓存变得更加困难。例如,对应用程序代码的单次更新将迫使浏览器重新下载所有供应商库,即使它们没有更改。

如果您打算频繁更新应用程序的 JavaScript,您应该考虑将所有供应商库提取到自己的文件中。这样,对应用程序代码的更改将不会影响大型 vendor.js 文件的缓存。Mix 的 extract 方法使这变得轻而易举:

php
mix.js('resources/js/app.js', 'public/js')
    .extract(['vue'])

extract 方法接受一个数组,其中包含您希望提取到 vendor.js 文件中的所有库或模块。使用上面的代码片段作为示例,Mix 将生成以下文件:

  • public/js/manifest.js: Webpack 清单运行时
  • public/js/vendor.js: 您的供应商库
  • public/js/app.js: 您的应用程序代码

为了避免 JavaScript 错误,请确保按正确的顺序加载这些文件:

php
<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>

自定义 Webpack 配置

有时,您可能需要手动修改底层的 Webpack 配置。例如,您可能有一个需要引用的特殊加载器或插件。

Mix 提供了一个有用的 webpackConfig 方法,允许您合并任何简短的 Webpack 配置覆盖。这特别有吸引力,因为它不需要您复制和维护自己的 webpack.config.js 文件副本。webpackConfig 方法接受一个对象,该对象应包含您希望应用的任何 Webpack 特定配置

php
mix.webpackConfig({
    resolve: {
        modules: [
            path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
        ]
    }
});

版本控制 / 缓存清除

许多开发人员在编译的资源后缀上添加时间戳或唯一标记,以强制浏览器加载新鲜的资源,而不是提供陈旧的代码副本。Mix 可以使用 version 方法自动处理此问题。

version 方法将为所有编译文件附加一个唯一的哈希,以便更方便地进行缓存清除:

php
mix.js('resources/js/app.js', 'public/js')
    .version();

生成版本化文件后,您将不知道确切的文件名。因此,您应该在 视图 中使用 Laravel 的全局 mix 函数来加载适当的哈希资源。mix 函数将自动确定哈希文件的当前名称:

php
<script src="{{ mix('/js/app.js') }}"></script>

由于在开发中通常不需要版本化文件,您可以指示版本化过程仅在 npm run prod 期间运行:

php
mix.js('resources/js/app.js', 'public/js');

if (mix.inProduction()) {
    mix.version();
}

自定义 Mix 基础 URL

如果您的 Mix 编译资源部署到与应用程序分开的 CDN,您将需要更改 mix 函数生成的基础 URL。您可以通过在应用程序的 config/app.php 配置文件中添加 mix_url 配置选项来实现:

php
'mix_url' => env('MIX_ASSET_URL', null)

配置 Mix URL 后,mix 函数将在生成资源的 URL 时添加配置的 URL 前缀:

bash
https://cdn.example.com/js/app.js?id=1964becbdd96414518cd

Browsersync 重新加载

BrowserSync 可以自动监视您的文件更改,并将更改注入浏览器,而无需手动刷新。您可以通过调用 mix.browserSync() 方法启用对此的支持:

js
mix.browserSync('laravel.test');

可以通过将 JavaScript 对象传递给 browserSync 方法来指定 BrowserSync 选项

js
mix.browserSync({
    proxy: 'laravel.test'
});

接下来,使用 npm run watch 命令启动 webpack 的开发服务器。现在,当您修改脚本或 PHP 文件时,您可以看到浏览器立即刷新页面以反映您的更改。

环境变量

您可以通过在 .env 文件中的环境变量前加上 MIX_ 前缀,将环境变量注入到 webpack.mix.js 脚本中:

php
MIX_SENTRY_DSN_PUBLIC=http://example.com

.env 文件中定义变量后,您可以通过 process.env 对象访问它。然而,如果环境变量的值在任务运行时发生变化,您将需要重新启动任务:

php
process.env.MIX_SENTRY_DSN_PUBLIC

通知

在可用时,Mix 将在编译时自动显示操作系统通知,立即反馈编译是否成功。然而,在某些情况下,您可能希望禁用这些通知。例如,在生产服务器上触发 Mix。可以使用 disableNotifications 方法停用通知:

php
mix.disableNotifications();