Skip to content
赞助商赞助商赞助商
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

编译资源 (Mix)

介绍

Laravel Mix 提供了一种流畅的 API,用于为您的 Laravel 应用程序定义 Webpack 构建步骤,使用多种常见的 CSS 和 JavaScript 预处理器。通过简单的方法链,您可以流畅地定义您的资源管道。例如:

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

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

安装与设置

安装 Node

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

php
node -v
npm -v

默认情况下,Laravel Homestead 包含您所需的一切;然而,如果您不使用 Vagrant,您可以通过 下载页面 的简单图形安装程序轻松安装最新版本的 Node 和 NPM。

Laravel Mix

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

php
npm install

运行 Mix

Mix 是 Webpack 之上的一个配置层,因此要运行您的 Mix 任务,您只需执行默认 Laravel package.json 文件中包含的一个 NPM 脚本:

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

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

监视资源的变化

npm run watch 命令将在您的终端中持续运行,并监视所有相关文件的变化。当检测到变化时,Webpack 将自动重新编译您的资源:

php
npm run watch

您可能会发现,在某些环境中,当文件发生变化时,Webpack 并没有更新。如果在您的系统上出现这种情况,请考虑使用 watch-poll 命令:

php
npm run watch-poll

处理样式表

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

Less

less 方法可用于将 Less 编译为 CSS。让我们将主要的 app.less 文件编译为 public/css/app.css

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

可以多次调用 less 方法来编译多个文件:

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

如果您希望自定义编译 CSS 的文件名,可以将完整的文件路径作为 less 方法的第二个参数传递:

php
mix.less('resources/less/app.less', 'public/stylesheets/styles.css');

如果您需要覆盖 底层 Less 插件选项,可以将对象作为第三个参数传递给 mix.less()

php
mix.less('resources/less/app.less', 'public/css', {
    strictMath: true
});

Sass

sass 方法允许您将 Sass 编译为 CSS。您可以这样使用该方法:

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

同样,像 less 方法一样,您可以将多个 Sass 文件编译为各自的 CSS 文件,甚至可以自定义生成的 CSS 的输出目录:

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

可以提供额外的 Node-Sass 插件选项 作为第三个参数:

php
mix.sass('resources/sass/app.sass', 'public/css', {
    precision: 5
});

Stylus

与 Less 和 Sass 类似,stylus 方法允许您将 Stylus 编译为 CSS:

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

您还可以安装额外的 Stylus 插件,例如 Rupture。首先,通过 NPM 安装所需的插件 (npm install rupture),然后在调用 mix.stylus() 时引用它:

php
mix.stylus('resources/stylus/app.styl', 'public/css', {
    use: [
        require('rupture')()
    ]
});

PostCSS

PostCSS 是一个强大的工具,用于转换您的 CSS,Laravel Mix 默认包含它。默认情况下,Mix 利用流行的 Autoprefixer 插件自动应用所有必要的 CSS3 浏览器前缀。然而,您可以自由添加任何适合您应用程序的额外插件。首先,通过 NPM 安装所需的插件,然后在 webpack.mix.js 文件中引用它:

php
mix.sass('resources/sass/app.scss', 'public/css')
    .options({
        postCss: [
            require('postcss-css-variables')()
        ]
    });

纯 CSS

如果您只想将一些纯 CSS 样式表合并为一个文件,可以使用 styles 方法。

php
mix.styles([
    'public/css/vendor/normalize.css',
    'public/css/vendor/videojs.css'
], 'public/css/all.css');

URL 处理

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

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

NOTE

任何给定 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/app/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 2015、模块打包、压缩和合并纯 JavaScript 文件。更好的是,这一切都能无缝工作,无需任何自定义配置:

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

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

  • ES2015 语法。
  • 模块
  • .vue 文件的编译。
  • 生产环境的压缩。

供应商提取

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

如果您打算频繁更新应用程序的 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>

React

Mix 可以自动安装 React 支持所需的 Babel 插件。要开始,请将您的 mix.js() 调用替换为 mix.react()

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

在后台,Mix 将下载并包含适当的 babel-preset-react Babel 插件。

Vanilla JS

与使用 mix.styles() 合并样式表类似,您还可以使用 scripts() 方法合并和压缩任意数量的 JavaScript 文件:

php
mix.scripts([
    'public/js/admin.js',
    'public/js/dashboard.js'
], 'public/js/all.js');

此选项对于不需要 Webpack 编译 JavaScript 的遗留项目特别有用。

NOTE

mix.scripts() 的一个轻微变体是 mix.babel()。其方法签名与 scripts 相同;然而,连接的文件将接收 Babel 编译,这将任何 ES2015 代码转换为所有浏览器都能理解的普通 JavaScript。

自定义 Webpack 配置

在后台,Laravel Mix 引用一个预配置的 webpack.config.js 文件,以便您快速启动并运行。偶尔,您可能需要手动修改此文件。您可能有一个需要引用的特殊加载器或插件,或者您可能更喜欢使用 Stylus 而不是 Sass。在这种情况下,您有两个选择:

合并自定义配置

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

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

自定义配置文件

如果您希望完全自定义您的 Webpack 配置,请将 node_modules/laravel-mix/setup/webpack.config.js 文件复制到项目的根目录。接下来,将 package.json 文件中的所有 --config 引用指向新复制的配置文件。如果您选择这种自定义方法,Mix 的 webpack.config.js 的任何未来上游更新都必须手动合并到您的自定义文件中。

复制文件和目录

copy 方法可用于将文件和目录复制到新位置。当 node_modules 目录中的特定资源需要重新定位到 public 文件夹时,这可能很有用。

php
mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');

在复制目录时,copy 方法将扁平化目录的结构。要保持目录的原始结构,您应该使用 copyDirectory 方法:

php
mix.copyDirectory('resources/img', 'public/img');

版本控制 / 缓存清除

许多开发人员在编译的资源后缀上添加时间戳或唯一标记,以强制浏览器加载新鲜的资源,而不是提供陈旧的代码副本。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 production 时运行:

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 前缀:

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

Browsersync 重新加载

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

php
mix.browserSync('my-domain.test');

// 或者...

// https://browsersync.io/docs/options
mix.browserSync({
    proxy: 'my-domain.test'
});

您可以将字符串(代理)或对象(BrowserSync 设置)传递给此方法。接下来,使用 npm run watch 命令启动 Webpack 的开发服务器。现在,当您修改脚本或 PHP 文件时,浏览器会立即刷新页面以反映您的更改。

环境变量

您可以通过在 .env 文件中为键添加 MIX_ 前缀来将环境变量注入 Mix:

php
MIX_SENTRY_DSN_PUBLIC=http://example.com

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

php
process.env.MIX_SENTRY_DSN_PUBLIC

通知

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

php
mix.disableNotifications();