12 9 6 3
just a phper
laravel之laravel-elixir以及gulp的使用

前言

“php是世界上最好的语言, laravel是php最好的框架,elixir是laravel管理前端资源的神器。”
---别人说的。
laravel-elixir的确给phper在处理繁杂前端资源方面上带来了不少方便
但是我发现 在 version > 5.3 之后, laravel没有用基于gulp的laravel-elixir,而是基于webpack的laravel-mix
抛弃了gulp,而用webpack .两者大同小异,不得不说,最近webpack的确火起来了
当然,本文是在laravel 5.3上谈laravel-elixir的。

安装以及配置

安装Node

npm 是nodejs非官方但公认的 nodejs包管理器,安装nodejs也就附带安装了npm
在Centos下,

方法一:在nodejs官网nodejs官网下载源码安装包 来安装
方法二:官方提供的方法:nodejs安装其实就是yum安装
Alternatively for Node.js v7:
curl --silent --location https://rpm.nodesource.com/setup_7.x | bash -
Then install, as root:
yum -y install nodejs


安装完,执行npm --version 查看npm版本
执行node --version查看nodejs版本

安装 gulp

通过 npm 安装gulp (全局安装gulp) :
npm install --global gulp
(作为项目的开发依赖安装) :
npm install --save-dev gulp
执行gulp --version 查看版本。

安装 Laravel Elixir

去到laravel 根目录下,会发现有一个package.json 文件。该文件和composer.json一样,只不过是用来定义Node依赖而非PHP,你可以通过运行如下命令来安装需要的依赖:
npm install
如果是在windows 下,需要在运行npm install命令时带上--no-bin-links:
npm install --no-bin-links

运行 Laravel Elixir

生成最小化(生产环境)

Elixir基于Gulp,所以要运行Elixir命令你只需要在终端中运行gulp命令即可。
添加--production标识到命令将会最小化CSS和JavaScript文件:
gulp --production

监控前端资源改变

由于每次修改前端资源后都要运行gulp很不方便,可以使用gulp watch命令。
该命令将会一直在终端运行并监控前端文件的改动。当改变发生时,新文件将会自动被编译:
gulp watch

处理CSS

less 资源

要将Less编译成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');
});

sass 资源

sass方法允许你将Sass编译成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');
});

原生css

如果你只想要将多个原生CSS样式文件合并到一个文件,可以使用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');});

源地图

默认源地图被启用,所以,对于每一个你编译过的文件都可以在同一目录下找到一个对应的*.css.map文件。
这种匹配允许你在浏览器中调试时将编译过的样式选择器回溯到原来的Sass或Less。

如果你不想为CSS生成源地图,可以使用一个简单配置选项关闭它们:

elixir.config.sourcemaps = false;

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

处理javascript

Elixir还提供了多个函数帮助你处理JavaScript文件,例如编译ECMAScript 6,CoffeeScript,Browserify,最小化以及简单连接原生JavaScript文件。

CoffeeScript

coffee方法用于将CoffeeScript编译成原生JavaScript。该方法接收关联到resources/assets/coffee目录的CoffeeScript文件的一个字符串或数组并在public/js目录下生成单个app.js文件:

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

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');
});

Babel

babel方法可用于将EcmaScript 6和7编译成原生JavaScript。
该方法接收相对于resources/assets/js目录的文件数组,并在public/js目录下生成单个all.js:

elixir(function(mix) {
    mix.babel([
        'order.js',
        'product.js'
    ]);});

要选择不同的输出路径,只需将目标路径作为第二个参数传递给该方法。
除了Babel编译之外,babel和mix.scripts()的使用方法和功能差不多。

原生javascript脚本

如果你有多个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');
});

版本号以及缓存刷新

很多开发者会给编译的前端资源添加时间戳或者唯一令牌后缀以强制浏览器加载最新版本而不是代码的缓存副本。
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>

调用存在的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');
});

编写Elixir扩展

如果你需要比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-elixir 是基于gulp的,要用elixir得先会用gulp,“用过都说好”

自由转载-非商用-非衍生-保持署名(创意共享3.0许可证