Skip to content

Laravel Elixir

介绍

Laravel Elixir 为你的 Laravel 应用程序提供了一个简洁、流畅的 API,用于定义基本的 Gulp 任务。Elixir 支持多种常见的 CSS 和 JavaScript 预处理器,甚至包括测试工具。通过方法链,Elixir 允许你流畅地定义你的资源管道。例如:

javascript
elixir(function(mix) {
    mix.sass('app.scss')
       .coffee('app.coffee');
});

如果你曾经对如何开始使用 Gulp 和资源编译感到困惑,你会喜欢 Laravel Elixir。不过,在开发应用程序时,你并不需要使用它。你可以自由选择任何资源管道工具,甚至可以不使用任何工具。

安装与设置

安装 Node

在触发 Elixir 之前,你必须先确保你的机器上安装了 Node.js。

php
node -v

默认情况下,Laravel Homestead 包含了你所需的一切;然而,如果你不使用 Vagrant,你可以通过访问 Node.js 下载页面轻松安装 Node。

Gulp

接下来,你需要将 Gulp 作为全局 NPM 包引入:

php
npm install --global gulp-cli

如果你使用版本控制系统,你可能希望运行 npm shrinkwrap 来锁定你的 NPM 需求:

php
npm shrinkwrap

一旦你运行了这个命令,可以将 npm-shrinkwrap.json 提交到源代码控制中。

Laravel Elixir

剩下的唯一步骤就是安装 Elixir!在 Laravel 的新安装中,你会在根目录找到一个 package.json 文件。可以将其视为你的 composer.json 文件,只不过它定义的是 Node 依赖而不是 PHP。你可以通过运行以下命令安装它引用的依赖:

php
npm install

如果你在 Windows 系统上开发,或者在 Windows 主机系统上运行你的虚拟机,你可能需要在启用 --no-bin-links 开关的情况下运行 npm install 命令:

php
npm install --no-bin-links

运行 Elixir

Elixir 构建在 Gulp 之上,因此要运行你的 Elixir 任务,你只需在终端中运行 gulp 命令。将 --production 标志添加到命令中将指示 Elixir 压缩你的 CSS 和 JavaScript 文件:

php
// 运行所有任务...
gulp

// 运行所有任务并压缩所有 CSS 和 JavaScript...
gulp --production

监视资源的变化

由于在每次更改资源后在终端中运行 gulp 命令很不方便,你可以使用 gulp watch 命令。此命令将在你的终端中持续运行,并监视你的资源是否有任何更改。当发生更改时,新文件将自动编译:

php
gulp watch

处理样式表

项目根目录中的 gulpfile.js 文件包含了你所有的 Elixir 任务。Elixir 任务可以链式调用,以定义你的资源应如何编译。

Less

要将 Less 编译为 CSS,你可以使用 less 方法。less 方法假定你的 Less 文件存储在 resources/assets/less 中。默认情况下,此示例的编译 CSS 将放置在 public/css/app.css 中:

javascript
elixir(function(mix) {
    mix.less('app.less');
});

你还可以将多个 Less 文件合并为一个 CSS 文件。同样,生成的 CSS 将放置在 public/css/app.css 中:

javascript
elixir(function(mix) {
    mix.less([
        'app.less',
        'controllers.less'
    ]);
});

如果你希望自定义编译 CSS 的输出位置,可以将第二个参数传递给 less 方法:

javascript
elixir(function(mix) {
    mix.less('app.less', 'public/stylesheets');
});

// 指定特定的输出文件名...
elixir(function(mix) {
    mix.less('app.less', 'public/stylesheets/style.css');
});

Sass

sass 方法允许你将 Sass 编译为 CSS。假设你的 Sass 文件存储在 resources/assets/sass 中,你可以这样使用该方法:

javascript
elixir(function(mix) {
    mix.sass('app.scss');
});

同样,像 less 方法一样,你可以将多个 Sass 文件编译为一个 CSS 文件,甚至可以自定义生成的 CSS 的输出目录:

javascript
elixir(function(mix) {
    mix.sass([
        'app.scss',
        'controllers.scss'
    ], 'public/assets/css');
});

纯 CSS

如果你只想将一些纯 CSS 样式表合并为一个文件,可以使用 styles 方法。传递给此方法的路径是相对于 resources/assets/css 目录的,生成的 CSS 将放置在 public/css/all.css 中:

javascript
elixir(function(mix) {
    mix.styles([
        'normalize.css',
        'main.css'
    ]);
});

当然,你也可以通过将第二个参数传递给 styles 方法来自定义生成文件的输出位置:

javascript
elixir(function(mix) {
    mix.styles([
        'normalize.css',
        'main.css'
    ], 'public/assets/css');
});

源映射

源映射默认启用。因此,对于每个编译的文件,你将在同一目录中找到一个伴随的 *.css.map 文件。此映射允许你在浏览器中调试时将编译的样式表选择器追溯到原始的 Sass 或 Less。

如果你不希望为 CSS 生成源映射,可以使用一个简单的配置选项禁用它们:

javascript
elixir.config.sourcemaps = false;

elixir(function(mix) {
    mix.sass('app.scss');
});

处理脚本

Elixir 还提供了几个函数来帮助你处理 JavaScript 文件,例如编译 ECMAScript 6、编译 CoffeeScript、Browserify、压缩以及简单地连接纯 JavaScript 文件。

CoffeeScript

coffee 方法可用于将 CoffeeScript 编译为纯 JavaScript。coffee 函数接受一个字符串或 CoffeeScript 文件数组,相对于 resources/assets/coffee 目录,并在 public/js 目录中生成一个 app.js 文件:

javascript
elixir(function(mix) {
    mix.coffee(['app.coffee', 'controllers.coffee']);
});

Browserify

Elixir 还附带了一个 browserify 方法,它为你提供了在浏览器中使用模块和 ECMAScript 6 以及 JSX 的所有好处。

此任务假定你的脚本存储在 resources/assets/js 中,并将生成的文件放置在 public/js/main.js 中。你可以将自定义输出位置作为可选的第二个参数传递:

javascript
elixir(function(mix) {
    mix.browserify('main.js');
});

// 指定特定的输出文件名...
elixir(function(mix) {
    mix.browserify('main.js', 'public/javascripts/main.js');
});

虽然 Browserify 附带了 Partialify 和 Babelify 转换器,但你可以自由安装和添加更多转换器:

php
npm install aliasify --save-dev
javascript
elixir.config.js.browserify.transformers.push({
    name: 'aliasify',
    options: {}
});

elixir(function(mix) {
    mix.browserify('main.js');
});

Babel

babel 方法可用于将 ECMAScript 6 和 7JSX 编译为纯 JavaScript。此函数接受一个文件数组,相对于 resources/assets/js 目录,并在 public/js 目录中生成一个 all.js 文件:

javascript
elixir(function(mix) {
    mix.babel([
        'order.js',
        'product.js',
        'react-component.jsx'
    ]);
});

要选择不同的输出位置,只需将所需的路径指定为第二个参数。此方法的签名和功能与 mix.scripts() 相同,但不包括 Babel 编译。

脚本

如果你有多个 JavaScript 文件想要合并为一个文件,可以使用 scripts 方法。

scripts 方法假定所有路径都是相对于 resources/assets/js 目录的,并默认将生成的 JavaScript 放置在 public/js/all.js 中:

javascript
elixir(function(mix) {
    mix.scripts([
        'jquery.js',
        'app.js'
    ]);
});

如果你需要将多个脚本集合并为不同的文件,可以多次调用 scripts 方法。传递给方法的第二个参数决定了每次连接的结果文件名:

javascript
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 中:

javascript
elixir(function(mix) {
    mix.scriptsIn('public/js/some/directory');
});

复制文件和目录

copy 方法可用于将文件和目录复制到新位置。所有操作都是相对于项目的根目录进行的:

javascript
elixir(function(mix) {
	mix.copy('vendor/foo/bar.css', 'public/css/bar.css');
});

elixir(function(mix) {
	mix.copy('vendor/package/views', 'resources/views');
});

版本控制 / 缓存清除

许多开发人员在编译的资源后面加上时间戳或唯一标记,以强制浏览器加载新资源,而不是提供过时的代码副本。Elixir 可以使用 version 方法为你处理此问题。

version 方法接受一个相对于 public 目录的文件名,并将一个唯一的哈希附加到文件名上,以实现缓存清除。例如,生成的文件名将类似于:all-16d570a7.css

javascript
elixir(function(mix) {
    mix.version('css/all.css');
});

生成版本化文件后,你可以在 视图 中使用 Laravel 的全局 elixir PHP 辅助函数来加载适当的哈希资源。elixir 函数将自动确定哈希文件的名称:

php
<link rel="stylesheet" href="{{ elixir('css/all.css') }}">

版本控制多个文件

你可以将一个数组传递给 version 方法以对多个文件进行版本控制:

javascript
elixir(function(mix) {
    mix.version(['css/all.css', 'js/app.js']);
});

一旦文件被版本化,你可以使用 elixir 辅助函数生成指向正确哈希文件的链接。请记住,你只需将未哈希文件的名称传递给 elixir 辅助函数。辅助函数将使用未哈希的名称来确定文件的当前哈希版本:

php
<link rel="stylesheet" href="{{ elixir('css/all.css') }}">

<script src="{{ elixir('js/app.js') }}"></script>

BrowserSync

BrowserSync 在你对前端资源进行更改后会自动刷新你的网页浏览器。你可以使用 browserSync 方法来指示 Elixir 在运行 gulp watch 命令时启动一个 BrowserSync 服务器:

javascript
elixir(function(mix) {
    mix.browserSync();
});

一旦你运行 gulp watch,使用端口 3000 访问你的 Web 应用程序以启用浏览器同步:http://homestead.app:3000。如果你在本地开发中使用的域名不是 homestead.app,你可以将一个 选项 数组作为第一个参数传递给 browserSync 方法:

javascript
elixir(function(mix) {
    mix.browserSync({
    	proxy: 'project.app'
    });
});

调用现有的 Gulp 任务

如果你需要从 Elixir 调用现有的 Gulp 任务,可以使用 task 方法。举个例子,假设你有一个 Gulp 任务,在调用时简单地说出一些文本:

javascript
gulp.task('speak', function() {
    var message = 'Tea...Earl Grey...Hot';

    gulp.src('').pipe(shell('say ' + message));
});

如果你希望从 Elixir 调用此任务,请使用 mix.task 方法,并将任务名称作为唯一参数传递给该方法:

javascript
elixir(function(mix) {
    mix.task('speak');
});

自定义监视器

如果你需要注册一个监视器以在某些文件被修改时运行你的自定义任务,请将正则表达式作为第二个参数传递给 task 方法:

javascript
elixir(function(mix) {
    mix.task('speak', 'app/**/*.php');
});

编写 Elixir 扩展

如果你需要比 Elixir 的 task 方法提供的更灵活的功能,可以创建自定义 Elixir 扩展。Elixir 扩展允许你向自定义任务传递参数。例如,你可以这样编写一个扩展:

javascript
// 文件: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 中引入该文件,如下所示:

javascript
// 文件:Gulpfile.js

var elixir = require('laravel-elixir');

require('./elixir-extensions')

elixir(function(mix) {
    mix.speak('Tea, Earl Grey, Hot');
});

自定义监视器

如果你希望在运行 gulp watch 时重新触发自定义任务,可以注册一个监视器:

javascript
new Task('speak', function() {
    return gulp.src('').pipe(shell('say ' + message));
})
.watch('./app/**');