Laravel Mix与资源编译
Laravel Mix 提供的资源编译功能比Webpack来的舒服,也是Laravel官方推荐的资源编译工具。
参考文档:Laravel 的资源任务编译器 Laravel Mix
安装
先确保安装了npm和node,运行下面命令进行检查:
node -v
npm -v
Laravel5自带了package.json
,内容如下:
{
...
"devDependencies": {
"axios": "^0.17",
"bootstrap-sass": "^3.3.7",
"cross-env": "^5.1",
"jquery": "^3.2",
"laravel-mix": "^1.0",
"lodash": "^4.17.4",
"vue": "^2.5.7"
}
}
说明自带了sass版本的bootstrap
、jquery
等,可以看到其中还有laravel-mix
。所以,直接运行:
npm install
如果在windows上或是在windows上运行的虚拟机里,那需要加--no-bin-links
:
npm install --no-bin-links
运行
安装完之后就可以运行Mix了:
// 运行所有Mix任务
npm run dev
// 运行所有Mix任务但缩小输出
npm run production
如果资源文件修改了的话,需要重新运行上述命令。
上述命令可能报错,因为找不到 cross-env
命令,查看package.json
得知:
{
...
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
...
},
...
}
development
脚本中需要用到 cross-env
命令,我们把这要用到这个命令的脚本代码都更改为:
node node_modules/cross-env/dist/bin/cross-env.js
即可,改完后就是:
{
...
"scripts": {
"dev": "npm run development",
"development": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
...
},
...
}
下面的 watch
命令可以帮你监视资源文件修改,并自动编译。
// 资源更改时自动编译
npm run watch
// watch失效时,用watch-poll
npm run watch-poll
样式
webpack.mix.js
相当于Webpack中的配置清单。Mix 任务支持链式调用,可以精确定义资源的编译方式。
Less
less
方法可以把Less编译为css,只需在webpack.mix.js写入下方代码,即可把app.less
编译、保存为 public/css/app.css
文件 。
mix.less('resource/assets/less/app.less', 'public/css');
编译多个:
mix.less('resources/assets/less/app.less', 'public/css')
.less('resources/assets/less/admin.less', 'public/css');
指定文件名:
mix.less('resources/assets/less/app.less', 'public/stylesheets/styles.css');
指定 Less插件 选项:
mix.less('resources/assets/less/app.less', 'public/css', {
strictMath: true
});
Sass
与Less的用法一样,不过底层的编译器使用的是 Node-Sass 插件选项。
mix.sass('resources/assets/sass/app.scss', 'public/css');
Stylus
与Less用法一样,不可以指定其他Stylus插件,如 Rupture(记得通过npminstall rupture
)安装插件,在使用时代码如下:
mix.stylus('resources/assets/stylus/app.styl', 'public/css', {
use: [
require('rupture')()
]
});
纯CSS
用法也类似,而且可以使用 styles
方法合并css文件:
mix.styles([
'public/css/vendor/normalize.css',
'public/css/vendor/videojs.css'
], 'public/css/all.css');
URL处理
在编译CSS时,Webpack会优化样式表中的 url()
调用,例如:
.example {
background: url('../images/example.png');
}
上述代码在默认情况下,图片会被移动到public/images
目录下面,并且会被编译成:
.example {
background: url(/images/example.png?d41d8cd98f00b204e9800998ecf8427e);
}
注意:绝对路径如 url('/images/example.png')
或 url('http://example.com/images/example.png')
不会被修改
如果不希望处理 url()
调用,那么可以禁用:
mix.sass('resources/assets/app/app.scss', 'public/css')
.options({
processCssUrls: false
});
脚本
编译
上代码:
mix.js('resources/assets/js/app.js', 'public/js');
这一行代码包括了:
- ES 2015 语法
- 模块化
- 编译
.vue
文件 - 生产环境压缩代码
提取依赖库
将js和依赖库捆绑在一起一个很大缺点就是每次都需要打包合并成一个文件,这样会使得缓存效率低下,一个好的方法是使用 extract
方法将依赖库单独提取出来:
mix.js('resources/assets/js/app.js', 'public/js')
.extract(['vue'])
这样一来,Mix 将生成三个文件:
public/js/manifest.js
: Webpack 运行的内容清单public/js/vendor.js
:依赖库public/js/app.js
: 应用代码
他们在html中的引入顺序为:
<script src="/js/manifest.js"></script>
<script src="/js/vendor.js"></script>
<script src="/js/app.js"></script>
React
mix.react('resources/assets/js/app.jsx', 'public/js');
原生JS
mix.scripts([
'public/js/admin.js',
'public/js/dashboard.js'
], 'public/js/all.js');
实战:初探
假定已使用 npm install
安装了各种依赖。
样例代码和目录结构
查看 webpack.mix.js
文件内容:
mix.js('resources/assets/js/app.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
它编译了一个脚本文件 app.js
和一个样式文件 app.scss
,进入到 resource/assets/
文件夹可以找到这俩文件。先来看看这个文件夹的结构:
.
├── js
│ ├── app.js
│ ├── bootstrap.js
│ └── components
│ └── ExampleComponent.vue
└── sass
├── app.scss
└── _variables.scss
components
目录从来放 vue
组件,默认有一个 ExampleComponent.vue
文件,相当于Hello world。
查看 app.js
代码:
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue'));
const app = new Vue({
el: '#app'
});
它依次干了以下事情:
- 引入bootstrap模块 (不是指Bootstrap框架,而是初始化工作)
- 引入vue模块并挂载的
window.Vue
- 加载
ExampleComponent.vue
组件 - 初始化Vue
跑起来
好了,看完代码之后,有过资源编译经验的朋友可能已经通了,这和以往Webpack+各种编译器的使用方法是一样的。那现在我们让这个Hello World程序跑起来。
我们在routes/web.php
新加一条路由:
Route::get('/hellomix', function() {
return view('hellomix');
});
创建前端模板文件 resource/views/hellomix.blade.php
,写入代码:
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Styles -->
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
<example-component></example-component>
</div>
<!-- Scripts -->
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
注意:上面使用 mix
方法来输出 app.css
和 app.js
的正确路径,建议回看 webpack.mix.js
的配置。
接着启动资源编译器:
npm run watch
访问刚刚定义的路由即可。