简介 Laravel Mix 是一个由 Laracasts 所开发的拓展包,作者 Jeffrey Way 。其使用了常见的 CSS 和 JavaScript 预处理器,为定义 webpack 构建步骤提供了流畅的 API。 换句话说,Mix 使您可以轻松地编译和压缩应用程序中的 CSS 和 JavaScript 文件。通过链式调用这些简洁方法,可以流畅地定义资源管道。例如: ``` mix.js('resources/js/app.js', 'public/js') .postCss('resources/css/app.css', 'public/css'); ``` 如果您曾经对使用 Webpack 和资源编译感到困惑和不知所措,那么你一定会喜欢 Laravel Mix。但你不一定非要使用它来开发应用,你可以使用你喜欢的任何资源管道工具,甚至干脆不用。 技巧:如果您需要先开始使用 Laravel 和 Tailwind CSS 构建应用程序,请查看我们的 应用程序入门工具包。 安装 & 配置 安装 Node 在运行 Mix 之前,要先确保您的机器上已经安装了 Node.js 和 NPM: ``` node -v npm -v ``` 您可以从 Node 官网 使用图形化安装器轻松安装最新版本的 Node 和 NPM。或者,如果您使用的是 Laravel Sail 则可以通过 Sail 调用 Node 和 NPM: ``` ./sail node -v ./sail npm -v ``` 安装 Laravel Mix 剩下的事就是安装 Laravel Mix。在全新安装的 Laravel 中,您会在应用目录结构的根目录中找到 package.json 文件。 默认的 package.json 包含了使用 Laravel Mix 所需要的所有东西。 您可以把它想象成为 composer.json 文件,只是它定义的是 Node 依赖而不是 PHP 依赖。您可以像这样来安装依赖: ``` npm install ``` 运行 Mix Mix 是 webpack 的顶层配置,因此如果您要执行 Mix 任务,您只需要执行一条被包含于 Laravel 默认的 package.json 文件中的 NPM 脚本。当您运行 dev 或 production 脚本时, 应用程序的所有 CSS 和 JavaScript 资源文件都将被编译并放置在应用程序的 public 目录中: ``` // 运行所有的 Mix 任务… npm run dev // 运行所有的 Mix 任务并最小化输出… npm run prod ``` 监听静态资源的变化 npm run watch 命令将会在您的终端中持续运行,并监听所有相关的 CSS 和 JavaScript 文件的修改。当发现文件有任何改动时, Webpack 将会自动重新编译它们: ``` npm run watch ``` 您会发现在特定的环境下, 文件的修改并不会触发 Webpack 的更新。如果在您的系统中发生了这样的事,您可以考虑使用 watch-poll 命令: ``` npm run watch-poll ``` 使用样式表 webpack.mix.js 是所有静态资源编译的入口。 您可以将其看成是 webpack 的轻量配置封装。Mix 任务能够与定义了静态资源的编译方式的配置一起被链式调用。 Tailwind CSS Tailwind CSS 是一种实用程序优先的现代框架,可在不离开 HTML 的情况下构建出色的网站。让我们研究一下如何在 Laravel Mix 的 Laravel 项目中开始使用它。首先,我们应该使用 NPM 安装 Tailwind 并生成我们的 Tailwind 配置文件: ``` npm install npm install -D tailwindcss npx tailwindcss init ``` init 命令将生成一个 tailwind.config.js 文件。该文件的 content 部分允许您配置所有 HTML 模板、JavaScript 组件和任何其他包含 Tailwind 类名称的源文件的路径,以便 Tailwind 在优化生产环境中的 CSS 时,可以削减未使用的样式: ``` content: [ './storage/framework/views/*.php', './resources/**/*.blade.php', './resources/**/*.js', './resources/**/*.vue', ], ``` 接下来,您应该将 Tailwind 的每个「层」添加到应用中的 resources/css/app.css 文件: ``` @tailwind base; @tailwind components; @tailwind utilities; ``` 配置 Tailwind 的层后,请更新应用中的 webpack.mix.js 文件,如此便可编译 Tailwind 支持的 CSS: ``` mix.js('resources/js/app.js', 'public/js') .postCss('resources/css/app.css', 'public/css', [ require('tailwindcss'), ]); ``` 最后,您应当在应用的主布局模板中引用您的样式表。很多应用都将该模板存储于 resources/views/layouts/app.blade.php 中。此外,如果它还未正常显示,请确保您已经添加了 meta 标签: ``` <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 文件的路径,第二个参数为编译后的文件的位置路径: ``` mix.postCss('resources/css/app.css', 'public/css', [ require('postcss-custom-properties') ]); ``` 或者,为了实现简单的 CSS 的编译和压缩,您可以在不使用其他插件的情况下执行 postCss : ``` mix.postCss('resources/css/app.css', 'public/css'); ``` Sass sass 方法允许您将 Sass 编译成 Web 浏览器可以理解的 CSS 文件。sass 方法的第一个参数是您的 Sass 文件的路径,第二个参数是编译后的文件的存储路径: ``` mix.sass('resources/sass/app.scss', 'public/css'); ``` 您可以将多个 Sass 文件编译成各自的 CSS 文件,甚至可以通过多次调用 sass 方法来自定义生成的 CSS 的输出目录: ``` 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: ``` .example { background: url('../images/example.png'); } ``` 注意:任何给定 url() 的绝对路径将被排除在 URL 重写之外。例如, url('/images/thing.png') 或 url('http://example.com/images/thing.png') 将不会作任何修改。 默认情况下,Laravel Mix 和 Webpack 将会寻找到 example.png,并将其复制到您的 public/images 文件夹中,然后重写生成的样式表中的 url() 。如此一来,编译后的 CSS 将变为: ``` .example { background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e); } ``` 源码映射 Source map 默认是关闭的,你可以在 webpack.mix.js 文件中调用 mix.sourceMaps() 方法来打开 Source map 功能。尽管这会给前端编译带来一些性能负担,但是在使用浏览器调试时就会很方便找到对应的代码: ``` mix.js('resources/js/app.js', 'public/js') .sourceMaps(); ``` 源码映射样式 Webpack 提供了多种 源码映射样式。在默认情况下 Mix 的源码映射使用 eval-source-map 模式,它快速构建非常快。 如果你想更改映射样式可以使用 sourceMaps 方法: ``` let productionSourceMaps = false; mix.js('resources/js/app.js', 'public/js') .sourceMaps(productionSourceMaps, 'source-map'); ``` 使用 JavaScript Mix 提供了多种功能来帮助您处理 JavaScript 文件,例如编译最新的 ECMAScript 语法,模块化,代码压缩和合并 JavaScript 文件。更棒的是,所有这些都可以无缝运行,而无需大量的自定义配置: ``` mix.js('resources/js/app.js', 'public/js'); ``` 通过这一行代码,你现在就可以实现: 支持最新的 EcmaScript 语法 支持模块化开发 在生产环境的代码压缩最小化 Vue 当使用 vue 方法时,Mix 会自动安装编译 Vue 组件所需要的 Babel 插件。 不需要其他任何配置。 ``` mix.js('resources/js/app.js', 'public/js') .vue(); ``` 编译 JavaScript 后,您可以在应用程序中引用它: ``` <head> <!-- ... --> <script src="/js/app.js"></script> </head> ``` React Mix 可以自动安装 React 支持所需的 Babel 插件。 首先,请添加一个对 react 方法的调用: ``` mix.js('resources/js/app.jsx', 'public/js') .react(); ``` Mix 将在后台下载并包含相应的 babel-preset-react Babel 插件。编译 JavaScript 后,您可以在应用程序中引用它: ``` <head> <!-- ... --> <script src="/js/app.js"></script> </head> ``` 提取 Vendor 将应用程序本身所有的 JavaScript 与 vendor 库(例如 React 和 Vue )捆绑在一起的潜在缺点是:这会使长期缓存变得更加困难。 例如,对应用程序代码进行一次更新将迫使浏览器重新下载所有 vendor 库,即使它们没有更改。 如果打算频繁更新应用程序的 JavaScript,则应考虑将所有 vender 库提取到它们自己的文件中。 这样,对应用程序代码的更改将不会影响大型 vendor.js 文件的缓存。 Mix 的 extract 方法使这变得轻而易举: ``` mix.js('resources/js/app.js', 'public/js') .extract(['vue']) ``` extract 方法接受你希望提取到 vendor.js 文件中的所有库或模块的数组。 以上面的代码段为例,Mix 将生成以下文件: public/js/manifest.js: Webpack 运行时清单 public/js/vendor.js: vendor 库 public/js/app.js: 你的应用程序代码 为避免 JavaScript 错误,请确保以正确的顺序加载这些文件: ``` <script src="/js/manifest.js"></script> <script src="/js/vendor.js"></script> <script src="/js/app.js"></script> ``` 自定义 Webpack 配置 有时候你可能需要手动修改 Webpack 配置,例如,你可能需要引入特殊的 loader 或者插件。 Mix 提供非常有用的 webpackConfig 方法可以让你覆盖 Webpack 的配置。这非常吸引人,因为它不需要你复制和维护自己的 webpack.config.js 文件。 webpackConfig 方法接收一个对象你可以传入你希望的 Webpack 特定配置 。 ``` mix.webpackConfig({ resolve: { modules: [ path.resolve(__dirname, 'vendor/laravel/spark/resources/assets/js') ] } }); ``` 版本管理 / 缓存销毁 许多开发者在他们编译后的资源添加时间戳或唯一令牌作后缀,强制浏览器加载新的资源,以替换旧的代码副本。Mix 可以使用 version 方法替你处理它们。 version 方法自动在所有编译后的文件名后追加唯一的哈希值,从而实现更方便的缓存销毁: ``` mix.js('resources/js/app.js', 'public/js') .version(); ``` 在生成版本化文件后,你不会知道确切的文件名。因此,你需要在 视图 中使用 Laravel 的全局 mix 函数载入相应的哈希资源。 mix 函数自动判断哈希文件的当前文件名: ``` <script src="{{ mix('/js/app.js') }}"></script> ``` 通常在开发阶段不需要版本化文件,你可以仅在运行 npm run prod 时执行版本化处理: ``` mix.js('resources/js/app.js', 'public/js'); if (mix.inProduction()) { mix.version(); } ``` 自定义 Mix Base URLs 如果你的 Mix 编译资产被部署到独立于应用程序的 CDN 上,则需要更改 mix 函数生成的基本 URL 。 你可以通过在 config/app.php 中添加一个 mix_url 配置选项来做到这一点。php 的配置文件: ``` 'mix_url' => env('MIX_ASSET_URL', null) ``` 在配置了 Mix URL 之后,mix 函数将在生成资产 URL 时为所配置的 URL 添加前缀: ``` https://cdn.example.com/js/app.js?id=1964becbdd96414518cd ``` Browsersync 重加载 BrowserSync 能够自动监测文件变化,并且无需手动刷新就将变化注入到浏览器。可以调用 mix.browserSync() 方法开启此项支持: ``` mix.browserSync('laravel.test'); ``` 可以将 BrowserSync 选项 通过 Javascript 对象传递给 browserSync 方法来指定: ``` mix.browserSync({ proxy: 'laravel.test' }); ``` 然后使用 npm run watch 命令启动 Webpack 的开发服务器。再编辑脚本或者 PHP 文件,就会看到浏览器立即刷新以响应你的修改。 环境变量 你可以通过在 .env 文件中添加 MIX_ 前缀,将环境变量注入到 Mix: ``` MIX_SENTRY_DSN_PUBLIC=http://example.com ``` 如果你在 .env 文件中定义了变量的话,你可以通过 process.env 对象来访问它。 但如果你在任务运行的时候修改了变量的值,你就需要重新启动任务了: ``` process.env.MIX_SENTRY_DSN_PUBLIC ``` 通知 如果系统支持 Mix , 将在编译时自动显示操作系统通知,为您提供有关编译是否成功的及时反馈。但是在某些情况下,您可能希望禁用这些通知。 比如在生产服务器上。禁用通知可以使用 disableNotifications 方法: ``` mix.disableNotifications(); ```