* * * * *
[TOC]
## 簡介
[Laravel Mix](https://github.com/JeffreyWay/laravel-mix)?提供了簡潔且可讀性高的 API,用于使用幾個常見的 CSS 和 JavaScript 預處理器為應用定義 Webpack 構建步驟。可以通過簡單鏈式調用來定義資源的編譯。例如:
~~~
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
~~~
如果你曾經對于使用 Webpack 及編譯資源感到困惑和不知所措,那么你會愛上 Laravel Mix。當然,Laravel 也并沒有強迫你一定要使用 Mix,你可以自由使用任何你喜歡的資源編譯工具,或者不用也行。
## 安裝 & 配置
#### 安裝 Node
在開始使用 Mix 之前,必須先確保你的機器上安裝了 Node.js 和 NPM。
~~~
node -v
npm -v
~~~
默認情況下,Laravel Homestead 會包含你所需的一切。當然,如果你沒有使用 Vagrant,就使用簡單的圖形安裝程序從?[其下載頁面](https://nodejs.org/en/download/)?安裝最新版的 Node 和 NPM。
#### Laravel Mix
然后就只需要安裝 Laravel Mix。在新的 Laravel 項目中,你可以在目錄結構的根目錄中找到一個?`package.json`?文件,它包括了運行基本的 Mix 所需的內容。就如同?`composer.json`?文件,只不過它定義的是 Node 的依賴而不是 PHP。你可以使用以下的命令安裝它引用的依賴項:
~~~
npm install
~~~
## 運行 Mix
Mix 是位于?[Webpack](https://webpack.js.org/)?頂部的配置層,所以要運行 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](http://lesscss.org/)?編譯為 CSS。在?`webpack.mix.js`?中這樣寫,可以將?`app.less`?編譯到?`public/css/app.css`?中。
~~~
mix.less('resources/assets/less/app.less', 'public/css');
~~~
可以多次調用?`less`?方法來編譯多個文件:
~~~
mix.less('resources/assets/less/app.less', 'public/css')
.less('resources/assets/less/admin.less', 'public/css');
~~~
如果要自定義編譯的 CSS 的文件名,可以將一個完整的路徑作為第二個參數傳給?`less`?方法:
~~~
mix.less('resources/assets/less/app.less', 'public/stylesheets/styles.css');
~~~
如果你需要重寫?[底層 Less 插件選項](https://github.com/webpack-contrib/less-loader#options),你可以將一個對象作為第三個參數傳到?`mix.less()`:
~~~
mix.less('resources/assets/less/app.less', 'public/css', {
strictMath: true
});
~~~
### Sass
`sass`?方法可以將?[Sass](http://sass-lang.com/)?編譯為 CSS。用法如下所示:
~~~
mix.sass('resources/assets/sass/app.scss', 'public/css');
~~~
跟?`less`?方法一樣,你可以將多個 Sass 文件編譯到各自的 CSS 文件中,甚至可以自定義生成的 CSS 的輸出目錄:
~~~
mix.sass('resources/assets/sass/app.sass', 'public/css')
.sass('resources/assets/sass/admin.sass', 'public/css/admin');
~~~
另外,[Node-Sass 插件選項](https://github.com/sass/node-sass#options)?也同樣可以作為第三個參數:
~~~
mix.sass('resources/assets/sass/app.sass', 'public/css', {
precision: 5
});
~~~
### Stylus
類似于 Less 和 Sass,`stylus`?方法可以將?[Stylus](http://stylus-lang.com/)?編譯為 CSS:
~~~
mix.stylus('resources/assets/stylus/app.styl', 'public/css');
~~~
你也可以安裝其他的 Stylus 插件,例如?[Rupture](https://github.com/jescalan/rupture)。首先,通過 NPM (`npm install rupture`) 來安裝插件,然后在調用?`mix.stylus()`?時引用它:
~~~
mix.stylus('resources/assets/stylus/app.styl', 'public/css', {
use: [
require('rupture')()
]
});
~~~
### PostCSS
Laravel Mix 自帶了一個用來轉換 CSS 的強大工具?[PostCSS](http://postcss.org/)。默認情況下, Mix 利用了流行的?[Autoprefixer](https://github.com/postcss/autoprefixer)?插件來自動添加所需要的 CSS3 瀏覽器引擎前綴。不過,你也可以自由添加任何適合你應用程序的插件。首先,通過 NPM 安裝所需的插件,然后在?`webpack.mix.js`?文件中引用它:
~~~
mix.sass('resources/assets/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 處理
由于 Laravel Mix 是建立在 Webpack 之上的,所以了解一些 Webpack 概念就非常有必要。編譯 CSS 的時候,Webpack 會重寫和優化樣式表中對?`url()`?的調用。 一開始聽起來可能會覺得奇怪,但這確實是一個非常強大的功能。試想一下我們要編譯一個包含圖片的相對路徑的 Sass 文件:
~~~
.example {
background: url('../images/example.png');
}
~~~
> {note} 任何給定?`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/assets/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/assets/js/app.js', 'public/js')
.sourceMaps();
~~~
## 使用腳本
Mix 提供了一些函數來處理 JavaScript 文件,像是編譯 ECMAScript 2015、模塊綁定、壓縮以及簡單地合并純 JavaScript 文件。更棒的是,這些操作都不需要進行任何自定義的配置:
~~~
mix.js('resources/assets/js/app.js', 'public/js');
~~~
僅僅這上面的一行代碼,就支持:
* ES 2015 語法
* 模塊
* 編譯?`.vue`?文件
* 生產環境壓縮代碼
### 提取依賴庫
將應用程序特定的 JavaScript 與依賴庫捆綁在一起有個潛在的缺點,會使得長期緩存更加困難。例如,即使應用程序使用的依賴庫沒有被更改,只要有代碼被單獨更新,都會強制瀏覽器重新下載所有依賴庫。
如果你打算頻繁更新應用程序的 JavaScript,應該考慮將所有的依賴庫提取到自己的文件中。如此一來,應用程序代碼的更改就不會影響到大型?`vendor.js`?文件的緩存。而 Mix 的?`extract`?方法能使之變得輕而易舉:
~~~
mix.js('resources/assets/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.js()`?為?`mix.react()`:
~~~
mix.react('resources/assets/js/app.jsx', 'public/js');
~~~
Mix 會在后臺自動下載包括?`babel-preset-react`?Babel 插件在內的庫。
### 原生 JS
類似?`mix.styles()`?合并樣式表文件,`scripts()`?方法可以合并壓縮任意數量的 JavaScript 文件:
~~~
mix.scripts([
'public/js/admin.js',
'public/js/dashboard.js'
], 'public/js/all.js');
~~~
對那些沒有用 Webpack 編譯 JavaScript 的舊項目來說,這個方法非常實用。
> {tip}?`mix.babel()`與?`mix.scripts()`?還是有些差別的。在使用上與?`scripts`?一致,但是,所有文件都會經過 Babel 編譯, 任何 ES2015 語法的代碼都會編譯成所有瀏覽器都支持的原生 JavaScript。
### 自定義 Webpack 配置
Laravel 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('assets/img', 'public/img');
~~~
## 版本控制/緩存清除
許多的開發者會對其編譯的資源文件中加上時間戳或是唯一的令牌作為后綴,以此來強迫瀏覽器加載全新的資源文件,而不是舊版本的代碼副本。你可以使用 Mix 的?`version`?方法處理它們。
`version`?方法會自動為所有編譯文件的文件名附加一個唯一的哈希值,從而實現更方便的緩存清除功能:
~~~
mix.js('resources/assets/js/app.js', 'public/js')
.version();
~~~
生成版本化文件后,你不會知道確切的文件名。因此,你應該在你的視圖中使用 Laravel 的全局輔助函數?`mix`?來正確加載名稱被哈希后的文件。`mix`?函數會自動確定被哈希的文件名稱:
~~~
<link rel="stylesheet" href="{{ mix('/css/app.css') }}">
~~~
因為在開發中通常是不需要版本化,你可以指示版本控制過程僅在?`npm run production`?運行期間進行:
~~~
mix.js('resources/assets/js/app.js', 'public/js');
if (mix.inProduction()) {
mix.version();
}
~~~
## Browsersync 重新加載
[BrowserSync](https://browsersync.io/)?會自動監控文件修改并將修改注入瀏覽器而無需手動刷新。 你可以通過調用?`mix.browserSync()`?方法啟用該支持:
~~~
mix.browserSync('my-domain.test');
// Or...
// https://browsersync.io/docs/options
mix.browserSync({
proxy: 'my-domain.test'
});
~~~
你可以傳遞一個字符串(代理)或對象(BrowserSync 設置)到該方法。 接下來,使用?`npm run watch`?命令來啟動 Webpack 的開發服務器。現在,當你編輯一個 JavaScript 腳本或 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();
~~~
- 前言
- 翻譯說明
- 發行說明
- 升級指南
- 貢獻導引
- 入門指南
- 安裝
- 配置信息
- 文件夾結構
- Homestead
- Valet
- 部署
- 核心架構
- 請求周期
- 服務容器
- 服務提供者
- Facades
- Contracts
- 基礎功能
- 路由
- 中間件
- CSRF 保護
- 控制器
- 請求
- 響應
- 視圖
- URL
- Session
- 表單驗證
- 錯誤
- 日志
- 前端開發
- Blade 模板
- 本地化
- 前端指南
- 編輯資源 Mix
- 安全相關
- 用戶認證
- Passport OAuth 認證
- 用戶授權
- 加密解密
- 哈希
- 重置密碼
- 綜合話題
- Artisan 命令行
- 廣播系統
- 緩存系統
- 集合
- 事件系統
- 文件存儲
- 輔助函數
- 郵件發送
- 消息通知
- 擴展包開發
- 隊列
- 任務調度
- 數據庫
- 快速入門
- 查詢構造器
- 分頁
- 數據庫遷移
- 數據填充
- Redis
- Eloquent ORM
- 快速入門
- 模型關聯
- Eloquent 集合
- 修改器
- API 資源
- 序列化
- 測試相關
- 快速入門
- HTTP 測試
- 瀏覽器測試 Dusk
- 數據庫測試
- 測試模擬器
- 官方擴展包
- Cashier 交易工具包
- Envoy 部署工具
- Horizon
- Scout 全文搜索
- Socialite 社會化登錄