目錄
五夜郁、插件plugins
5.1什燕、插件概要
Plugin 是用來擴(kuò)展 Webpack 功能的,通過在構(gòu)建流程里注入鉤子實(shí)現(xiàn)竞端,它給 Webpack 帶來了很大的靈活性屎即。
插件是 webpack 的支柱功能。webpack 自身也是構(gòu)建于事富,你在 webpack 配置中用到的相同的插件系統(tǒng)之上技俐!插件目的在于解決 loader 無法實(shí)現(xiàn)的其他事。
webpack 插件是一個具有 apply 屬性的 JavaScript 對象统台。apply 屬性會被 webpack compiler 調(diào)用雕擂,并且 compiler 對象可在整個編譯生命周期訪問。
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">ConsoleLogOnBuildWebpackPlugin.js
const pluginName = 'ConsoleLogOnBuildWebpackPlugin';
class ConsoleLogOnBuildWebpackPlugin {
apply(compiler) {
compiler.hooks.run.tap(pluginName, compilation => {
console.log("webpack 構(gòu)建過程開始贱勃!");
});
}
}</pre>
](javascript:void(0); "復(fù)制代碼")
compiler hook 的 tap 方法的第一個參數(shù)井赌,應(yīng)該是駝峰式命名的插件名稱。建議為此使用一個常量贵扰,以便它可以在所有 hook 中復(fù)用仇穗。
由于插件可以帶參數(shù)/選項,你必須在 webpack 配置中戚绕,向 plugins 屬性傳入 new 實(shí)例纹坐。
根據(jù)你的 webpack 用法,這里有多種方式使用插件舞丛。
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin'); //通過 npm 安裝
const webpack = require('webpack'); //訪問內(nèi)置的插件
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /.(js|jsx)$/,
use: 'babel-loader' }
]
},
plugins: [ new webpack.optimize.UglifyJsPlugin(), new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;</pre>
[](javascript:void(0); "復(fù)制代碼")
5.1耘子、HTML Webpack Plugin(創(chuàng)建HTML插件)
該個插件的作用是用來自動生成html頁面,既可以生成單個頁面又可以生成多個頁面瓷马,并且在生成前可以給它一些的配置參數(shù)拴还,它會按照你想要的生成方式去生成頁面。
第一步:安裝
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">npm i html-webpack-plugin -D</pre>
第二步:在webpack.config.js里引入模塊
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">const HtmlWebpackPlugin=require('html-webpack-plugin');</pre>
第三步:在webpack.config.js中的plugins對象里new一個實(shí)例
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">plugins:[ new HtmlWebpackPlugin({參數(shù)})
]</pre>
結(jié)果
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js' },
plugins: [ new HtmlWebpackPlugin()
]
}</pre>
](javascript:void(0); "復(fù)制代碼")
參數(shù):
title
生成頁面的titile
元素
filename
生成的html文件的文件名欧聘。默認(rèn)index.html
片林,可以直接配置帶有子目錄
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack.config.js
...
plugins: [ new HtmlWebpackPlugin({
...
filename: 'index1.html'//可帶子目錄'html/index1.html'
})
]</pre>
](javascript:void(0); "復(fù)制代碼")
template
模版文件路徑
templateParameters
{Boolean|Object|Function}
允許覆蓋模板中使用的參數(shù)
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack.config.js
...
plugins: [ new HtmlWebpackPlugin({
...
templateParameters: {
title: 'xxxx',
favicon: './favicon/index.ico',
}
})
]</pre>
](javascript:void(0); "復(fù)制代碼")
inject
插入的script
插入的位置,四個可選值:
true
: 默認(rèn)值怀骤,script
標(biāo)簽位于html
文件的body
底部
body
: 同true
head
: script
標(biāo)簽位于html
文件的head
標(biāo)簽內(nèi)
false
: 不插入生成的js
文件费封,只是生成的html
文件
favicon
為生成的html
文件生成一個favicon
,屬性值是路徑
minify
對html
文件進(jìn)行壓縮蒋伦。屬性值是false
或者壓縮選項值弓摘。默認(rèn)false
不對html
文件進(jìn)行壓縮。
html-webpack-plugin
中集成的html-minifier
痕届,生成模板文件壓縮配置韧献,有很多配置項末患,這些配置項就是minify
的壓縮選項值。
hash
給生成的js
文件尾部添加一個hash
值锤窑。這個hash
值是本次webpack
編譯的hash
值璧针。默認(rèn)false
;
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack.config.js
...
plugins: [ new HtmlWebpackPlugin({
...
hash: true })
] //html
<script type="text/javascript" src="bundle.js?59a5ed17040d94df87fe">
//59a5ed17040d94df87fe是本次webpack編譯的hash值</pre>
](javascript:void(0); "復(fù)制代碼")
cache
Boolean
類型。只在文件被修改的時候才生成一個新文件渊啰。默認(rèn)值true
showErrors
Boolean
類型探橱。錯誤信息是否寫入html
文件。默認(rèn)true
chunks
在html
文件中引用哪些js
文件,用于多入口文件時绘证。不指定chunks時隧膏,所有文件都引用
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack.config.js
entry: {
index1: path.resolve(__dirname, './index1.js'),
index2: path.resolve(__dirname, './index2.js'),
index3: path.resolve(__dirname, './index3.js')
}
...
plugins: [ new HtmlWebpackPlugin({
...
chunks: [index1, index2]//html文件中只引入index1.js, index2.js
})
]</pre>
](javascript:void(0); "復(fù)制代碼")
excludeChunks
與chunks相反,html
文件不引用哪些js
文件
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack.config.js
entry: {
index1: path.resolve(__dirname, './index1.js'),
index2: path.resolve(__dirname, './index2.js'),
index3: path.resolve(__dirname, './index3.js')
}
...
plugins: [ new HtmlWebpackPlugin({
...
excludeChunks: [index3.js]//html文件中不引入index3.js
})
]</pre>
](javascript:void(0); "復(fù)制代碼")
chunksSortMode
控制script
標(biāo)簽的引用順序嚷那。默認(rèn)五個選項:
none
: 無序
auto
: 默認(rèn)值, 按插件內(nèi)置的排序方式
dependency
: 根據(jù)不同文件的依賴關(guān)系排序
manual
: chunks按引入的順序排序, 即屬性chunks的順序
{Function}
: 指定具體的排序規(guī)則
xhtml
Boolean
類型胞枕,默認(rèn)false
, true
時以兼容xhtml
的模式引用文件
示例:
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">plugins:[ new HtmlWebpackPlugin({
title:'Hello app', /這個值對應(yīng)html里的title/ template:'./src/template.html', //模板文件地址
filename:'test1.html', //文件名,默認(rèn)為index.html(路徑相對于output.path的值)
inject:true, //script標(biāo)簽的位置车酣,true/body為在</body>標(biāo)簽前曲稼,head為在<head>里,false表示頁面不引入js文件
hash:true, //是否為引入的js文件添加hash值
chunks:['one'], //頁面里要引入的js文件湖员,值對應(yīng)的是entry里的key。省略參數(shù)會把entry里所有文件都引入
//excludeChunks:['one'],//頁面里不能引入的js文件瑞驱,與chunks剛好相反
minify:{ //html-webpack-plugin內(nèi)部集成了html-minifier
collapseWhitespace:true, //壓縮空格
removeAttributeQuotes:true, //移除引號
removeComments:true, //移除注釋
},
}), //生成兩個文件娘摔,分別引入兩個js文件(現(xiàn)在是一個文件里引入了兩個js)
new HtmlWebpackPlugin({
title:'kaivon',
template:'./src/template.html',
hash:true,
filename:'test2.html',
chunks:['two']
})
]</pre>
](javascript:void(0); "復(fù)制代碼")
示例1:
webpack.config03.js配置文件
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack配置文件
//導(dǎo)入用于生成html的插件
const HtmlWebpackPlugin=require("html-webpack-plugin"); //依賴node中的path模塊
var path=require('path'); //定義一個默認(rèn)模塊對象
module.exports={
entry:{app01:"./src/app03.js"}, //設(shè)置輸出結(jié)果
output: { //路徑,將相對路徑轉(zhuǎn)絕對路徑
path:path.resolve(__dirname,'dist'), //文件,[name]是模塊名稱唤反,占位
filename: "[hash:8].bundle.js" },
module: {
},
plugins: [ //創(chuàng)建一個插件對象凳寺,并指定參數(shù)
new HtmlWebpackPlugin({ //指定生成的文件路徑與名稱
filename:"../app03.html", //標(biāo)題
title:"Hello App03!" })
]
};</pre>
](javascript:void(0); "復(fù)制代碼")
arc/app03.js
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">alert("Hello App03!");</pre>
打包結(jié)果:
運(yùn)行:
示例2:
webpack.config03.js配置文件
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack配置文件
//導(dǎo)入用于生成html的插件
const HtmlWebpackPlugin=require("html-webpack-plugin"); //依賴node中的path模塊
var path=require('path'); //定義一個默認(rèn)模塊對象
module.exports={
entry:{app01:"./src/app03.js"}, //設(shè)置輸出結(jié)果
output: { //路徑,將相對路徑轉(zhuǎn)絕對路徑
path:path.resolve(__dirname,'dist'), //文件,[name]是模塊名稱彤侍,占位
filename: "[hash:8].bundle.js" },
module: {
},
plugins: [ //創(chuàng)建一個插件對象肠缨,并指定參數(shù)
new HtmlWebpackPlugin({ //指定生成的文件路徑與名稱
filename:"../app03.html", //標(biāo)題
title:"Hello App03!", //指定模板
template:"./templates/tmpl03.html", //模板參數(shù),允許覆蓋templates中的參數(shù)
templateParameters:{
content:"Hello templateParameters!", //重寫title
title:"Hello App03 title!",
key:"value" },
minify:{
removeComments:true, //移除注釋
collapseWhitespace:true, //折疊空格
//更新請參數(shù)https://github.com/kangax/html-minifier#options-quick-reference
}
})
]
};</pre>
](javascript:void(0); "復(fù)制代碼")
/templates/tmpl03.html 模板文件
View Code
生成結(jié)果:
5.2盏阶、Mini-css-extract-plugin(單獨(dú)提取CSS插件)
將CSS提取為獨(dú)立的文件的插件晒奕,對每個包含css的js文件都會創(chuàng)建一個CSS文件,支持按需加載css和sourceMap
默認(rèn)情況下css是被js注入的一段style名斟,如下所示:
只能用在webpack4中脑慧,對比另一個插件 extract-text-webpack-plugin特點(diǎn):
- 異步加載
- 不重復(fù)編譯,性能更好
- 更容易使用
- 只針對CSS
目前缺失功能砰盐,HMR(熱模塊替換)闷袒。
HMR解釋
安裝:
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">npm install --save-dev mini-css-extract-plugin</pre>
使用:
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [ new MiniCssExtractPlugin({ // 類似 webpackOptions.output里面的配置 可以忽略
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: { // 這里可以指定一個 publicPath
// 默認(rèn)使用 webpackOptions.output中的publicPath
publicPath: '../' },
}, 'css-loader',
],
}
]
}
}</pre>
](javascript:void(0); "復(fù)制代碼")
高級配置:
這個插件應(yīng)該只用在 production 配置中,并且在loaders鏈中不使用 style-loader, 特別是在開發(fā)中使用HMR岩梳,因?yàn)檫@個插件暫時不支持HMR
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';
module.exports = {
plugins: [ new MiniCssExtractPlugin({
filename: devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
})
],
module: {
rules: [
{
test: /.(sa|sc|c)ss$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader',
],
}
]
}
}</pre>
](javascript:void(0); "復(fù)制代碼")
示例:
webpack.config03.js
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack配置文件
//導(dǎo)入用于生成html的插件
const HtmlWebpackPlugin=require("html-webpack-plugin"); //導(dǎo)入用于提取css的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //依賴node中的path模塊
var path=require('path'); //定義一個默認(rèn)模塊對象
module.exports={
entry:{app01:"./src/app03.js"}, //設(shè)置輸出結(jié)果
output: { //路徑囊骤,將相對路徑轉(zhuǎn)絕對路徑
path:path.resolve(_dirname,'dist'), //文件,[name]是模塊名稱晃择,占位
filename: "[hash:8].bundle.js" },
module: {
rules: [
{
test: /.scss$/,
use: [{
loader:MiniCssExtractPlugin.loader //提取css并link
}, {
loader: "css-loader" // 將 CSS 轉(zhuǎn)化成 CommonJS 模塊
}, {
loader: "sass-loader" // 將 Scss 編譯成 CSS
}]
}
]
},
plugins: [ //創(chuàng)建一個插件對象,并指定參數(shù)
new HtmlWebpackPlugin({ //指定生成的文件路徑與名稱
filename:"../app03.html", //標(biāo)題
title:"Hello App03!", //指定模板
template:"./templates/tmpl03.html", //模板參數(shù)也物,允許覆蓋templates中的參數(shù)
templateParameters:{
content:"Hello templateParameters!", //重寫title
title:"Hello App03 title!",
key:"value" },
minify:{
removeComments:true, //移除注釋
collapseWhitespace:true, //折疊空格
//更新請參數(shù)https://github.com/kangax/html-minifier#options-quick-reference
}
}), //創(chuàng)建一個用于提取css的插件對象
new MiniCssExtractPlugin({
filename:"[name][hash:10].css",
chunkFilename:"[id]" })
]
};</pre>
](javascript:void(0); "復(fù)制代碼")
src/app03.js
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">import '../css/baseScss.scss';
alert("Hello App03!");</pre>
打包生成的結(jié)果
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);"><!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Hello App03 title!</title>
<link href="dist/app01_1b7c11aa92.css" rel="stylesheet">
</head>
<body><h2>Hello templateParameters!</h2>
<script type="text/javascript" src="dist/1b7c11aa.bundle.js"></script>
</body>
</html></pre>
](javascript:void(0); "復(fù)制代碼")
運(yùn)行結(jié)果:
5.3藕各、clean-webpack-plugin(刪除或清理構(gòu)建目錄)
在用HtmlWebpackPlugin的時候時需要把dist目錄刪掉再去看生成的文件,clean-webpack-plugin這個插件就可以做這件事情
第一步:安裝
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">npm i clean-webpack-plugin --save-dev</pre>
第二步:在webpack.config.js里引入模塊
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">const CleanWebpackPlugin=require('clean-webpack-plugin');</pre>
第三步:在plugins的最前面創(chuàng)建清理對象
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">plugins:[ new CleanWebpackPlugin(['./dist']), //這個一定要放在最上面焦除,作用是先刪除dist目錄再創(chuàng)建新的dist目錄激况。里面的參數(shù)為要刪除的目錄,放在一個數(shù)組里面
...
]</pre>
在文件夾里打開dist所在的目錄膘魄,并在終端里再次執(zhí)行命令webpack后乌逐,會看到dist目錄先被刪除后又被創(chuàng)建。
關(guān)于clean-webpack-plugin插件的所有配置參數(shù)請參考:https://www.npmjs.com/package/clean-webpack-plugin
該插件有兩個參數(shù):
Paths ( 必須)
An [array] of string paths to clean
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">[ 'dist', // removes 'dist' folder
'build/.', // removes all files in 'build' folder
'web/*.js' // removes all JavaScript files in 'web' folder
]</pre>
](javascript:void(0); "復(fù)制代碼")
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">{ // Absolute path to your webpack root folder (paths appended to this)
// Default: root of your package
root: __dirname, // Write logs to console.
verbose: true, // Use boolean "true" to test/emulate delete. (will not remove files).
// Default: false - remove files
dry: false, // If true, remove files on recompile.
// Default: false
watch: false, // Instead of removing whole path recursively,
// remove all path's content with exclusion of provided immediate children.
// Good for not removing shared files from build directories.
exclude: [ 'files', 'to', 'ignore' ], // allow the plugin to clean folders outside of the webpack root.
// Default: false - don't allow clean folder outside of the webpack root
allowExternal: false
// perform clean just before files are emitted to the output dir
// Default: false
beforeEmit: false }</pre>
](javascript:void(0); "復(fù)制代碼")
示例:
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">const CleanWebpackPlugin = require('clean-webpack-plugin'); //installed via npm
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const path = require('path'); // the path(s) that should be cleaned
let pathsToClean = [ 'dist', 'build' ] // the clean options to use
let cleanOptions = {
root: '/full/webpack/root/path',
exclude: ['shared.js'],
verbose: true,
dry: false } // sample WebPack config
const webpackConfig = {
entry: './path/to/my/entry/file.js',
output: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /.(js|jsx)$/,
loader: 'babel-loader' }
]
},
plugins: [ new CleanWebpackPlugin(pathsToClean, cleanOptions), new webpack.optimize.UglifyJsPlugin(), new HtmlWebpackPlugin({template: './src/index.html'})
]
}</pre>
](javascript:void(0); "復(fù)制代碼")
示例:
webpack.config03.js
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">//webpack配置文件
//導(dǎo)入用于理清目錄的插件
const CleanWebpackPlugin=require('clean-webpack-plugin'); //導(dǎo)入用于生成html的插件
const HtmlWebpackPlugin=require("html-webpack-plugin"); //導(dǎo)入用于提取css的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); //依賴node中的path模塊
var path=require('path'); //定義一個默認(rèn)模塊對象
module.exports={
entry:{app01:"./src/app03.js"}, //設(shè)置輸出結(jié)果
output: { //路徑创葡,將相對路徑轉(zhuǎn)絕對路徑
path:path.resolve(_dirname,'dist'), //文件,[name]是模塊名稱浙踢,占位
filename: "[hash:8].bundle.js" },
module: {
rules: [
{
test: /.scss$/,
use: [{
loader:MiniCssExtractPlugin.loader //提取css并link
}, {
loader: "css-loader" // 將 CSS 轉(zhuǎn)化成 CommonJS 模塊
}, {
loader: "sass-loader" // 將 Scss 編譯成 CSS
}]
}
]
},
plugins: [ //創(chuàng)建一個清理插件,參數(shù)一為目標(biāo),如路徑灿渴,參數(shù)二為選項
new CleanWebpackPlugin(['dist'],{dry:false}), //創(chuàng)建一個插件對象洛波,并指定參數(shù)
new HtmlWebpackPlugin({ //指定生成的文件路徑與名稱
filename:"../app03.html", //標(biāo)題
title:"Hello App03!", //指定模板
template:"./templates/tmpl03.html", //模板參數(shù),允許覆蓋templates中的參數(shù)
templateParameters:{
content:"Hello templateParameters!", //重寫title
title:"Hello App03 title!",
key:"value" },
minify:{
removeComments:true, //移除注釋
collapseWhitespace:true, //折疊空格
//更新請參數(shù)https://github.com/kangax/html-minifier#options-quick-reference
}
}), //創(chuàng)建一個用于提取css的插件對象
new MiniCssExtractPlugin({
filename:"[name][hash:10].css",
chunkFilename:"[id]" })
]
};</pre>
](javascript:void(0); "復(fù)制代碼")
運(yùn)行前:
運(yùn)行后:
5.4骚露、常用plugins
5.4.1蹬挤、用于修改行為
- define-plugin:定義環(huán)境變量
-
context-replacement-plugin:修改
require
語句在尋找文件時的默認(rèn)行為。 - ignore-plugin:用于忽略部分文件棘幸。
5.4.2焰扳、用于優(yōu)化
- commons-chunk-plugin:提取公共代碼
- extract-text-webpack-plugin:提取 JavaScript 中的 CSS 代碼到單獨(dú)的文件中
- prepack-webpack-plugin:通過 Facebook 的 Prepack 優(yōu)化輸出的 JavaScript 代碼性能
- uglifyjs-webpack-plugin:通過 UglifyES 壓縮 ES6 代碼
- webpack-parallel-uglify-plugin:多進(jìn)程執(zhí)行 UglifyJS 代碼壓縮,提升構(gòu)建速度误续。
- imagemin-webpack-plugin:壓縮圖片文件吨悍。
- webpack-spritesmith:用插件制作雪碧圖。
- ModuleConcatenationPlugin:開啟 Webpack Scope Hoisting 功能
- dll-plugin:借鑒 DDL 的思想大幅度提升構(gòu)建速度
- hot-module-replacement-plugin:開啟模塊熱替換功能蹋嵌。
5.4.3育瓜、其它
- serviceworker-webpack-plugin:給網(wǎng)頁應(yīng)用增加離線緩存功能
- stylelint-webpack-plugin:集成 stylelint 到項目中
- i18n-webpack-plugin:給你的網(wǎng)頁支持國際化。
- provide-plugin:從環(huán)境中提供的全局變量中加載模塊栽烂,而不用導(dǎo)入對應(yīng)的文件躏仇。
- web-webpack-plugin:方便的為單頁應(yīng)用輸出 HTML,比 html-webpack-plugin 好用愕鼓。
六钙态、DevServer開發(fā)服務(wù)器
webpack-dev-server就是一個基于Node.js和webpack的一個簡易服務(wù)器。它在服務(wù)器端使用webpack-dev-middleware進(jìn)行webpack構(gòu)建打包菇晃;并在客戶端注入一份runtime册倒,用于接受服務(wù)器端的構(gòu)建打包后信息。
在實(shí)際開發(fā)中我們可能會需要完成如下功能:
- 提供 HTTP 服務(wù)而不是使用本地文件預(yù)覽磺送;
- 監(jiān)聽文件的變化并自動刷新網(wǎng)頁驻子,做到實(shí)時預(yù)覽灿意;
- 支持 Source Map,以方便調(diào)試崇呵。
Webpack 原生支持上述第2缤剧、3點(diǎn)內(nèi)容,再結(jié)合官方提供的開發(fā)工具 DevServer 也可以很方便地做到第1點(diǎn)域慷。 DevServer 會啟動一個 HTTP 服務(wù)器用于服務(wù)網(wǎng)頁請求荒辕,同時會幫助啟動 Webpack ,并接收 Webpack 發(fā)出的文件更變信號犹褒,通過 WebSocket 協(xié)議自動刷新網(wǎng)頁做到實(shí)時預(yù)覽抵窒。
6.1、快速開啟DevServer
安裝 DevServer:
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">npm i -D webpack-dev-server</pre>
安裝成功后在項目的根目錄下執(zhí)行webpack-dev-server 命令叠骑, DevServer 服務(wù)器就啟動了李皇,這時你會看到控制臺有一串日志輸出:
Project is running at http://localhost:8080/
webpack output is served from /
現(xiàn)在就可以直接訪問了
這意味著 DevServer 啟動的 HTTP 服務(wù)器監(jiān)聽在 http://localhost:8080/ ,DevServer 啟動后會一直駐留在后臺保持運(yùn)行宙枷,訪問這個網(wǎng)址你就能獲取項目根目錄下的 index.html掉房。
注意:
1、此時可能會提示webpack-dev-server不是內(nèi)部命令慰丛,解決辦法為在全局再次安裝一下webpack-dev-server模塊卓囚,或者在package.json里的scripts里加上"dev": "webpack-dev-server",然后執(zhí)行命令npm run dev
2璧帝、并沒有通過webpack命令生成一個dist目錄捍岳,然后在瀏覽器里輸入地址http://localhost:8080/后,頁面會正常顯示睬隶。這個原因是devServer會將webpack構(gòu)建出的文件保存到內(nèi)存里,不需要打包生成就能預(yù)覽
6.2页徐、參數(shù)設(shè)置
在webpack.config.js中可以根據(jù)需要配置dev-server滿足你更多的需求苏潜。
[](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">// webpack.config.js 配置一下 devServer
devServer: {
clientLogLevel: 'warning',
historyApiFallback: true,
hot: true,
compress: true,
host: 'localhost',
port: 8080 }</pre>
](javascript:void(0); "復(fù)制代碼")
Hot (文檔)
- 熱模塊更新作用。即修改或模塊后变勇,保存會自動更新恤左,頁面不用刷新呈現(xiàn)最新的效果。
- 這不是和 webpack.HotModuleReplacementPlugin (HMR) 這個插件不是一樣功能嗎搀绣?是的飞袋,不過請注意了,
***HMR* 這個插件是真正實(shí)現(xiàn)熱模塊更新的**
链患。而 devServer 里配置了 hot: true , webpack會自動添加 HMR 插件巧鸭。所以模塊熱更新最終還是 HMR 這個插件起的作用。
host (文檔)
- 寫主機(jī)名的麻捻。默認(rèn) localhost
port (文檔)
- 端口號纲仍。默認(rèn) 8080
historyApiFallback (文檔)
如果為 true 呀袱,頁面出錯不會彈出 404 頁面。
-
如果為 {...} , 看看一般里面有什么郑叠。
- rewrites
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">rewrites: [
[
{ from: /^/subpage/, to: '/views/subpage.html' },
{
from: /^/helloWorld/.*$/,
to: function() { return '/views/hello_world.html;
}
}
]
// 從代碼可以看出 url 匹配正則夜赵,匹配成功就到某個頁面。
// 并不建議將路由寫在這乡革,一般 historyApiFallback: true 就行了寇僧。</pre>](javascript:void(0); "復(fù)制代碼")
- verbose:如果 true ,則激活日志記錄沸版。
-
disableDotRule: 禁止 url 帶小數(shù)點(diǎn)
.
嘁傀。
compress (文檔)
- 如果為 true ,開啟虛擬服務(wù)器時推穷,為你的代碼進(jìn)行壓縮心包。加快開發(fā)流程和優(yōu)化的作用。
contentBase (文檔)
你要提供哪里的內(nèi)容給虛擬服務(wù)器用馒铃。這里最好填 絕對路徑蟹腾。
默認(rèn)情況下,它將使用您當(dāng)前的工作目錄來提供內(nèi)容区宇。
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">// 單目錄
contentBase: path.join(__dirname, "public") // 多目錄
contentBase: [path.join(__dirname, "public"), path.join(__dirname, "assets")]</pre>
](javascript:void(0); "復(fù)制代碼")
Open (文檔)
- true妇智,則自動打開瀏覽器。
overlay (文檔)
- 如果為 true 锣光,在瀏覽器上全屏顯示編譯的errors或warnings憋活。默認(rèn) false (關(guān)閉)
- 如果你只想看 error ,不想看 warning卧晓。
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">overlay:{
errors:true芬首,
warnings:false }</pre>
quiet (文檔)
- true,則終端輸出的只有初始啟動信息逼裆。 webpack 的警告和錯誤是不輸出到終端的郁稍。
publicPath (文檔)
- 配置了 publicPath后,
*url* = '主機(jī)名' + '*publicPath*配置的' + '原來的*url.path*'
胜宇。這個其實(shí)與 output.publicPath 用法大同小異耀怜。 - output.publicPath 是作用于 js, css, img 。而 devServer.publicPath 則作用于請求路徑上的桐愉。
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">// devServer.publicPath
publicPath: "/assets/"
// 原本路徑 --> 變換后的路徑
http://localhost:8080/app.js --> http://localhost:8080/assets/app.js</pre>
](javascript:void(0); "復(fù)制代碼")
proxy (文檔)
- 當(dāng)您有一個單獨(dú)的API后端開發(fā)服務(wù)器财破,并且想要在同一個域上發(fā)送API請求時,則代理這些 url 从诲∽罅。看例子好理解。
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);"> proxy: { '/proxy': {
target: 'http://your_api_server.com',
changeOrigin: true,
pathRewrite: { '^/proxy': '' }
}</pre>
](javascript:void(0); "復(fù)制代碼")
- 假設(shè)你主機(jī)名為 localhost:8080 , 請求 API 的 url 是 http://your_api_server.com/user/list
-
'/proxy':如果點(diǎn)擊某個按鈕,觸發(fā)請求 API 事件抖锥,這時請求 url 是
http://localhost:8080**/proxy**/user/list
亿眠。 -
changeOrigin:如果 true ,那么
http://localhost:8080/proxy/user/list 變?yōu)?http://your_api_server.com/proxy/user/list
磅废。但還不是我們要的 url 纳像。 -
pathRewrite:重寫路徑。匹配 /proxy 拯勉,然后變?yōu)?code>'' 竟趾,那么 url 最終為
http://your_api_server.com/user/list
。
watchOptions (文檔)
- 一組自定義的監(jiān)聽模式宫峦,用來監(jiān)聽文件是否被改動過岔帽。
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">watchOptions: {
aggregateTimeout: 300,
poll: 1000,
ignored: /node_modules/ }</pre>
](javascript:void(0); "復(fù)制代碼")
- aggregateTimeout:一旦第一個文件改變导绷,在重建之前添加一個延遲犀勒。填以毫秒為單位的數(shù)字。
- ignored:觀察許多文件系統(tǒng)會導(dǎo)致大量的CPU或內(nèi)存使用量妥曲〖址眩可以排除一個巨大的文件夾。
-
poll:填以毫秒為單位的數(shù)字檐盟。每隔(你設(shè)定的)多少時間查一下有沒有文件改動過褂萧。不想啟用也可以填
false
。
](javascript:void(0); "復(fù)制代碼")
<pre style="margin: 0px; padding: 0px; font-family: "microsoft yahei" !important; white-space: pre-wrap; overflow-wrap: break-word; font-size: 16px !important; background: rgb(255, 255, 255);">var path = require("path"); var webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode:"development",
entry:{
app:"./src/js/main.js" },
output:{
filename: "bundle.js",
path:path.resolve(__dirname,"../dist"), //path.resolve是nodejs里的方法葵萎,具體看nodejs api
},
devServer:{
contentBase:false, //我這里沒有設(shè)置contentBase导犹,contentBase必須指向存在的bundle.js文件所在目錄,
//因?yàn)檫@里是開發(fā)模式羡忘,所以dist目錄并不存在谎痢,所以用false.
host:'localhost',
port:'8888',
inline:true,//webpack官方推薦
watchOptions: {
aggregateTimeout: 2000,//瀏覽器延遲多少秒更新
poll: 1000//每秒檢查一次變動
},
compress:true,//一切服務(wù)都啟用gzip 壓縮
historyApiFallback:true,//找不到頁面默認(rèn)跳index.html
hot:true,//啟動熱更新,必須搭配new webpack.HotModuleReplacementPlugin()插件
open:true,
},
plugins: [ new webpack.HotModuleReplacementPlugin(), new HtmlWebpackPlugin({
template:"index.html",
title:'index',
inject: true }), // new webpack.NamedModulesPlugin(),
// HMR shows correct file names in console on update.
// new webpack.NoEmitOnErrorsPlugin()
]
} </pre>
](javascript:void(0); "復(fù)制代碼")
示例:
配置文件:
View Code
運(yùn)行結(jié)果:
七卷雕、視頻
https://www.bilibili.com/video/av37008594/
八舶得、示例
https://git.dev.tencent.com/zhangguo5/WebPackDemo.git
九、作業(yè)
(1)爽蝴、創(chuàng)建一個項目,項目中使用ES6的模塊功能與箭頭函數(shù)纫骑,使用babel-loader轉(zhuǎn)譯成兼容IE8的前端輸出蝎亚。
本文轉(zhuǎn)載于張果大神的《10分鐘學(xué)會前端工程化webpack4.0》