安裝
npm install -g webpack // 全域性安裝
npm install --save-dev webpack //本地安裝
在完成全域性安裝和本地安裝之後,就可以開始進行webpack
的使用了。
嘗試打包
安裝完成之後,我們可以嘗試使用webpack
進行一次簡單的打包。webpack
最基本的命令就是webpack
,可以直接使用webpack
命令對檔案進行編譯,例如
webpack main.js bundle.js
上述程式碼就能將main.js
檔案打包成bundle.js
檔案。
使用配置檔案
也可以在webpack
配置檔案中設定好引數後直接執行webpack
命令進行打包。在專案根目錄下新建webpack.config.js
,webpack
會預設其為配置檔案。
module.exports = {
entry: __dirname + "/src/main.js", //設定main.js為專案入口
output: {
path: __dirname + "/public",//設定public為編譯後的目錄
filename: "bundle.js"//編譯後輸出檔案的檔名
}
}
注意:__dirname
是指專案根目錄,必須要加上,這樣在打包之後才能準確找到相應目錄。
配置好之後,在命令列中直接輸入webpack
就能得到前面的同樣的結果。
接下來也可以在package.json
檔案中配置webpack
命令的代替方式,如下
"scripts": {
"start":"webpack"
}
這樣直接輸入 npm run start
也能取得同樣的效果。
如果想要執行自定義webpack
的配置檔案的話,可以使用如下程式碼
webpack --config webpack.dev.config.js
這樣就能將配置檔案設定為webpack.dev.config.js
了。也可以在package.json
中去設定
"scripts": {
"webpack":"webpack --config webpack.dev.config.js"
}
執行 npm run webpack
,就能實現和上面程式碼一樣的功能,將配置檔案設定為webpack.dev.config.js
並執行。
配置檔案解析
在配置檔案中,entry
欄位可以分別設定為以下三種形式:
1.字串
指定這個目錄下的檔案為入口檔案
entry:'main.js' //指定main.js為入口檔案
2.陣列
存在多個入口檔案的時候,使用陣列方式可以新增多個互相不依賴的檔案
entry:['src/main.js','dist/index.js'] //兩個檔案會被打包為一個檔案
3.物件
指定多個檔案打包成多個檔案以供不同頁面使用
{
entry:{
'mainEntry':'src/main.js',
'indexEntry':'src/index.js'
},
output:{
path:'/dist',
filename:'[name].js' //執行後會打包成mainEntry.js和indexEntry兩個檔案
}
}
output
最常用的兩個屬性分別是filepath
和filename
。
其中filepath
是一個絕對路徑,指定打包生成之後的檔案存放的目錄。fliename
指定打包生成之後的檔名。
根據上述entry
欄位的敘述,我們有時候會同時指定多個入口檔案,如果只是在output.filename
中指定一個檔名,那麼會將兩個入口檔案打包到一個檔案中去。這時候我們可以使用佔位符的方式來指定output.filename
,這樣就能根據相應的入口檔案打包出相應的檔案了。
佔位符可以設定以下內容:
name
模板名稱,對應上面的mainEntry
和indexEntry
hash
整體的hash值chunkhash
分片的hash值
hash和chunkhash
為什麼會有hash
和chunkhash
值呢?其實,hash
值是在整個打包過程中每一次版本變化生成的值,這樣一來,一旦某一個資原始檔有發生變化,則整個hash
值就會發生改變,從而導致所有打包出來的檔案的檔名都會發生變化。
怎樣避免這個問題呢,那就是使用chunkhash
,chunkhash
是根據具體的模組的變化來生成的值,所以某一個檔案的變化只會影響到它自己的chunkhash
值的變化。
例如:
{
entry: {
mainEntry:__dirname + "/app/main.js",
indexEntry:__dirname + "/app/index.js"
},
output: {
path: __dirname + "/public",
filename: "[name]-[hash].js"
}
}
使用name
加hash
的方式來命名打包後的檔案,生成的結果如下
Hash: 8449fbacd884544a83ed
Version: webpack 2.5.1
Time: 57ms
Asset Size Chunks Chunk Names
mainEntry-8449fbacd884544a83ed.js 2.73 kB 0 [emitted] mainEntry
indexEntry-8449fbacd884544a83ed.js 2.71 kB 1 [emitted] indexEntry
[0] ./app/index.js 76 bytes {1} [built]
[1] ./app/main.js 84 bytes {0} [built]
兩個打包之後的檔案擁有同一個hash
值8449fbacd884544a83ed
,一旦main.js
和index.js
其中的一個檔案發生變化,則會引起整體的hash
值變化。
如果使用chunkhash
的話,如果所示:
{
entry: {
mainEntry:__dirname + "/app/main.js",
indexEntry:__dirname + "/app/index.js"
},
output: {
path: __dirname + "/public",
filename: "[name]-[chunkhash].js"
}
}
生成結果如下:
Hash: 41e84bc2e3034e423af1
Version: webpack 2.5.1
Time: 54ms
Asset Size Chunks Chunk Names
mainEntry-d4d7121b09d82bb73a8e.js 2.73 kB 0 [emitted] mainEntry
indexEntry-252220e65aed8b7f327b.js 2.71 kB 1 [emitted] indexEntry
[0] ./app/index.js 76 bytes {1} [built]
[1] ./app/main.js 84 bytes {0} [built]
同樣也會生成hash
值,但是兩個檔案的chunkhash
值是互不影響的,其中的一個檔案發生變化,則只會改變發生變化檔案打包後的檔名。
看上去好像chunkhash
能取代hash
的作用,但是我認為hash
的存在肯定有其適用的場景。比如在做靜態資源大版本管理和資料夾命名的時候就能用上,肯定還會有更多其他可能的場景。
使用plugin
在使用hash
和chunkhash
來為打包之後的檔名做版本,每次打包之後會生成新的檔名,我們無法預知每一次打包之後的檔名,所以有什麼辦法可以一次實現html檔案中對打包檔案進行引用呢?
這裡我們可以使用html-webpack-plugin
這個外掛來幫我們完成。
- 在專案目錄中對外掛進行安裝:
npm install html-webpack-plugin --save-dev
- 在配置檔案中對外掛進行引用:
var htmlWebpackPlugin = require('html-webpack-plugin')
- 使用並配置外掛引數
外掛的使用方式是直接在配置檔案中新增一個值為陣列的屬性:
plugins:[
new htmlWebpackPlugin(); //不加任何引數直接新建外掛物件是最基本使用方式
]
這樣就能在output.path
指定的目錄中生成一個新的index.html
檔案,這個index.html
檔案會將所有打包完成之後的靜態資源進行引用。由於每次重新打包之後的index.html
檔案是重新生成的,所以就解決了上面我們打包之後的靜態資原始檔名不斷變化的問題。
由於我們沒有進行任何的引數設定,所以webpack會用預設的模板打包生成一個檔案,我們也可以使用自定義模板的方式進行打包生成。
new htmlWebpackPlugin({
template:'index.html', //webpack會在根目錄下尋找index.html檔案作為模板
fliename:'main.html', //還可以自定義打包生成之後的檔名
})
這樣我們就能使用根目錄下的index.html
檔案作為模板,在output.path
下打包生成一個名為main.html
的檔案,這個檔案包含了我們打包之後的靜態資原始檔的引用。
但是我們真實專案中不同型別的靜態資源存放的目錄不一樣,這裡其實可以在filename
屬性中來指定帶目錄的檔名。
filename:__dirname+'/dist/views/index.html'
這樣我們就能將打包之後的html
檔案和js
檔案分開存放了。
另外,我們如果需要進行多頁面開發的話,可以多次建立新的htmlWebpackPlugin
物件來配置。大體模板如下:
new htmlWebpackPlugin({
template:'index.html',
fliename:'main.html',
}),
new htmlWebpackPlugin({
template:'index.html',
fliename:'side.html',
}),
...
html-webpack-plugin
外掛的其他配置引數和使用方法可以去官網檢視。
使用loader編譯ES6程式碼
通過使用loader
,webpack能實現對各種各樣的檔案進行處理。loader
需要在配置檔案中的modules
下進行配置,主要包括以下欄位:
test
一個匹配該loader所需要處理的檔案擴充名的正規表示式loader
loader的名稱include/exclude
指定要處理的資料夾/遮蔽不需要處理的資料夾query
額外選項
使用 babel
babel
需要在命令列中安裝單獨的包
npm install --save-dev babel-core babel-loader babel-preset-es2015
以上是本地安裝,需要在專案根目錄下執行。
按照上面的loader
配置方法,我們可以按照如下模板來配置babel
module:{
loaders:[{
test:/\.js$/, //以.js結尾的檔案都是babel需要處理的
loader:'babel-loader', //loader的名稱
exclude:/node_modules/, //忽略node_modules目錄下的所有檔案
},{} //多個loader用逗號分隔開
,...]
}
配置完之後在專案根目錄下建立檔案.babelrc
,並在檔案中寫入以下內容:
注:在windows系統下不能直接建立
.babelrc
檔案,可以在根目錄下開啟命令列輸入type null>.babelrc
命令建立
{ "presets": [ "es2015" ] }
完成之後執行webpack
命令,在編譯js檔案的時候就會使用babel-loader
將檔案中的ES6程式碼編譯成瀏覽器可執行的ES5程式碼。