larave-mix是位于webpack顶层的一个简洁的配置层,在80%的的状况下使用laravel mix会使操做变的很是简单。尽管webpack很是的强大,但大部分人都认为webpack的学习曲线很是陡峭。可是若是你没必要用再担忧这些了呢?javascript
看一下基本的webpack.mix.js文件,让咱们想象一下咱们如今只须要编译javascript(ES6)和sass文件:css
let mix = require('laravel-mix'); mix.sass('src/app.sass', 'dist') .js('src/app.js', 'dist');
怎么样,简单吗?html
1. 编译sass文件, ./src/app.sass到 ./dist/app.css前端
2. 打包在./src/app.js的全部js(包括任何依赖)到 ./dist/app.js。vue
使用这个配置文件,能够在命令行触发webpack指令:node_modules/bin/webpackjava
在开发模式下,并不须要压缩输出文件,若是在执行webpack的时候加上环境变量:export NODE_ENV=production && webpack,文件会自动压缩node
可是若是你更喜欢使用Less而不是Sass呢?没问题,只要把mix.sass()换成mix.less()就OK了。react
使用laravel-mix,你会使发现大部分webpack任务会变得更又把握jquery
尽管laravel-mix对于laravel使用来讲最优的,但也能被用于任何其余的应用。webpack
laravel项目
laravel已经包含了你所须要的一切,简易步骤:
1. 安装laravel
2. 运行 npm install
3. 看一下你的webpack.mix.js ,而后就done了
你能够在命令行运行 npm run watch 来监视你的前段资源改变,而后从新编译。
注:在项目根目录下并无webpack.config.js配置文件,laravel默认指向根目录下的配置文件。若是你须要本身配置它,你能够把它拷贝到根目录下,同时修改package.json里的npm脚本: cp node_modules/laravel-mix/setup/webpack.config.js ./
.
独立项目
首先使用npm或者yarn安装laravel-mix,而后把示例配置文件复制到项目根目录下
mkdir my-app && cd my-app npm init -y npm install laravel-mix --save-dev cp -r node_modules/laravel-mix/setup/** ./
如今你会有以下的目录结构
laravel-mix 包括两个核心组件
打开你的webpack.mix.js文件:
let mix = require('laravel-mix'); mix.js('src/app.js', 'dist') .sass('src/app.scss', 'dist');
注意源文件的路径,而后建立匹配的目录结构(你也能够改为你喜欢的结构)。如今都准备好了,在命令行运行node_modules/.bin/webpack 编译全部文件,而后你将会看到:
干得漂亮!如今能够干活了。
NPM Scripts
把下面的npm脚本添加到你的package.json文件中可让你的工做更快,laravel安装的时候已经包含了这个东西了
"scripts": { "dev": "cross-env NODE_ENV=development webpack --progress --hide-modules", "watch": "cross-env NODE_ENV=development webpack --watch --progress --hide-modules", "hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot", "production": "cross-env NODE_ENV=production webpack --progress --hide-modules" }
咱们先回顾一下通用的工做流程以便你能在本身的项目上采用
1 . 安装laravel
laravel new my-app
2 . 安装Node依赖
npm install
3 . 配置webpack.mix.js
这个文件全部前端资源编译的入口
let mix = require('laravel-mix'); mix.js('resources/assets/js/app.js', 'public/js'); mix.sass('resources/assets/sass/app.scss', 'public/css');
默认会启用ES2015模块绑定,就行sass编译同样。
4 . 编译
用以下指令编译
node_modules/.bin/webpack
也可使用package.json 里的npm脚本:
npm run dev
而后会看到编译好的文件:
监视前端资源更改:
npm run watch
laravel装载了一个./resources/assets/js/components/Example.vue文件,do它,编译完成后会有一个系统通知。
5 . 修改视图
laravel自带一个欢迎页面,咱们能够用这个来作示例,修改一下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Laravel</title> <link rel="stylesheet" href="{{ mix('css/app.css') }}"> </head> <body> <div id="app"> <example></example> </div> <script src="{{ mix('js/app.js') }}"></script> </body> </html>
刷新页面,干得漂亮!
6 . 热加载
当咱们修改了已个vue组件的时候能够当即在浏览器看到他的变化而不是须要手动去刷新是很是酷的,更酷的是,刷新不会重置咱们组件的状态。HMR来拯救你了!
返回命令行,Ctrl+c强制结束webpack监视器,而后输入:
npm run hot
“hot”表示HMR(Hot module replacement),这个指令是你激活热加载惟一须要作的事情
刷新浏览器,而后修改./resources/assets/js/components/Example.vue文件,一旦你点击保存,浏览器就会立马有反应,酷不酷!
mix和elixir有哪些不一样呢?
你可能已经知道一个叫作laravel elixir的工具已经存在一段时间了(也是咱们写的), laravel mix 是它的升级版,尽管他们的API是几乎同样的,但还有少数关键的不一样你须要知道一下,若是你要替换他们的话。
1 . laravel mix 是创建在webpack的顶层,而不是Gulp
最重要的变化固然是咱们把底层实现用webpack替代了gulp,这样带来的结果是不只更健壮,更灵活,并且更简单,更可配置(你所须要的)的代码。请注意一下全部的laravel elixir插件都使用gulp,由于laravel mix 使用的是webpack,因此laravel elixir的插件在这里都不能用了,那就是为何咱们改了名字,避免你们蒙圈。另外一方面,laravel mix不须要插件,因此你能够自由的编写webpack.config.js。
2 . gulpfile.js变成webpack.mix.js
由于laravel mix 创建在webpack上,因此安装laravel的时候你并不能找到gulpfile.js,而是:
3 . webpack 不是一个一般意义上的任务构建工具 ,like gulp
对于通常的任务,gulp是很是nice的,移动文件,压缩脚本,编译js,还能版本化特定文件,然而,webpack只是一个JavaScript入口,在这里,你能够选择多种编译方式或者插件。这是一个很重要的区别。
话虽然是这么说,咱们仍是要给你介绍一些跟webpack模块无关的操做来合并多个文件,或者压缩样式表,这意味着,mix.copy(),mix.combine(),mix.minify() 仍然是能够用的
例如:在laravel elixir下,你可能会使用mix.version('./public/some/random/files.js') ,它会给文件名附加hash值。但在laravel mix下,你只须要简单的调用mix.version()就好了,工具会自动的版本化全部的关联文件。
4.更灵活
由于咱们如今使用webpack,会有一些新的功能,例如mix.extract(['vendor', 'libs']), 它会把全部指定的第三方库拆分红独立的文件,为了长期缓存。
laravel-mix必须在laravel下使用吗?
不,在laravel下使用使最好的,但也能够用在别的任何项目
个人代码没有压缩
只有在node环境变量为生产环境时才会被压缩,这样会加速编译过程,但在开发过程当中是没必要要的,下面是在生成环境下运行webpack的示例
export NODE_ENV=production && webpack --progress --hide-modules
强烈推荐你把下面的npm脚本添加到你的package.json文件中,注意laravel已经包括了这些了
"scripts": { "dev": "cross-env NODE_ENV=development webpack --progress --hide-modules", "watch": "cross-env NODE_ENV=development webpack --watch --progress --hide-modules", "hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot", "production": "cross-env NODE_ENV=production webpack --progress --hide-modules" },
我使用的是VM,webpack不能检测到个人文件变化
若是你在VM下执行 npm run dev,你会发现webpack并不能监视到你的文件改变。若是这样的话,修改一下你的npm脚本,使用--watch-poll和--watch标签,像这样:
"scripts": { "watch": "NODE_ENV=development webpack --watch --watch-poll", }
若是你仍是有问题,去这儿溜达溜达吧。
为何在个人css文件里显示图片在node_modules里找不到
你可能用的是相对路径,可是在的resources/assets/sass/app.css里并不存在:
body { background: url('../img/example.jpg'); }
当引用相对路径的时候,会根据当前文件的路径来搜索,一样的,webpack会首先搜索resources/assets/img/example.jpg,若是找不到,会继续搜索文件位置,包括node_modules,若是还找不到,就报错:
ERROR Failed to compile with 1 errors This dependency was not found in node_modules:
有两个解决办法:
1 . 让resources/assets/img/example.jpg能找获得就好了,就是把文件放这儿。
2 . 编译css的时候添加下面的选项,禁用css的url处理:
mix.sass('resources/assets/sass/app.scss', 'public/css') .options({ processCssUrls: false });
这对于一些文件This is particularly useful for legacy projects where your folder structure is already exactly as you desire.彻底符合你的要求的遗留项目是很是有用的。
我不想把mix-manifest.json文件放在项目根目录下
若是你没有使用laravel,你的mix-manifest.json文件会被放到项目根目录下,若是你不喜欢的话,能够调用mix.setPublicPath('dist/'),而后manifest文件就会被放到dist目录下。
怎样使用webpack自动加载模块
webpack 使用ProvidePlugin插件加载一些须要的模块,经常使用的一个例子就是加载jQuery:
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }); // in a module $('#item'); // <= just works jQuery('#item'); // <= just works
//$和jQuery被自动设置为‘jQuery’的出口
当laravel-mix自动加载模块的时候(像上面说的那样),你若是想禁用(传一个空对象)或者用你本身的模块覆盖它,能够调用mix.autoload()方法:
mix.autoload({ jquery: ['$', 'window.jQuery', 'jQuery'], // more than one moment: 'moment' // only one })
怎样手动添加CoffeeScript编译器
很是简单!你只须要在webpack.mix.js里调用mix.webpackConfig()方法就能够了,它会自动和mix的默认配置合并。
// npm install coffee-loader coffee-script
mix.js('resources/assets/js/app.coffee', 'public/js') .webpackConfig({ module: { rules: [ { test: /\.coffee$/, loader: 'coffee-loader' } ] } });
mix.js(src|[src], output)
简单的一行代码,larave mix能够执行不少重要的操做
用法
let mix = require('laravel-mix'); // 1. 单个文件 mix.js('src/app.js', 'dist/app.js'); // 2. 多个文件编译成一个文件 mix.js([ 'src/app.js', 'src/another.js' ], 'dist/app.js'); // 3. 编译多个文件 mix.js('src/app.js', 'dist/') .js('src/forum.js', 'dist/');
laravel 示例
考虑到典型的laravel默认安装的时候会把入口定位在 ./resources/assets/js/app.js,因此咱们先准备一个webpack.mix.js把app.js编译到 ./public/js/app.js。
let mix = require('laravel-mix'); mix.js('resources/assets/js/app.js', 'public/js');
如今上面全部的项你均可以用了,只须要调用一个方法。
在命令行调用npm run dev 执行编译。
Vue 组件
laravel mix 一应俱全,支持vue组件编译,若是你不使用vue的话,能够忽略这块。
单文件组件是vue最重要的特征。在一个文件里为一个组件定义模板,脚本,样式表。
./resources/assets/js/app.js
import Vue from 'vue'; import Notification from './components/Notification.vue'; new Vue({ el: '#app', components: { Notification } });
在上面,咱们导入了vue(首先你须要执行npm install vue --save-dev安装vue),而后引入了一个叫Notification的vue组件而且注册了root vue实例。
./resources/asset/js/components/Notification.vue
<template> <div class="notification"> {{ body }} </div> </template> <script> export default { data() { return { body: 'I am a notification.' } } } </script> <style> .notification { background: grey; } </style>
若是你了解vue,这些你都会很熟悉,继续。
./webpack.mix.js
let mix = require('laravel-mix');
mix.js('resources/assets/js/app.js', 'public/js');
执行npm run dev 编译文件,这样就简单的建立了一个HTML文件,引入./js/app.js 文件,而后在浏览器里查看吧!
React 支持
laravel mix 也装载了基本的react支持,只要把mix.js()改为mix.react()而且使用相同的参数。在底层,mix会引用react须要的任何babel插件。
mix.react('resources/assets/js/app.jsx', 'public/js/app.js');
固然,你仍然须要使用npm安装react和reactDOM,不过要注意当心行事。
mix.js(src, output) .extract(['any', 'vendor', 'library']);
把全部的js都打包成一个文件会伴随着潜在的风险:每次更新项目中就算很小的一部分都须要破坏全部用户的缓存,这意味着你的第三方库须要从新被下载和缓存。这样很很差。
一个解决的办法是分离或者提取你的库文件。
mix.extract(['vue', 'jquery']);
extract方法接受一个你想要从打包文件里提取出的库的数组,使用这个方法,Vue和jQuery的源代码都会被放在vendor.js里。若是在将来你须要对应用代码作一些微小的变更,并不会对大的vendor库产生影响,它们依然会留在长期缓存。
一旦执行webpack打包文件,你会发现三个新的文件,你能够在HTML页面引用它们。
<script src="/js/manifest.js"></script> <script src="/js/vendor.js"></script> <script src="/js/app.js"></script>
实际上,咱们付出了一些HTTP请求的代价(就是会多请求几回)来换取长期缓存的提高。
Manifest文件是什么
webpack编译的时候会有一些run-time代码协助其工做。若是没有使用mix.extract(),这些代码你是看不到的,它会在打包文件里,然而,若是咱们分离了代码而且容许长期缓存,在某些地方就须要这些run-time代码,因此,mix会把它提取出来,这样一来,vendor库和manifest文件都会被缓存很长时间。
BrowserSync能让浏览器实时的,快速的响应您的文件的更改 --彻底不须要手动刷新。你能够调用mix.browserSync()方法来开启这个功能:
mix.browserSync('my-domain.dev'); // Or: // https://browsersync.io/docs/options/ mix.browserSync({ proxy: 'my-domain.dev' })
参数能够传字符串,也能够传对象。你声明的域名做为proxy是很是重要的,Browsersync将包裹你的虚拟主机(webpack dev server)使用代理网址查看您的网站。
laravel mix对模块热替换提供了无缝的支持。
模块热替换(或者叫热加载),意思就是当javascript改变刷新页面的时候能够维持组件的状态,例如如今有一个计数器,按一下按钮,计数器会加1,想象一下你点了不少次而后修改一下组件的相关文件,浏览器会实时的反映出你所作出的更改而保持计数器不变,计数器不会被重置,这就是热加载的意义最在。
在laravel里的用法
看一下laravel里的package.json文件,在scripts模块,你能够看到:
"scripts": { "dev": "cross-env NODE_ENV=development webpack --progress --hide-modules", "watch": "cross-env NODE_ENV=development webpack --watch --progress --hide-modules", "hot": "cross-env NODE_ENV=development webpack-dev-server --inline --hot", "production": "cross-env NODE_ENV=production webpack --progress --hide-modules" }
注意一下hot指令,这个地方就是你所须要的,在命令行执行npm run hot会启动一个node服务器而且监视你的bundle文件,接下来,在浏览器打开你的laravel应用,通常应该是http://my-app.dev。
在laravel应用里使用热加载很重要的一点是要保证全部的脚本资源引用的是前面启动的node服务器的url:http://localhost:8080,如今你能够手动更新你的HTML\Blade文件了:
<body> <div id="app">...</div> <script src="http://localhost:8080/js/bundle.js"></script> </body>
假设你有一些组件,尝试在浏览器里更改他们的状态,而后更新他们的模板文件,你能够看到浏览器会马上反应出你的更新,可是状态并无被改变。
可是,在开发部署环境下手动更新url会是一个负担,因此,laravel提供了一个mix()方法,他会动态的构建js或者样式表的引用,而后输出。上面的代码所以能够修改为:
<body> <div id="app"></div> <script src="{{ mix('js/bundle.js') }}"></script> </body>
当你执行npm run hot的时候,这个方法会把http://localhost:8080设置为base url,当你运行npm run dev或者npm run pro的时候,它会使用你根目录的地址。
在spa里的用法
laravel mix包含了流行的vue-loader包,这意味着,若是是单页应用,你什么都不须要作,它是开包即用的。