前言
“模組化”可以說是現在前端最流行的三個字,而webpack就是一款非常非常流行的模組打包工具,它可以分析模組之間的依賴關係,並將這些模組根據指定規則打包成瀏覽器能識別的靜態資源。
作為一個前端,學習並使用webpack已經是刻不容緩的事情,現在,就讓我們開始webpack之旅吧。
安裝webpack
首先新建一個空的資料夾,使用npm init命令初始化。
初始化的目的是為了生成package.json檔案,這是一個npm說明檔案,裡面包含了當前專案的依賴模組,自定義的指令碼任務等資訊。
//新建webpack-demo的資料夾
mkdir webpack-demo
//進入該資料夾
cd webpack-demo
// 初始化
npm init
複製程式碼
輸入npm init命令後,終端會要求你填寫一些資訊,如果你不準備在npm中釋出你的模組,直接一路回車完成初始化就行。
初始化完成後,你可以看到已經生成了一個package.json檔案,你也可以在這個檔案裡手動修改初始化的時候終端讓你輸入的資訊。
接下來就要安裝webpack,你可以全域性安裝webpack,也可以在專案目錄下安裝webpack,官方不支援全域性安裝,因為那樣會使不同webpack版本的專案搭建失敗。
// 全域性安裝
npm install -g webpack
// 安裝到指定專案目錄
npm install --save-dev webpack
複製程式碼
安裝完成後我們發現專案目錄中多了一個node_modules資料夾,我們可以檢視下webpack的版本。
// 檢視全域性安裝的webpack版本
webpack -v
// 檢視非全域性安裝的webpack版本
cd node_modules/.bin
webpack -v
複製程式碼
接下來我們開始用webpack來打包第一個檔案。
打包第一個檔案
用編輯器開啟專案,新建一個hello.js檔案。
使用webpack打包hello.js檔案,同樣,不是全域性安裝webpack的小夥伴們這時得注意路徑問題了。
// 全域性安裝webpack的情況
webpack hello.js bundle.js
// 非全域性安裝webpack的情況
cd node_modules/.bin
webpack [完整路徑]/hello.js [完整路徑]/bundle.js
複製程式碼
如圖所示,打包完成後,webpack會告訴我們一些資訊,比如打包時間、打包後檔案的大小等。
這時我們發現,如果不是全域性安裝webpack,執行webpack打包命令將變得非常麻煩,其實我們可以配合npm的指令碼來更快捷的執行打包任務。
修改package.json檔案,在scripts屬性中新增執行webpack打包的指令碼,比如build,執行npm run build hello.js bundle.js,發現打包成功。
打包好之後我們可以通過live-server啟動一個本地服務。
// 全域性安裝live-server
$ npm install -g live-server
複製程式碼
安裝好之後執行live-server,會發現它已經幫我們開啟了一個瀏覽器頁面,並且當你修改本地任何檔案時,瀏覽器都會自動更新。
現在我們已經成功打包了一個js檔案,接下來讓我們試著打包一個css檔案。
新建一個index.html檔案和style.css檔案,在樣式檔案中新增一些樣式,並在hello.js檔案裡用require的方式將其引入(require是CommonJS的語法,webpack支援CommonJS/AMD/CMD)。
這時如果我們直接打包會發現報錯了,錯誤提示我們需要一個合適的loader來處理這種css檔案型別。因此我們要先安裝兩個loader,css-loader和style-loader,前者是使webpack支援css檔案,後者則會將樣式通過style標籤插入到html中。
npm install css-loader style-loader --save-dev
複製程式碼
安裝完成後,我們還需要在檔案引用的地方指定相應的loader。
require('style-loader!css-loader!./style.css')
複製程式碼
再次執行打包命令發現打包成功,在index.html裡引入打包好的bundle.js,開啟index.html頁面發現樣式已經成功顯示。
// 檔案更新的時候自動打包
webpack {entry file} {bundled file} --watch
// 顯示檔案打包的過程
webpack {entry file} {bundled file} --progress
// 顯示所有模組
webpack {entry file} {bundled file} --display-modules
// 顯示打包模組的原因
webpack {entry file} {bundled file} --display-reasons
複製程式碼
webpack配置檔案
webpack有非常多的功能,因此我們需要有一份好的配置檔案來放置所有的打包配置資訊。
如圖所示,構建一份新的目錄,src資料夾用來放打包前的資源,dist資料夾用來放打包後的資源,webpack.config.js用來配置打包資訊,如果配置檔案不叫webpack.config.js,則打包的時候需要用--config來重新指定,比如
webpack --config webpack.config.a.js
複製程式碼
入口(Entry)和出口(Output)
入口(enrty),簡單來說,就是告訴webpack從哪裡開始。我們可以通過在webpack配置中配置entry屬性,來指定一個入口起點(或多個入口起點)。webpack會根據這個入口,來獲取模組之間的依賴關係並根據依賴關係來知道需要繫結些什麼。
出口(output),用來告訴webpack打包後檔案做何處理及存放的位置。如上圖所示,output.filename 指定了打包後的檔案的名字,output.path則指定了檔案存放的位置。
關於path獲取到的絕對路徑,我們可以新建一個js檔案輸入該路徑,並用node執行這個js檔案。
入口(Entry)
- 單個入口寫法
entry屬性的單個入口語法,是下面這種的簡寫方式:
- 物件語法
出口(Output)
- 單個入口起點
- 多個入口起點
如果在打包生成的檔名後面加上不確定的chunkhash,這時候我們需要藉助webpack的外掛html-webpack-plugin來自動生成專案中的html頁面。
// 通過npm安裝
$ npm install html-webpack-plugin --save-dev
複製程式碼
Loader
loader用於對模組的原始碼進行轉換。它可以將不同語言的檔案轉換為JavaScript,或將圖片轉換為dataURL等。
- 舉個例子babel
安裝babel:
$ npm install --save-dev babel-loader babel-core babel-preset-latest
複製程式碼
指示webpack對每個.js結尾的檔案使用babel-loader進行轉換:
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
include: path.resolve(__dirname, 'src'),
exclude: path.resolve(__dirname, 'node_modules'),
query: {
presets: ['latest']
}
}
]
}
複製程式碼
- 其他檔案型別
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
include: path.resolve(__dirname, 'src'),
exclude: path.resolve(__dirname, 'node_modules'),
query: {
presets: ['latest']
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
},
{
test: /\.(png|jpg|gif|svg)$/i,
loaders: [
'url-loader?limit=10000&name=assets/[name]-[hash:5].[ext]',
'image-webpack-loader'
]
}
]
複製程式碼