今天要介紹的周邊配備是webpack,通常會拿來和glup、grunt比較,但他們其實可以共存,甚至webpack不只是處理build task,最主要可以處理不同模組化的方式,AMD、CommonJS或ES6 Module。Webpack就是把所有可模組化的靜態資源整合,並且管理開發流程的一套強大的工具。
在webpack中,所有東西都可以視為module(EX:js、images、css),它是一個模組整合工具/模組打包工作,它的特性如下:
它可以把所有的code整合並且分裝,分開有用到的模組,假設你的網站有好幾頁入口(entry),它可以把每頁會用到的code分別打包,也可以把不同頁面會共同使用到的code合併成common code。
在build之前,可以預先處理像SASS/LESS,或是ES6/JSX這種需要預先處理的resource,除了JS也可以整合CSS、images等其他種resource。
支援AMD、CommonJS或ES6 Module方式。
使用前需要用前面我們提到的NPM來安裝webpack:
npm install webpack -g
然後,假設我們在根目錄下有一個開發的main.js,要把它build成bundle.js,我們可以用CLI指令執行build動作,也可以使用webpack.config.js來做設定。
(1) CLI指令
webpack main.js bundle.js
(2) webpack.config.js設定
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
當使用webpack.config.js的方式,要執行build的動作,只需要在CLI執行:
webpack
若要自己取config的檔案名稱,可以加上 --config 設定:
webpack --config webpack.config.prod.js
因為webpack功能強大,後面也會介紹到loaders和plugins,所以建議使用webpack.config.js來定義設定檔。
要使用JSX+ES6撰寫React,我們可以靠babel來編譯,所以先安裝babel-loader相關的package。
npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save-dev
一口氣我們就安裝了4個babel相關package:
然後,回到webpack.config.js設定loaders:
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
}
]
}
};
Webpack允許bundle任何靜態資源,不只是Javascript,像是CSS、images、JSON等,都可以使用loader來bundle,甚至也可以使用Node.js自己寫loader。
通常可以使用下面command來安裝loaders:
npm install xxxx-loader --save-dev
而loaders的寫法,用上面例子來說明:
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
// loaders列出要使用到的loaders array
loaders: [
{
// 用正規表示法,表示babel-loader是用在.js副檔名的檔案
test: /\.js$/,
// 使用的loader,也可以只寫'babel'
loader: 'babel-loader',
// 提供給loader使用的參數,設定方式也可以寫在loader裡
// loader: 'babel-loader?presets[]=es2015,presets[]=react'
query: {
presets: ['es2015', 'react']
}
}
]
}
};
另外,也可以在loader裡面設定
Webpack可以用require的方式來加入css與圖片:
require('./bootstrap.css');
require('./myapp.less');
var img = document.createElement('img');
img.src = require('./logo.png');
當使用CSS(SASS/LESS)的時候,webpack會把style放在標籤裡面,並加到頁面上。而使用圖片時,會使用圖片路徑的URL。所以需要在loaders裡面設定,讓webpack知道用什麼loader來載入這兩種資源:
module.exports = {
entry: './main.js',
output: {
// 產生bundle.js的路徑
path: './build',
// 使用require()時,產生URL的路徑,例如:圖片的URL
publicPath: 'http://mycdn.com/',
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
},
{
// 指定只處理.less檔案
test: /\.less$/,
// 使用!把loader串接在一起,會從最右邊的loader開始compile
loader: 'style-loader!css-loader!less-loader'
},
{
// 指定只處理.css檔案
test: /\.css$/,
// 這邊少了less-loader,因為.css檔不需轉譯LESS
loader: 'style-loader!css-loader'
},
{
test: /\.(png|jpg)$/,
// query參數表示當圖片小於8192bytes,就使用inline base64 URLs
// 剩下超過大小的圖片,就顯示URL
loader: 'url-loader?limit=8192'
}
]
}
};
當然使用這幾個loader都需要npm install,以及加上--save-dev,表示寫入devDependencies。
webpack-howto
(這篇有說到更深入的Multiple entrypoints部分,值得一讀)