系列:
webpack入門——了解及使用
webpack進(jìn)階——緩存與獨(dú)立打包
文件目錄:
-- /node_modules:依賴的各種模塊
-- /src
– index.js
– print.js
– style.css
– package.json:配置npm相關(guān)設(shè)置
– webpack.config.js:配置webpack
package.json腳本(輸入npm run xxx憔购,xxx為腳本中對(duì)應(yīng)命令宫峦,將會(huì)在命令行中執(zhí)行相應(yīng)操作):
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack", // webpack打包
"watch": "webpack --watch", // webpack監(jiān)聽模式
"start": "webpack-dev-server --open" // 自動(dòng)刷新
}
webpack.config.js:
(這是一個(gè)我們已經(jīng)配置好的webpack配置js,本文中的講解都將基于該文件玫鸟,會(huì)在本文件上多多少少做一些改變以供測(cè)試导绷。)
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /.css$/,
use: ['style-loader', 'css-loader']
}
]
},
devtool: 'inline-source-map',
devServer: {
hot: true,
contentBase: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "common",
minChunks: Infinity,
}),
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Output Management'
})
]
HtmlWebpackPlugin
由webpack.config.js可知,webpack打包后生成的是若干個(gè)js文件屎飘,但是最終這些js文件都是應(yīng)用在html中的妥曲。
假如打包后的文件只有app.js贾费,那么完全可以手動(dòng)創(chuàng)建一個(gè)html,并加入<script type="text/javascript" src="app.js">檐盟,html就可以應(yīng)用該打包后的文件褂萧。
但是如果我們打包的文件不止一個(gè),或者打包后的文件包含hash值葵萎,那么每次我們都需要添加script或者說每次都需要更改文件的hash值嗎导犹?當(dāng)然可以,但是這樣很麻煩羡忘,開發(fā)效率很低锡足。
所以我們就引入了HtmlWebpackPlugin插件,這樣就可以自動(dòng)生成html模版并且自動(dòng)添加script壳坪。
plugins: [
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: "common",
minChunks: Infinity,
}),
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({ // 已添加該插件
title: 'Output Management'
})
]
現(xiàn)在我們進(jìn)行wepack打包:
生成目錄:
-- /dist
– app.js
– common.js
– print.js
– index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Output Management</title>
</head>
<body>
<script type="text/javascript" src="common.js"></script><script type="text/javascript" src="app.js"></script><script type="text/javascript" src="print.js"></script></body>
</html>
更多配置:HTML Webpack Plugin
CleanWebpackPlugin
該插件的主要作用是清除前次打包文件。
沒有hash時(shí)掰烟,這個(gè)插件體現(xiàn)不出來效果爽蝴,我我們?cè)谝陨系膚ebpack配置中做點(diǎn)小的變動(dòng):
// 給輸出文件名上加上hash
output: {
filename: '[name].[hash].js',
path: path.resolve(__dirname, 'dist')
}
// 注釋掉CleanWebpackPlugin
plugins: [
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: "common",
minChunks: Infinity,
}),
new webpack.HotModuleReplacementPlugin(),
// new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Output Management'
})
]
然后再次打包,可以看見dist文件夾中:
現(xiàn)在我們只需要hash后的文件給html使用纫骑,但是這里卻任然保留著很多上一次打包留下來的東西蝎亚。
這個(gè)時(shí)候我們把CleanWebpackPlugin取注釋,然后再次打包先馆。
可以看見上次文件夾里的垃圾都沒有了发框,只留下了現(xiàn)在需要的文件。
故CleanWebpackPlugin的效果是在打包前煤墙,刪除指定的曾經(jīng)打包的文件夾梅惯,然再新建并把最新打包好的內(nèi)容放在dist文件夾里。
參數(shù)為文件夾字符串?dāng)?shù)組仿野,更多配置:Clean Webpack Plugin
webpack-dev-server
webpack有一個(gè)功能叫做監(jiān)聽铣减,使用方法:命令行中輸入 webpack --watch。
這樣啟動(dòng)webpack之后脚作,每當(dāng)我們?cè)谠次募邪l(fā)生了改變葫哗,都會(huì)進(jìn)行重新打包,這樣提高了生產(chǎn)效率球涛,雖然重新打包了劣针,但是我們必須刷新頁(yè)面才能看見更變。
這樣是不友好的亿扁,如果能夠自己刷新頁(yè)面那就極好了捺典,這也就是webpack-dev-server的作用,啟動(dòng)一個(gè)小型server達(dá)到實(shí)時(shí)刷新的效果魏烫。
使用方法:
sudo npm install webpack-dev-server --save-dev
## 然后啟動(dòng)的時(shí)候辣苏,就
webpack-dev-server --open
## 運(yùn)行參數(shù)可以用以下查看
webpack-dev-server -help
## 常用的有 編譯刷新的時(shí)候出現(xiàn)顏色和進(jìn)程條
webpack-dev-server --progress --colors
我們將該腳本寫入了package.json中肝箱,可以快捷啟動(dòng) npm run start。
Hot Module Replace
熱替換常常和webpack-dev-server同時(shí)使用稀蟋,所謂熱替換(HMR: Hot Module Replace)描述的是運(yùn)行中的一個(gè)系統(tǒng)煌张,我要更換其中部分內(nèi)容,而仍然要保持不替換的內(nèi)容繼續(xù)工作退客,并在替換后骏融,替換部分能夠立即生效。
可能到這里大家還不是很明白熱替換的具體作用萌狂,簡(jiǎn)單來說就是部分刷新档玻。
假如我們僅僅只使用webpack-dev-server,然后在index.js 引入了 style.css茫藏。 那么我們修改一下style.css的樣式误趴,webpack-dev-server會(huì)監(jiān)聽到源文件發(fā)生了變化,然后重新進(jìn)行webpack打包务傲,然后再刷新頁(yè)面凉当,可能到這里已經(jīng)滿足了很多人的需求。但是我現(xiàn)在有了一個(gè)新的需求售葡,我頁(yè)面上有一個(gè)input看杭,我在input中輸入了一系列文字,現(xiàn)在我希望挟伙,我更改了樣式楼雹,input中的文字仍然保持不變,只有修改的樣式發(fā)生改變尖阔。我們知道webpack-dev-server在源文件發(fā)生改變后贮缅,會(huì)刷新整個(gè)頁(yè)面,一旦刷新的整個(gè)頁(yè)面介却,那么input中的文字必當(dāng)消失携悯。 這個(gè)時(shí)候就是體現(xiàn)熱替換強(qiáng)大功能的時(shí)候了,使用了熱替換筷笨,就可以僅僅只更改樣式而保持input中的值不發(fā)生改變憔鬼。
使用方法:
- 在命令行中直接使用:
webpack-dev-server --hot
- 將啟動(dòng)配置寫入webpack.config.js中,首先在插件數(shù)組中添加該插件:
plugins: [
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: "common",
minChunks: Infinity,
}),
new webpack.HotModuleReplacementPlugin(), // 在實(shí)例webpack.config.js中已添加
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Output Management'
})
]
這之后我們將進(jìn)行webpack-dev-server的配置胃夏,
devServer: {
hot: true, // hot為true則代表啟動(dòng)了熱替換服務(wù)
contentBase: path.resolve(__dirname, 'dist'),
publicPath: '/'
},
進(jìn)行配置之后轴或,我們直接啟動(dòng)npm run start腳本既可(webpack-dev-server --open)。
由本例我們知道了devServer是關(guān)于webpack-dev-server的配置仰禀,我們來看看常用參數(shù):
- port:8080(Number照雁,訪問端口),從localhost:8080訪問服務(wù)器
- hot:是否開啟熱替換模式
- contentBase:簡(jiǎn)單來說就是提供靜態(tài)資源文件的目錄,如果我們沒有使用HtmlWebpackPlugin的饺蚊,而是手動(dòng)的添加了index.html萍诱,那么這個(gè)時(shí)候index.html在哪個(gè)目錄下,contentBase就需要寫哪個(gè)目錄污呼。這里一定要寫絕對(duì)路徑裕坊。因?yàn)檫@個(gè)路徑是基于本機(jī)的,如果寫相對(duì)路徑則是相對(duì)于本機(jī)的根路徑的燕酷。
- publicPath:開發(fā)模式中籍凝,打包的文件在該目錄下,而不是在output中制定的文件夾下苗缩。并且路徑是相對(duì)于當(dāng)前目錄的饵蒂,以'/'開頭。例如:publicPath: '/public/'酱讶,則應(yīng)該通localhost:8080/public/來訪問打包的文件退盯,例如我要訪問common.js,那么就是localhost:8080/public/common.js泻肯。使用該路徑時(shí)得问,通常都不會(huì)自己手寫index.html,這樣會(huì)造成訪問混亂软免,直接使用HtmlWebpackPlugin生成HTML。
更多配置:Webpack Dev Server
source map
首先我們先在本例的webpack配置上做出一些修改:
// devtool: 'inline-source-map' // 注釋掉source-map
之后我們運(yùn)行npm run start焚挠,這個(gè)時(shí)候我們的項(xiàng)目應(yīng)該正常進(jìn)入了開發(fā)模式中膏萧。進(jìn)入print.js文件:
import _ from 'lodash';
export default function printMe() {
console.log(_.join(['qq', 'bb'], ' '));
}
這個(gè)時(shí)候我們把console改成consol然后保存,在頁(yè)面上觸發(fā)這個(gè)printMe函數(shù)蝌衔,發(fā)現(xiàn)控制臺(tái)上:
我們知道錯(cuò)誤明明出現(xiàn)在print.js中榛泛,但是由于是app.js引用了print.js,所以報(bào)錯(cuò)還是在app.js上噩斟,這樣以后我們出現(xiàn)了錯(cuò)誤很難定位出錯(cuò)的位置曹锨,導(dǎo)致難以調(diào)試,現(xiàn)在我們吧
// devtool: 'inline-source-map'
解注剃允,然后重新執(zhí)行npm run start沛简。再次觸發(fā)printMe這個(gè)函數(shù):
然后我們可以看見,清楚的定位了出錯(cuò)的是在print.js第四行斥废,這就是source map的作用椒楣,用于錯(cuò)誤定位。但是在生產(chǎn)環(huán)境中牡肉,我們一般都是經(jīng)過調(diào)試好的文件捧灰,所以在生產(chǎn)環(huán)境中不需要這個(gè)source map。
相關(guān)信息查看:開發(fā)輔助調(diào)試工具(Devtool)
參考資料:
開發(fā)中 Server
Webpack dev server
webpack-dev-server 使用總結(jié)
Webpack使用教程三(webpack-dev-server)
本文將持續(xù)更新统锤。毛俏。炭庙。。