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包,這意味着,若是是單頁應用,你什麼都不須要作,它是開包即用的。