企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] # 编译资源 Mix ## 使用样式表 `webpack.mix.js` 文件所有资源编译的切入点。把它想像为 Webpack 的轻量级配置封装。Mix 任务可以与如何编译资源的配置一起被链式调用。 ### Less `less` 方法可用于将 [Less](http://lesscss.org/) 编译成 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 插件选项](https://github.com/webpack-contrib/less-loader#options) ,可以传递一个对象作为 `mix.less()` 的第三个参数: ``` mix.less('resources/less/app.less', 'public/css', { strictMath: true }); ``` ### Sass `sass` 方法能将 [Sass](https://sass-lang.com/) 编译成 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 插件选项](https://github.com/sass/node-sass#options) 可以作为第三个参数: ``` mix.sass('resources/sass/app.sass', 'public/css', { precision: 5 }); ``` ### Stylus 与 Less 和 Sass 相似, `stylus` 方法将 [Stylus](http://stylus-lang.com/) 编译成 CSS: ``` mix.stylus('resources/stylus/app.styl', 'public/css'); ``` 还可以安装额外的 Stylus 插件,比如 [Rupture](https://github.com/jescalan/rupture) 。先通过 NPM (`npm install rupture`)安装有插件,然后在调用 `mix.stylus()` 时包含它: ``` mix.stylus('resources/stylus/app.styl', 'public/css', { use: [ require('rupture')() ] }); ``` ### PostCSS [PostCSS](https://postcss.org/) 是一个转换 CSS 的强力工具,它已经包含在 Laravel Mix 中。默认情况下,Mix 利用流行的 [Autoprefixer](https://github.com/postcss/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/app/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(); ``` ## 使用 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 将生成如下文件: ``` <div class="content-list" markdown="1"> - `public/js/manifest.js`: *Webpack 运行时清单* - `public/js/vendor.js`: *第三方库代码* - `public/js/app.js`: *应用代码* </div> ``` 为避免 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 代码转换为浏览器能够理解的 vanilla JavaScript。 ### 自定义 Webpack 配置 Lavarel Mix 在后台引用预先配置的 `webpack.config.js` 文件以加速启动和运行。有时,你可能需要手动编辑这个文件。你可能有一个特殊的加载器或插件需要引用,或者可能更愿意用 Stylus 代替 Sass。这种情况下,你有两个选择: #### 合并自定义配置 Mix 提供了 `webpackConfig` 方法来合并任意简短的 Webpack 配置以覆盖已有配置。这是个非常勾人的选择,因为它不要求你复制和维护你自己的 `webpack.config.js` 副本。 `webpackConfig` 方法接受一个对象作为作参数,它包含你想要应用的任何 [Webpack 特定配置](https://webpack.js.org/configuration/) , ``` 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](/docs/{{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(); } ``` ## Browsersync 重加载 [BrowserSync](https://browsersync.io/) 能够自动监测文件变化,并且无需手动刷新就将变化注入到浏览器。可以调用 `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(); ```