`webpack.mix.js` 文件位于項目根目錄下,是所有資源編譯的入口,可以將其看作 Webpack 的輕量級**配置封裝層**。Mix 任務以方法鏈的方式,被鏈在一起來定義前端資源如何被編譯。
默認版如下:
~~~javascript
let mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
~~~
[TOC]
## API 概覽
~~~javascript
mix.js(src, output);
mix.react(src, output); // Identical to mix.js(), but registers React Babel compilation.
mix.ts(src, output); // Requires tsconfig.json to exist in the same folder as webpack.mix.js
mix.extract(vendorLibs);
mix.sass(src, output);
mix.standaloneSass('src', output); // Faster, but isolated from Webpack.
mix.fastSass('src', output); // Alias for mix.standaloneSass().
mix.less(src, output);
mix.stylus(src, output);
mix.postCss(src, output, [require('postcss-some-plugin')()]);
mix.browserSync('my-site.dev');
mix.combine(files, destination);
mix.babel(files, destination); // Identical to mix.combine(), but also includes Babel compilation.
mix.copy(from, to);
mix.copyDirectory(fromDir, toDir);
mix.minify(file);
mix.sourceMaps(); // Enable sourcemaps
mix.version(); // Enable versioning.
mix.disableNotifications();
mix.setPublicPath('path/to/public');
mix.setResourceRoot('prefix/for/resource/locators');
mix.autoload({}); // Will be passed to Webpack's ProvidePlugin.
mix.webpackConfig({}); // Override webpack.config.js, without editing the file directly.
mix.then(function () {}); // Will be triggered each time Webpack finishes building.
mix.options({
extractVueStyles: false, // Extract .vue component styling to file, rather than inline.
globalVueStyles: file, // Variables file to be imported in every component.
processCssUrls: true, // Process/optimize relative stylesheet url()'s. Set to false, if you don't want them touched.
purifyCss: false, // Remove unused CSS selectors.
uglify: {}, // Uglify-specific options. https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
postCss: [] // Post-CSS options: https://github.com/postcss/postcss/blob/master/docs/plugins.md
});
~~~
## 處理樣式表
### 處理 Sass
`sass` 方法將 Sass 編譯成 CSS。
1. 編譯 `app.scss` 文件到 `public/css/app.css`:
~~~javascript
mix.sass('resources/assets/sass/app.scss', 'public/css');
~~~
2. 多次調用 `sass` 方法可用于編譯多個文件:
~~~javascript
mix.sass('resources/assets/sass/app.sass', 'public/css')
.sass('resources/assets/sass/admin.sass', 'public/css');
~~~
3. 如果要自定義編譯后文件的輸出位置,可以將完整的路徑信息作為第二個參數傳遞到 `sass` 方法:
~~~javascript
mix.sass('resources/assets/sass/app.sass', 'public/stylesheets/styles.css');
~~~
* [Node-Sass 插件選項 ](https://github.com/sass/node-sass#options) 可以作為第三個參數:
~~~javascript
mix.sass('resources/assets/sass/app.sass', 'public/css', {
precision: 5
});
~~~
### 處理 Less
`less` 方法將 Less 編譯成 CSS。
1. 編譯 `app.less` 文件到 `public/css/app.css`:
~~~javascript
mix.less('resources/assets/less/app.less', 'public/css');
~~~
2. 和 `sass` 方法一樣,也可以多次調用 `less` 方法以編譯多個文件,甚至自定義結果 CSS 的輸出路徑:
~~~javascript
mix.less('resources/assets/less/app.less', 'public/css')
.less('resources/assets/less/admin.less', 'public/css/admin');
~~~
* [Less 插件選項](https://github.com/webpack-contrib/less-loader#options) 可以作為第三個參數:
~~~javascript
mix.less('resources/assets/less/app.less', 'public/css', {
strictMath: true
});
~~~
### 處理原生 CSS
`styles` 方法,將多個原生 CSS 樣式文件合并到一個文件:
~~~javascript
mix.styles([
'public/css/vendor/normalize.css',
'public/css/vendor/videojs.css'
], 'public/css/all.css');
~~~
### 資源映射 Source Map
Source Map 默認被禁用,但可以通過調用 `sourceMaps` 方法來激活。
盡管這會帶來編譯/性能開銷,不過在編譯資源的時候,可以提供額外的調試信息給瀏覽器的開發者工具。
~~~javascript
mix.js('resources/assets/js/app.js', 'public/js')
.sourceMaps();
~~~
## 處理腳本
Mix 還提供了多個特性來處理 JavaScript 文件,例如編譯 ECMAScript 2015,模塊捆綁,最小化以及合并原生 JavaScript 文件。
這些都是無縫集成的,不需要額外的自定義配置:
~~~javascript
mix.js('resources/assets/js/app.js', 'public/js');
~~~
通過這一行代碼,你可以實現如下功能:
> 1. ES2015 語法
> 2. 模塊
> 3. 編譯 `.vue` 文件
> 4. 生產環境壓縮代碼
### 提取依賴庫
捆綁所有應用特定 JavaScript 和 vendor 庫的一個潛在缺點是進行長期緩存將變得更加困難,例如,單個更新應用代碼將會強制瀏覽器下載所有 vendor 庫,即使它們并沒有更新。
如果你想要頻繁更新應用的 JavaScript,需要考慮對 vendor 庫進行提取和拆分,這樣的話,一次修改應用代碼不會影響 `vendor.js` 文件的緩存。
`extract` 方法可以接收包含所有庫的數組,或你想要提取到 vendor.js 文件的模塊:
~~~javascript
mix.js('resources/assets/js/app.js', 'public/js')
.extract(['vue', 'jquery']);
~~~
使用上述代碼作為示例,Mix將會生成如下文件:
* `public/js/manifest.js`:Webpack manifest runtime
* `public/js/vendor.js`:vendor 庫
* `public/js/app.js`:應用代碼
為避免 JavaScript 錯誤,需要頁面確保以正確的順序加載這些文件:
~~~html
<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>
~~~
### 處理原生 JS
`scripts` 方法,可以合并&壓縮多個 JavaScript 文件:
~~~javascript
mix.scripts([
'public/js/admin.js',
'public/js/dashboard.js'
], 'public/js/all.js');
~~~
這個選項對于不需要為 JavaScript 編寫 Webpack 的舊項目非常有用。
>[info] `mix.scripts()` 的一個微小變化是 `mix.babel()`。其方法簽名與 `scripts` 一樣。不過,連接的文件會經過 Babel 編譯,將所有 ES2015 的代碼轉換為所有瀏覽器都能識別的原生 JavaScript。
## 自定義 Webpack 配置
在場景背后,Laravel Mix 引用了預配置的 `webpack.config.js` 文件來盡可能快的啟動和運行。
默認應用的配置文件為 `node_modules/laravel-mix/setup/webpack.config.js`。
使用 `webpackConfig` 方法可以覆蓋默認的 Webpack 配置。方法接收一個對象,該對象包含了任意你想要應用的 [Webpack 指定配置](https://webpack.js.org/configuration/)。
## 代碼壓縮
### CSS 代碼壓縮
使用 [`optimize-css-assets-webpack-plugin`](http://npm.taobao.org/package/optimize-css-assets-webpack-plugin) 來壓縮 CSS:
~~~javascript
mix.webpackConfig({
plugins: [
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true,
discardComments: {
removeAll: true
}
}
})
]
});
~~~
### JS 代碼壓縮
`options` 方法,傳入任何需要的 [UglifyJsPlugin](https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin) 配置選項,JS 代碼將在生產模式下自動被壓縮。
默認配置如下:
~~~javascript
mix.options({
uglify: {
uglifyOptions: {
sourceMap: false, // 關閉資源映射
compress: {
warnings: false,
drop_console: true // 去除控制臺輸出代碼
},
output: {
comments: false // 去除所有注釋
}
}
}
});
~~~
選項解析:
屬性 | 類型 | 默認值 | 描述
| --- | --- | --- | --- |
compress | boolean, object | true | [見 UglifyJS 文檔](https://github.com/mishoo/UglifyJS2#compress-options)。
mangle | boolean, object | true | [見 UglifyJS 文檔](https://github.com/mishoo/UglifyJS2#compress-options)。
beautify | boolean | false | 美化輸出。
output | 一個提供 UglifyJS OutputStream 選項的對象 | | 更底層地訪問 UglifyJS 輸出。
comments | boolean, RegExp, function(astNode, comment) -> boolean | 默認保存包含 `/*!`, `/**!`, `@preserve` or `@license` 的注釋 | 注釋相關的配置。
sourceMap | boolean | false | 使用 SourceMaps 將錯誤信息的位置映射到模塊。這會減慢編譯的速度。
test | RegExp, Array | `/.js($|\?)/i` | 測試匹配的文件。
include | RegExp, Array | | 只測試包含的文件。
exclude | RegExp, Array | | 要從測試中排除的文件。
## 拷貝文件和目錄
`copy` 方法拷貝文件和目錄到新路徑,這在將 `node_modules` 目錄下的特定資源文件重新放置到 `public` 目錄下時很有用:
~~~javascript
mix.copy('node_modules/foo/bar.css', 'public/css/bar.css');
~~~
復制目錄時,`copy` 方法會平面化目錄的結構。要維護目錄的原始結構,應該使用 `copyDirectory` 方法:
~~~javascript
mix.copyDirectory('assets/img', 'public/img');
~~~
## 版本號和緩存刷新
`version` 方法為編譯的前端資源添加時間戳或唯一令牌后綴,可以強制瀏覽器加載最新版本而不是代碼的緩存副本。
該方法會自動附加唯一 hash 值到已編譯文件名,從而方便實現緩存刷新:
~~~javascript
mix.js('resources/assets/js/app.js', 'public/js')
.version();
~~~
生成版本文件后,還不知提取的文件名,所以需要在 視圖 中使用 Laravel 全局的 `mix` 函數來加載相應的帶 hash 值的前端資源。`mix` 函數會自動判當前的 hash 文件名:
~~~html
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
~~~
由于版本文件在本地開發中沒有什么用,可以使用 `inProduction` 方法,只在生產模式下進行版本處理操作:
~~~javascript
mix.js('resources/assets/js/app.js', 'public/js');
if (mix.inProduction()) {
mix.version();
}
~~~
## 修改后 `webpack.mix.js` 文件示例
~~~javascript
let mix = require('laravel-mix');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
if (mix.inProduction()) {
// 生產模式下的特殊配置
mix.webpackConfig({
plugins: [
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true,
discardComments: {
removeAll: true
}
}
})
]
}).version();
}
~~~
- 日常命令
- 第一章 開發環境部署
- 第一節 安裝 VirtualBox
- 第二節 安裝 Vagrant
- 第三節 安裝 Git for Windows
- 命令行提示符的寫作約定
- Git Bash 使用技巧
- 第四節 安裝和配置 Homestead
- 第五節 啟動 Homestead 虛擬機
- 第六節 創建 Laravel 應用
- 第七節 使用 Git 進行版本控制
- 總結 本章命令概覽
- 第二章 前端工作流
- 第一節 Yarn 安裝前端擴展包
- 第二節 Laravel Mix 前端資源編譯
- (1)配置 webpack.mix.js 指定 Mix 任務
- (2)修改 resources/assets 前端資源文件
- (3)運行 Mix 任務編譯和監控代碼
- 總結 本章命令概覽
- 第三章 數據庫
- 第一節 Config 數據庫配置信息
- 第二節 Migrations 數據庫遷移文件
- 第三節 Schema 數據庫結構生成器
- (1) 數據表操作
- (2) 字段操作
- (3) 索引操作
- 第四節 Seeding 數據填充
- 第五節 DB 數據庫查詢構建器
- (1)獲取結果集