[TOC]
### **1、簡介**
[Laravel](http://laravelacademy.org/tags/laravel "View all posts in Laravel")?[Elixir](http://laravelacademy.org/tags/elixir "View all posts in Elixir")?提供了一套干凈、平滑的 API 用于為 Laravel 應用定義基本的[Gulp](http://gulpjs.com/)任務。Elixir 支持一些通用的?[CSS](http://laravelacademy.org/tags/css "View all posts in CSS")?和?[JavaScript](http://laravelacademy.org/tags/javascript "View all posts in JavaScript")?預處理器,甚至測試工具。使用方法鏈,Elixir 允許你平滑的定義資源管道。例如:
~~~
elixir(function(mix) {
mix.sass('app.scss')
.coffee('app.coffee');
});
~~~
如果你曾經對如何使用?[Gulp](http://laravelacademy.org/tags/gulp "View all posts in Gulp")?和[編譯](http://laravelacademy.org/tags/%e7%bc%96%e8%af%91 "View all posts in 編譯")[前端資源](http://laravelacademy.org/tags/%e5%89%8d%e7%ab%af%e8%b5%84%e6%ba%90 "View all posts in 前端資源")感到困惑,那么你會愛上 Laravel ?Elixir。然而,并不是強制要求在開發期間使用它。你可以自由選擇使用任何前端資源管道工具,或者壓根不使用。
### **2、安裝 & 設置**
#### **2.1 安裝 Node**
在開始 Elixir 之前,必須首先確保?[Node.js](http://laravelacademy.org/tags/node-js "View all posts in Node.js")?在機器上已經安裝:
~~~
node -v
~~~
默認情況下,Laravel Homestead 包含你需要的一切;然而,如果你不使用 Vagrant,你也可以通過訪問[Node的下載頁面](http://nodejs.org/download/)輕松的安裝 Node。
#### **2.2 Gulp**
接下來,需要安裝 Gulp 作為全局 NPM 包:
~~~
npm install --global gulp
~~~
#### **2.3 Laravel Elixir**
最后,在新安裝的 Laravel 根目錄下,你會發現有一個?`package.json`?文件。該文件和?`composer.json`?一樣,只不過是用來定義 Node 依賴而非 PHP,你可以通過運行如下命令來安裝需要的依賴:
~~~
npm install
~~~
如果你正在 Windows 系統上開發,需要在運行?`npm install`?命令時帶上?`--no-bin-links`:
~~~
npm install --no-bin-links
~~~
### **3、運行Elixir**
Elixir 基于 Gulp,所以要運行 Elixir 命令你只需要在終端中運行?`gulp`?命令即可。添加?`--production`?標識到命令將會最小化 CSS 和 JavaScript 文件:
~~~
// Run all tasks...
gulp
// Run all tasks and minify all CSS and JavaScript...
gulp --production
~~~
#### **監控前端資源改變**
由于每次修改前端資源后都要運行?`gulp`?很不方便,可以使用?`gulp watch`?命令。該命令將會一直在終端運行并監控前端文件的改動。當改變發生時,新文件將會自動被編譯:
~~~
gulp watch
~~~
### **4、處理CSS**
項目根目錄下的?`gulpfile.js`?文件包含了所有的 Elixir 任務。Elixir 任務可以使用方法鏈的方式鏈接起來用于定義前端資源如何被編譯。
#### **4.1?[Less](http://laravelacademy.org/tags/less "View all posts in Less")**
要將?[Less](http://lesscss.org/)?編譯成 CSS,可以使用?`less`?方法。`less`?方法假定你的 Less 文件都放在?`resources/assets/less`。默認情況下,本例中該任務會將編譯后的 CSS 放到`public/css/app.css`:
~~~
elixir(function(mix) {
mix.less('app.less');
});
~~~
你還可以將多個 Less 文件編譯成單個 CSS 文件。同樣,該文件會被放到?`public/css/app.css`:
~~~
elixir(function(mix) {
mix.less([
'app.less',
'controllers.less'
]);
});
~~~
如果你想要自定義編譯后文件的輸出位置,可以傳遞第二個參數到?`less`?方法:
~~~
elixir(function(mix) {
mix.less('app.less', 'public/stylesheets');
});
// Specifying a specific output filename...
elixir(function(mix) {
mix.less('app.less', 'public/stylesheets/style.css');
});
~~~
#### **4.2?[Sass](http://laravelacademy.org/tags/sass "View all posts in Sass")**
`sass`?方法允許你將?[Sass](http://sass-lang.com/)?編譯成 CSS。假定你的 Sass 文件存放在`resources/assets/sass`,你可以像這樣使用該方法:
~~~
elixir(function(mix) {
mix.sass('app.scss');
});
~~~
同樣,和?`less`?方法一樣,你可以將多個腳本編譯成單個 CSS 文件,甚至自定義結果 CSS 的輸出路徑:
~~~
elixir(function(mix) {
mix.sass([
'app.scss',
'controllers.scss'
], 'public/assets/css');
});
~~~
#### **4.3 原生CSS**
如果你只想要將多個原生 CSS 樣式文件[合并](http://laravelacademy.org/tags/%e5%90%88%e5%b9%b6 "View all posts in 合并")到一個文件,可以使用?`styles`?方法。傳遞給該方法的路徑相對于`resources/assets/css`?目錄,結果 CSS 被存放在?`public/css/all.css`:
~~~
elixir(function(mix) {
mix.styles([
'normalize.css',
'main.css'
]);
});
~~~
當然,你還可以通過傳遞第二個參數到?`styles`?方法來輸出結果文件到一個自定義路徑:
~~~
elixir(function(mix) {
mix.styles([
'normalize.css',
'main.css'
], 'public/assets/css');
});
~~~
#### **4.4 源地圖**
默認源地圖被啟用,所以,對于每一個你編譯過的文件都可以在同一目錄下找到一個對應的?`*.css.map`?文件。這種匹配允許你在瀏覽器中調試時將編譯過的樣式選擇器回溯到原來的 Sass 或 Less。
如果你不想為 CSS 生成源地圖,可以使用一個簡單配置選項關閉它們:
~~~
elixir.config.sourcemaps = false;
elixir(function(mix) {
mix.sass('app.scss');
});
~~~
### **5、處理JavaScript**
Elixir 還提供了多個函數幫助你處理 JavaScript 文件,例如編譯 ECMAScript 6,CoffeeScript,Browserify,最小化以及簡單連接原生JavaScript文件。
#### **5.1?CoffeeScript**
`coffee`?方法用于將?[CoffeeScript](http://coffeescript.org/)?編譯成原生 JavaScript。該方法接收關聯到?`resources/assets/coffee`?目錄的 CoffeeScript 文件的一個字符串或數組并在?`public/js`?目錄下生成單個?`app.js`?文件:
~~~
elixir(function(mix) {
mix.coffee(['app.coffee', 'controllers.coffee']);
});
~~~
#### **[5.2](http://laravelacademy.org/tags/5-2 "View all posts in 5.2")?Browserify**
Elixir 還提供了?`browserify`?方法,從而讓你可以在瀏覽器中引入模塊并使用 EcmaScript 6。
該任務假定你的腳本都存放在?`resources/assets/js`?而且將結果文件存放到?`public/js/bundle.js`:
~~~
elixir(function(mix) {
mix.browserify('main.js');
});
~~~
除了處理 Partialify 和 Babelify,還可以安裝并添加更多:
~~~
npm install vueify --save-dev
~~~
~~~
elixir.config.js.browserify.transformers.push({
name: 'vueify',
options: {}
});
elixir(function(mix) {
mix.browserify('main.js');
});
~~~
#### **5.3 Babel**
`babel`?方法可用于將[EcmaScript 6和7](https://babeljs.io/docs/learn-es2015/)編譯成原生JavaScript。該方法接收相對于?`resources/assets/js`?目錄的文件數組,并在?`public/js`?目錄下生成單個`all.js`:
~~~
elixir(function(mix) {
mix.babel([
'order.js',
'product.js'
]);
});
~~~
要選擇不同的輸出路徑,只需將目標路徑作為第二個參數傳遞給該方法。處了 Babel 編譯之外,`babel`?和`mix.scripts()`的使用方法和功能差不多。
#### **5.4 腳本**
如果你有多個 JavaScript 文件想要編譯成單個文件,可以使用?`scripts`?方法。
`scripts`?方法假定所有路徑相對于?`resources/assets/js`?目錄,而且所有結果 JavaScript 默認存放在`public/js/all.js`:
~~~
elixir(function(mix) {
mix.scripts([
'jquery.js',
'app.js'
]);
});
~~~
如果你需要將多個腳本集合合并到不同的文件,需要多次調用?`scripts`?方法。該方法的第二個參數決定每個合并的結果文件名:
~~~
elixir(function(mix) {
mix.scripts(['app.js', 'controllers.js'], 'public/js/app.js')
.scripts(['forum.js', 'threads.js'], 'public/js/forum.js');
});
~~~
如果你需要將多個腳本合并到給定目錄,可以使用?`scriptsIn`?方法。結果 JavaScript 會被存放到`public/js/all.js`:
~~~
elixir(function(mix) {
mix.scriptsIn('public/js/some/directory');
});
~~~
### **6、拷貝文件/目錄**
你可以使用?`copy`?方法拷貝文件/目錄到新路徑,所有操作都相對于項目根目錄:
~~~
elixir(function(mix) {
mix.copy('vendor/foo/bar.css', 'public/css/bar.css');
});
elixir(function(mix) {
mix.copy('vendor/package/views', 'resources/views');
});
~~~
### **7、[版本號](http://laravelacademy.org/tags/%e7%89%88%e6%9c%ac%e5%8f%b7 "View all posts in 版本號")/緩存刷新**
很多開發者會給編譯的前端資源添加時間戳或者唯一令牌后綴以強制瀏覽器加載最新版本而不是代碼的緩存副本。Elixir 可以使用?`version`?方法為你處理這種情況。
`version`?方法接收相對于?`public`?目錄的文件名,附加唯一hash到文件名,從而實現緩存刷新。例如,生成的文件名看上去是這樣——`all-16d570a7.css`:
~~~
elixir(function(mix) {
mix.version('css/all.css');
});
~~~
生成版本文件后,可以在視圖中使用 Elixir 全局的 PHP 幫助函數?`elixir`?方法來加載相應的帶hash值的前端資源,`elixir`?函數會自動判斷hash文件名:
~~~
<link rel="stylesheet" href="{{ elixir('css/all.css') }}">
~~~
#### **給多個文件加上版本號**
你可以傳遞一個數組到?`version`?方法來為多個文件添加版本號:
~~~
elixir(function(mix) {
mix.version(['css/all.css', 'js/app.js']);
});
~~~
一旦文件被加上版本號,就可以使用幫助函數?`elixir`?來生成指向該hash文件的鏈接。記住,你只需要傳遞沒有hash值的文件名到`elixir`方法。該幫助函數使用未加hash值的文件名來判斷文件當前的hash版本:
~~~
<link rel="stylesheet" href="{{ elixir('css/all.css') }}">
<script src="{{ elixir('js/app.js') }}"></script>
~~~
### **8、BrowserSync**
BrowserSync 會在你修改前端資源后自動刷新瀏覽器,運行?`gulp watch`?命令時你可以使用?`browserSync`?方法告知Elixir 啟動一個 BrowserSync 服務器:
~~~
elixir(function(mix) {
mix.browserSync();
});
~~~
運行`gulp watch`后,使用?`http://homestead.app:3000`?訪問應用來開啟瀏覽器同步。如果你在本地開發中使用`homestead.app`之外的其它域名,可以傳遞域名參數到?`browserSync`?方法:
~~~
elixir(function(mix) {
mix.browserSync({
proxy: 'project.app'
});
});
~~~
### **9、調用存在的Gulp任務**
如果你需要從 Elixir 調用已存在的 Gulp 任務,可以使用?`task`?方法。例如,假定你有一個調用時只是簡單說幾句話的 Gulp 任務:
~~~
gulp.task('speak', function() {
var message = 'Tea...Earl Grey...Hot';
gulp.src('').pipe(shell('say ' + message));
});
~~~
如果你想要從 Elixir 中調用該任務,使用?`mix.task`?方法并傳遞任務名作為該方法的唯一參數:
~~~
elixir(function(mix) {
mix.task('speak');
});
~~~
#### **自定義監控者**
如果你需要注冊一個監控器在每一次文件修改時都運行自定義任務,傳遞一個正則表達式作為?`task`?方法的第二個參數:
~~~
elixir(function(mix) {
mix.task('speak', 'app/**/*.php');
});
~~~
### **10、編寫 Elixir?[擴展](http://laravelacademy.org/tags/%e6%89%a9%e5%b1%95 "View all posts in 擴展")**
如果你需要比 Elixir 的?`task`?方法所提供的更加靈活的功能,可以創建自定義的 Elixir 擴展。Elixir 擴展允許你傳遞參數到自定義任務,例如,你可以像這樣編寫一個擴展:
~~~
// File: elixir-extensions.js
var gulp = require('gulp');
var shell = require('gulp-shell');
var Elixir = require('laravel-elixir');
var Task = Elixir.Task;
Elixir.extend('speak', function(message) {
new Task('speak', function() {
return gulp.src('').pipe(shell('say ' + message));
});
});
// mix.speak('Hello World');
~~~
就是這樣簡單!注意你的特定Gulp邏輯應該放到閉包函數里作為第二個參數傳遞給?`Task`?構造器。你可以將其放在`Gulpfile`?頂端,或者將其解析到自定義的任務文件。例如,如果你將擴展放在?`elixir-extensions.js`,可以在主`Gulpfile`?中像這樣引入該文件:
~~~
// File: Gulpfile.js
var elixir = require('laravel-elixir');
require('./elixir-extensions')
elixir(function(mix) {
mix.speak('Tea, Earl Grey, Hot');
});
~~~
#### **自定義監控器**
如果你想要自定義任務在運行?`gulp watch`?的時候被觸發,可以注冊一個監控器:
~~~
new Task('speak', function() {
return gulp.src('').pipe(shell('say ' + message));
}).watch('./app/**');
~~~
- 序言
- 發行版本說明
- 升級指南
- 貢獻代碼
- 開始
- 安裝
- 配置
- Laravel Homestead
- 基礎
- HTTP 路由
- HTTP 中間件
- HTTP 控制器
- HTTP 請求
- HTTP 響應
- 視圖
- Blade 模板引擎
- 架構
- 一次請求的生命周期
- 應用目錄結構
- 服務提供者
- 服務容器
- 門面(Facades)
- 數據庫
- 起步
- 查詢構建器
- 遷移
- 填充數據
- Eloquent ORM
- 起步
- 關聯關系
- 集合
- 訪問器&修改器
- 序列化
- 服務
- 用戶認證
- 用戶授權
- Artisan Console
- 訂閱支付實現:Laravel Cashier
- 緩存
- 集合
- 集成前端資源:Laravel Elixir
- 加密
- 錯誤&日志
- 事件
- 文件系統/云存儲
- 哈希
- 輔助函數
- 本地化
- 郵件
- 包開發
- 分頁
- Redis
- 隊列
- Session
- Envoy Task Runner
- 任務調度
- 測試
- 驗證
- 新手入門指南
- 簡單任務管理系統
- 帶用戶功能的任務管理系統