编译资源 (Mix)

提供了定义 Webpack 构建步骤的 API,用于在应用中使用常见的 CSS 和 JavaScript 预处理器。通过链式调用这些简洁方法,可以流畅地定义资源管道。例如:

如果对如何开始使用 Webpack 和资源编译感到困惑和不知所措,那么你一定会喜欢 Laravel Mix。但是,你不一定非要使用它来开发应用;可以使用你喜欢的任何资源管道工具,甚至干脆不用。

安装 & 设置

安装 Node

在触发 Mix 之前,要先确保机器上已经安装了 Node.js 和 NPM。

默认情况下, Laravel Homestead 包含了你需要的所有东西;不过如果你使用 Vagrant,你也能使用从 获取的更易用的图形化安装器安装最新版本的 Node 和 NPM。

Laravel Mix

剩下的事儿就是安装 Laravel Mix。在 Laravel 的纯净安装版中,可以在目录结构的根目录中找到 文件。默认的 package.json 文件包含了起步所需的所有东西,把它想像成 composer.json 文件,只不过它是定义 Node 的依赖项,而不是 PHP 的。通过运行如下命令来安装它引用的依赖:

    运行 Mix

    Mix 是 的顶层配置,因此运行 Mix 任务,只需要执行一条包含在 Laravel 默认的 package.json 文件中的脚本:

    1. // 运行 Mix 任务...
    2. npm run dev
    3. // 运行所有的 Mix 任务并最小化输出结果...
    4. npm run production

    监听资源变化

    npm run watch 命令能够在终端持续运行并且监听相关文件的变化。一旦它发现改变,Webpack 将自动重新编译资源:

    1. npm run watch

    你会发现在特定环境下,文件发生改变并不会促使 Webpack 更新。如果系统中出现这种情况,不妨考虑使用 watch-poll 命令:

    1. npm run watch-poll

    webpack.mix.js 文件所有资源编译的切入点。把它想像为 Webpack 的轻量级配置封装。Mix 任务可以与如何编译资源的配置一起被链式调用。

    less 方法可用于将 编译成 CSS。下面的语句将 app.less 文件编译为 public/css/app.css

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

    可以通过多次调用 less 方法完成多文件编译:

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

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

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

    如果需要覆盖 隐含的 Less 插件选项 ,可以传递一个对象作为 mix.less() 的第三个参数:

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

    Sass

    sass 方法能将 编译成 CSS。可以像下面这样使用这个方法:

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

    less 方法类似,可以将多个 Sass 文件编译为各自的 CSS 文件,并为结果 CSS 自定义输出目录:

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

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

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

    Stylus

    与 Less 和 Sass 相似, stylus 方法将 编译成 CSS:

    1. mix.stylus('resources/stylus/app.styl', 'public/css', {
    2. use: [
    3. require('rupture')()
    4. ]
    5. });

    是一个转换 CSS 的强力工具,它已经包含在 Laravel Mix 中。默认情况下,Mix 利用流行的 Autoprefixer 插件自动附加所有必要的 CSS3 第三方前缀。不过,你可以自由添加应用中所需的任何附加插件。首先通过 NPM 安装所需插件,然后在 webpack.mix.js 文件引用:

    1. mix.sass('resources/sass/app.scss', 'public/css')
    2. .options({
    3. postCss: [
    4. require('postcss-css-variables')()
    5. ]
    6. });

    原生 CSS

    如果想要将几个原生 CSS 样式表合并到单个文件中,可以使用 styles 方法。

    1. mix.styles([
    2. 'public/css/vendor/normalize.css',
    3. ], 'public/css/all.css');

    URL 处理

    因为是基于 Webpack 之上构建,了解几个 Webpack 概念就很重要了。对于 CSS 编译,Webpack 将重写和优化任何带有样式表的 url() 调用。虽然初听上去好像很奇怪,但这确实是个强大的功能。 想像一下我们想要编译包含图片相对 URL 的 Sass:

    1. .example {
    2. background: url('../images/example.png');
    3. }

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

    1. .example {
    2. background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
    3. }

    尽管此功能可能很有用,但是已有文件夹结构可能已经按你的预期做了配置。这种情况下,你可以禁用 url() 重写:

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

    webpack.mix.js 文件中加入这项配置,Mix 将不再匹配任何 url() 或者复制资源到 public 目录。换句话说,编译后的 CSS 看上去和你原来输入的内容一样:

    1. .example {
    2. background: url("../images/thing.png");

    虽然默认情况下源码映射被禁用,但是可以通过在 webpack.mix.js 文件中调用 mix.sourceMaps() 方法来激活。尽管会提高编译/执行的成本,却可以在在编译资源时为浏览器开发工具提供额外的调试信息。

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

    使用 JavaScript

    Mix 提供了几个有助于使用 JavaScript 文件的特性,比如编译 ECMAScript 2015、模块打包、最小化和合并原生 JavaScript 文件。更棒的是,所有这些都无需配置就可以很好地工作。

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

    只需这一行代码,就可以支持:

    • ES2015 语法
    • 模块
    • 编译 .vue 文件。
    • 为生产环境最小化代码。

    Vendor 提取

    将应用自身的 JavaScript 和第三方库绑定在一起有个潜在的缺点:会使长期缓存变得困难。例如,应用代码的单独更新将强制浏览器重新下载全部第三方库,即使第三方库没有发生变化。

    如果你打算频繁地更新应用中的 JavaScript,应该考虑将第三方库提取到它自己的文件中。这样一来,应用代码的改变将不影响 vendor.js 文件缓存。Mix 的 extract 方法为之提供了便利:

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

    extract 方法接受你想要提取到 vendor.js 的全部库或模块的数组作为参数。使用上面例子中的代码片段,Mix 将生成如下文件:

    • public/js/manifest.js: Webpack 运行时清单
    • public/js/vendor.js: 第三方库代码
    • public/js/app.js: 应用代码

    为避免 JavaScript 错误,应确保按适应顺序加载这些文件:

    1. <script src="/js/manifest.js"></script>
    2. <script src="/js/vendor.js"></script>
    3. <script src="/js/app.js"></script>

    React

    Mix 能自动安装 React 支持所需的 Babel 插件。要达成此目的,只需要用 mix.react() 替换 mix.js()

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

    与利用 mix.styles() 整合样式表类似,你也可以使用 scripts() 方法整合并最小化任意数量的 JavaScript 文件:

    1. mix.scripts([
    2. 'public/js/admin.js',
    3. 'public/js/dashboard.js'
    4. ], 'public/js/all.js');

    对于不需要使用 Webpack 编译 JavaScript 的遗留代码,这个选项尤其有用。

    自定义 Webpack 配置

    Lavarel Mix 在后台引用预先配置的 webpack.config.js 文件以加速启动和运行。有时,你可能需要手动编辑这个文件。你可能有一个特殊的加载器或插件需要引用,或者可能更愿意用 Stylus 代替 Sass。这种情况下,你有两个选择:

    合并自定义配置

    Mix 提供了 webpackConfig 方法来合并任意简短的 Webpack 配置以覆盖已有配置。这是个非常勾人的选择,因为它不要求你复制和维护你自己的 webpack.config.js 副本。 webpackConfig 方法接受一个对象作为作参数,它包含你想要应用的任何 ,

    1. mix.webpackConfig({
    2. resolve: {
    3. modules: [
    4. path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js')
    5. ]
    6. }
    7. });

    自定义配置文件

    如果你想完全自定义 Webpack 配置,将 node_modules/laravel-mix/setup/webpack.config.js 文件复制到项目的根目录。然后将 package.json 文件中所有的 —config 引用都指向新复制的配置文件。如果选择用这种方式自定义配置,Mix webpack.config.js 后续的任何更新,都必须手动合并到你的自定义配置文件中。

    复制文件 & 目录

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

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

    复制文件夹时, copy 方法将扁平化目录结构。想要保持目录的原始结构,需要使用 copyDirectory 方法:

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

    许多开发者在他们编译后的资源添加时间戳或唯一令牌作后缀,强制浏览器加载新的资源,以替换旧的代码副本。Mix 可以使用 version 方法替你处理它们。.

    version 方法自动在所有编译后的文件名后追加唯一的哈希值,从而实现更方便的缓存销毁:

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

    在生成版本化文件后,你不会知道确切的文件名。因此,你需要在 views 中使用 Laravel 的全局 mix 函数载入相应的哈希资源。 mix 函数自动判断哈希文件的当前文件名:

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

    通常在开发阶段不需要版本化文件,你可以仅在运行 npm run production 时执行版本化处理:

    1. mix.js('resources/js/app.js', 'public/js');
    2. if (mix.inProduction()) {
    3. mix.version();
    4. }

    Browsersync 重加载

    能够自动监测文件变化,并且无需手动刷新就将变化注入到浏览器。可以调用 mix.browserSync() 方法开启此项支持:

    1. mix.browserSync('my-domain.test');
    2. // 或...
    3. // https://browsersync.io/docs/options
    4. mix.browserSync({
    5. proxy: 'my-domain.test'
    6. });

    可以传递字符串(代理)或对象Y(BrowserSync 设置)给此方法。然后使用 npm run watch 命令启动 Webpack 的开发服务器。再编辑脚本或者 PHP 文件,就会看到浏览器立即刷新以响应你的修改。

    环境变量

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

    1. MIX_SENTRY_DSN_PUBLIC=http://example.com

    一旦此变量被定义在 .env 文件中,就可以借助 process.env 对象访问它。如果在运行 watch 任务时这个值发生改,就需要重启任务:

    1. process.env.MIX_SENTRY_DSN_PUBLIC

    如果可用,Mix 将自动为每次绑定显示操作系统通知。这将为你提供编译是否成功的实时反馈。不过,可能在某些情况下,你希望禁用通知。一个例子是在生产服务器上触发 Mix。通知可以借助 disableNotifications 方法来禁用。