编辑资源 Mix
编辑资源 (Mix)
简介
Laravel Mix 使用了常见的 CSS 和 JavaScript 预处理器,为定义 Webpack 构建步骤提供了流畅的 API。通过链式调用这些简洁方法,可以流畅地定义资源管道。例如:
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
如果对如何开始使用 Webpack 和资源编译感到困惑和不知所措,那么你一定会喜欢 Laravel Mix。但是,你不一定非要使用它来开发应用;可以使用你喜欢的任何资源管道工具,甚至干脆不用。
安装 & 配置
安装 Node
在触发 Mix 之前,要先确保机器上已经安装了 Node.js 和 NPM。
node -v
npm -v
默认情况下, Laravel Homestead 包含了你需要的所有东西;不过如果你不使用 Vagrant,你也能使用从 它们的下载页面 获取到更易用的图形化安装器来安装最新版本的 Node 和 NPM。
Laravel Mix
剩下的事就是安装 Laravel Mix。在 Laravel 的纯净安装副本中,您可以在应用目录结构的根目录中找到 package.json
文件。默认的 package.json
包含了起步所需要的所有东西。您可以把它想象成为 composer.json
文件,只是它定义的是 Node 依赖而不是 PHP 依赖。您可以像这样来安装依赖:
npm install
运行 Mix
Mix 是 Webpack 的顶层配置,因此如果您要执行 Mix 任务,您只需要执行一条被包含于 Laravel 默认的 package.json
文件中的 NPM 脚本:
// 运行所有的 Mix 任务……
npm run dev
// 运行所有的 Mix 任务并最小化输出……
npm run production
监听静态资源的变化
npm run watch
命令将会在您的终端中持续运行并监听所有相关文件的修改。当发现有改动时, Webpack 将会自动重新编译它们:
npm run watch
您会发现在特定的环境下, 文件的修改并不会触发 Webpack 的更新。如果在您的系统中发生了这样的事,您可以考虑使用 watch-poll
命令:
npm run watch-poll
使用样式表
webpack.mix.js
是所有静态资源编译的入口。您可以将其看成是 Webpack 的轻量配置封装。Mix 任务能够与定义了静态资源的编译方式的配置一起被链式调用。
Less
less
方法可用于将 Less 编译为 CSS 。让我们将 app.less
文件编译为 public/css/app.css
。
mix.less('resources/less/app.less', 'public/css');
可以通过多次调用 less
方法完成多文件编译:
mix.less('resources/less/app.less', 'public/css')
.less('resources/less/admin.less', 'public/css');
如果希望自定义编译后的 CSS 文件名,可以把完整的文件路径作为传递给 less
方法的第二个参数:
mix.less('resources/less/app.less', 'public/stylesheets/styles.css');
如果需要覆盖 隐含的 Less 插件选项 ,可以传递一个对象作为 mix.less()
的第三个参数:
mix.less('resources/less/app.less', 'public/css', {
strictMath: true
});
Sass
sass
方法能将 Sass 编译成 CSS。可以像下面这样使用这个方法:
mix.sass('resources/sass/app.scss', 'public/css');
和 less
方法类似,可以将多个 Sass 文件编译为各自的 CSS 文件,并为结果 CSS 自定义输出目录:
mix.sass('resources/sass/app.sass', 'public/css')
.sass('resources/sass/admin.sass', 'public/css/admin');
额外的 Node-Sass 插件选项 可以作为第三个参数:
mix.sass('resources/sass/app.sass', 'public/css', {
precision: 5
});
Stylus
与 Less 和 Sass 相似, stylus
方法将 Stylus 编译成 CSS:
mix.stylus('resources/stylus/app.styl', 'public/css');
还可以安装额外的 Stylus 插件,比如 Rupture 。先通过 NPM (npm install rupture
)安装有插件,然后在调用 mix.stylus()
时包含它:
mix.stylus('resources/stylus/app.styl', 'public/css', {
use: [
require('rupture')()
]
});
PostCSS
PostCSS 是一个转换 CSS 的强力工具,它已经包含在 Laravel Mix 中。默认情况下,Mix 利用流行的 Autoprefixer 插件自动附加所有必要的 CSS3 第三方前缀。不过,你可以自由添加应用中所需的任何附加插件。首先通过 NPM 安装所需插件,然后在 webpack.mix.js
文件引用:
mix.sass('resources/sass/app.scss', 'public/css')
.options({
postCss: [
require('postcss-css-variables')()
]
});
原生 CSS
如果想要将几个原生 CSS 样式表合并到单个文件中,可以使用 styles
方法。
mix.styles([
'public/css/vendor/normalize.css',
'public/css/vendor/videojs.css'
], 'public/css/all.css');
URL 处理
因为是基于 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);
}
尽管此功能可能很有用,但是已有文件夹结构可能已经按你的预期做了配置。这种情况下,你可以禁用 url()
重写:
mix.sass('resources/sass/app.scss', 'public/css')
.options({
processCssUrls: false
});
在 webpack.mix.js
文件中加入这项配置,Mix 将不再匹配任何 url()
或者复制资源到 public 目录。换句话说,编译后的 CSS 看上去和你原来输入的内容一样:
.example {
background: url("../images/thing.png");
}
源码映射
虽然默认情况下源码映射被禁用,但是可以通过在 webpack.mix.js
文件中调用 mix.sourceMaps()
方法来激活。尽管会提高编译 / 执行的成本,却可以在在编译资源时为浏览器开发工具提供额外的调试信息。
mix.js('resources/js/app.js', 'public/js')
.sourceMaps();
源码映射样式
Webpack 提供了多种 source mapping styles 。默认情况下,Mix 的源码映射样式设置为 eval-source-map
,这提供了快速的重建时间。如果你想改变映射风格,你可以使用 sourceMaps
方法:
let productionSourceMaps = false;
mix.js('resources/js/app.js', 'public/js')
.sourceMaps(productionSourceMaps, 'source-map');
使用 JavaScript
Mix 提供了几个有助于使用 JavaScript 文件的特性,比如编译 ECMAScript 2015、模块打包、最小化和合并原生 JavaScript 文件。更棒的是,所有这些都无需配置就可以很好地工作。
mix.js('resources/js/app.js', 'public/js');
只需这一行代码,就可以支持:
- ES2015 语法。
- 模块。
- 编译
.vue
文件。 - 为生产环境最小化代码。
Vendor 提取
将应用自身的 JavaScript 和第三方库绑定在一起有个潜在的缺点:会使长期缓存变得困难。例如,应用代码的单独更新将强制浏览器重新下载全部第三方库,即使第三方库没有发生变化。
如果你打算频繁地更新应用中的 JavaScript,应该考虑将第三方库提取到它自己的文件中。这样一来,应用代码的改变将不影响 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
: 第三方库代码public/js/app.js
: 应用代码
为避免 JavaScript 错误,应确保按适应顺序加载这些文件:
<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>
React
Mix 能自动安装 React 支持所需的 Babel 插件。要达成此目的,只需要用 mix.react()
替换 mix.js()
:
mix.react('resources/js/app.jsx', 'public/js');
Mix 将在后台下载并包含合适的 babel-preset-react
Babel 插件。
Vanilla JS
与使用 mix.styles()
合并样式表一样,您可以使用 scripts()
方法合并并最小化输出任意数量的 JavaScript 文件:
mix.scripts([
'public/js/admin.js',
'public/js/dashboard.js'
], 'public/js/all.js');
对于那些您无需使用 Webpack 来编译 JavaScript 的遗留代码而言,这个选项显得格外有用。
技巧:
mix.babel()
是mix.scripts()
的一个小变种。其方法签名与scripts
完全一致;但整合的文件将会由 Babel 进行编译,它会将 ES2015 代码转换成浏览器能够理解的代码。
自定义 Webpack 配置
Laravel Mix 在后台引用预配置的 webpack.config.js
文件以加速启动和运行。有些时候,您需要手动修改这个文件。您可能有一个特殊的加载器(loader)或插件需要被引用,亦或是您想要使用 Stylus 来代替 Sass。在这种情况下,您有两种选择:
合并自定义配置
Mix 提供了一个非常有用的 webpackConfig
方法,它允许您合并任意简短的 Webpack 配置以重写现有配置。这可能是一个非常吸引人的选择,因为它不需要您复制和维护您自己的 webpack.config.js
文件的副本。webpackConfig
方法接收一个对象,它应该包含任何您想要应用的 Webpack 特定配置 。
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
文件夹时,这个方法很有用。
mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');
复制文件夹时, copy
方法将扁平化目录结构。想要保持目录的原始结构,需要使用 copyDirectory
方法:
mix.copyDirectory('resources/img', 'public/img');
版本管理 / 缓存销毁
许多开发者在他们编译后的资源添加时间戳或唯一令牌作后缀,强制浏览器加载新的资源,以替换旧的代码副本。Mix 可以使用 version
方法替你处理它们。
version
方法自动在所有编译后的文件名后追加唯一的哈希值,从而实现更方便的缓存销毁:
mix.js('resources/js/app.js', 'public/js')
.version();
在生成版本化文件后,你不会知道确切的文件名。因此,你需要在 views 中使用 Laravel 的全局 mix
函数载入相应的哈希资源。 mix
函数自动判断哈希文件的当前文件名:
<script src="{{ mix('/js/app.js') }}"></script>
通常在开发阶段不需要版本化文件,你可以仅在运行 npm run production
时执行版本化处理:
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('my-domain.test');
// 或...
// https://browsersync.io/docs/options
mix.browserSync({
proxy: 'my-domain.test'
});
可以传递字符串(代理)或对象 Y(BrowserSync 设置)给此方法。然后使用 npm run watch
命令启动 Webpack 的开发服务器。再编辑脚本或者 PHP 文件,就会看到浏览器立即刷新以响应你的修改。
环境变量
可以通过在 .env
文件中添加 MIX_
前缀,将环境变量注入到 Mix:
MIX_SENTRY_DSN_PUBLIC=http://example.com
一旦此变量被定义在 .env
文件中,就可以借助 process.env
对象访问它。如果在运行 watch
任务时这个值发生改变,就需要重启任务:
process.env.MIX_SENTRY_DSN_PUBLIC
通知
如果可用,Mix 将自动为每次绑定显示操作系统通知。这将为你提供编译是否成功的实时反馈。不过,可能在某些情况下,你希望禁用通知。一个例子是在生产服务器上触发 Mix。通知可以借助 disableNotifications
方法来禁用。
mix.disableNotifications();
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: