webpack安裝
yarn add webpack webpack-cli -S
mode屬性,指明打包環(huán)境
mode:'development', //打包模式 默認(rèn)兩種 production和development
開(kāi)發(fā)環(huán)境下,打包輸出的文件不會(huì)進(jìn)行壓縮;生產(chǎn)環(huán)境則會(huì)
入口entry和出口output
// entry:{ //配置多入口文件
// home:'./src/home.js',
// other:'./src/other.js'
// },
entry:'./src/index.js',
output:{
filename:'[name].[hash:8].js',
//打包后的文件名,[hash],打包后會(huì)在文件后綴添加hash戳,長(zhǎng)度為8個(gè)字節(jié)
path:path.resolve(__dirname,'dist'),
//路徑必須是一個(gè)絕對(duì)路徑,可以使用path模塊轉(zhuǎn)換成絕對(duì)路徑
// publicPath:''//打包后統(tǒng)一添加前綴域名
library:'bd',//將打包的文件執(zhí)行的即使函數(shù)賦值給bd變量
},
<script src="main.js?6628f94fe86c206b417f"></script>
<!-- 尾部hash戳,防止因?yàn)闉g覽器緩存,導(dǎo)致文件不更新-->
開(kāi)發(fā)靜態(tài)服務(wù)器的配置
安裝插件webpack-dev-server,安裝后靜態(tài)服務(wù)配置需要在devServer中配置
module.exports={
devServer:{ //開(kāi)發(fā)靜態(tài)服務(wù)配置
port:3000,
progress:true,
hot:true, //熱更新
contentBase:"./dist",
compress:true, //gzip壓縮
before(webapp){ //只想單純模擬數(shù)據(jù)數(shù)據(jù)時(shí) ,可以再before鉤子函數(shù)中寫(xiě)假數(shù)據(jù)
webapp.get('/api/user',(req,res)=>{
res.json({'name':'xxxxxxxxxx'})
})
},
// proxy:{ //請(qǐng)求代理到express服務(wù)器,解決跨域的問(wèn)題,本地服務(wù)端口必須是8080,需要開(kāi)發(fā)模式下使用
// '/api':{
// target:'http://localhost:3002',
// pathRewrite:{'/api':'/get'} //重寫(xiě)url地址,請(qǐng)求服務(wù)器提供的url地址
// }
// }
},
- 在package.json文件中配置執(zhí)行腳本命令
"scripts": {
"build": "webpack --config webpack.config.js",
"dev": "webpack-dev-server"
},
打包指令
yarn run build是webpack打包指令,如果安裝了webpack-cli,可以使用npx webpack進(jìn)行打包;--config webpack.config.js參數(shù)指明了webpack的配置文件,你的webpack配置文件名也可以是webpack.dev.js或者webpack.prod.js,通過(guò)--config xxx.js指明目標(biāo)webpack配置進(jìn)行打包開(kāi)啟靜態(tài)服務(wù)指令
yarn run dev
常用插件
//將所有js文佳中引入的樣式文件打包合并到一個(gè)文件
let MiniCssExtractPlugin = require('mini-css-extract-plugin')
//css壓縮
let OptimizeCss = require('optimize-css-assets-webpack-plugin')
//mini-css-extract-plugin壓縮css,不過(guò)該壓縮會(huì)覆蓋webpack提供的默認(rèn)設(shè)置,
//因此還需要插件uglifyjs-webpack-plugin壓縮js,需要在生產(chǎn)模式下起作用
let UglifyJsWebpackPlugin = require('uglifyjs-webpack-plugin')
//打包時(shí)清除舊的打包文件
let {CleanWebpackPlugin} = require('clean-webpack-plugin')
//拷貝其他文件夾下的文件到打包目錄
let CopyWebpackPlugin = require('copy-webpack-plugin')
//使用webpack本身的插件時(shí)
let Webpack = require('webpack')
plugins插件配置
plugins:[ //數(shù)組 ,放著所有的webpack插件,插件十個(gè)類或者構(gòu)造函數(shù)
new HtmlwebpackPlugin({
'template':'./src/index.html',//目標(biāo)模板文件
'filename':'index.html',
'minify':{
// removeAttributeQuotes:true,//刪除html可以去除掉的雙引號(hào)
// collapseWhitespace:true//折疊一行顯示
},
hash:true //每次打包生成不同的文件名解決由于緩存,文件不變的問(wèn)題
}),
new MiniCssExtractPlugin({
filename:"main.css" //規(guī)定抽離出的css文件名
}),
new Webpack.ProvidePlugin({
$:'jquery' // 使用webpack插件中的ProvidePlugin方法,將jquery以$注入到模塊中
}),
new Webpack.DefinePlugin({ //定義全局變量,將下方屬性注入到所有模塊中
"DEV":JSON.stringify('production')
}),
new CleanWebpackPlugin(), //重新打包刪除舊的打包輸出的目錄dist
// new CopyWebpackPlugin({//將目標(biāo)文件夾下的文件拷貝到dist打包目錄
// patterns:[{
// from:'fromDir',to:''
// }]
// }),
new Webpack.NamedModulesPlugin(), //打印更新的模塊路徑
new Webpack.HotModuleReplacementPlugin() //熱更新組件
],
webpack優(yōu)化項(xiàng)
optimization:{ //webpack 優(yōu)化項(xiàng) 需要在production模式下起作用
minimizer:[
new OptimizeCss(),
new UglifyJsWebpackPlugin({
cache:true,
parallel:true,
sourceMap:true
})
],
splitChunks:{ //分割代碼塊,將公共部分代碼抽離成一個(gè)文件
cacheGroups:{
common:{
chunks:'initial',
minSize:0,
minChunks:2 //引用大于等于2次才進(jìn)行抽離
},
vendor:{ //抽離出公共的模塊,依賴苦苦
priority:1,//優(yōu)先抽離
test:/node_modules/,
chunks:'initial',
minSize:0,
minChunks:2
}
}
}
}
resolve 屬性
resolve:{ //用來(lái)解析第三方包
modules:[path.resolve('node_modules')],
// 配置 Webpack 去哪些目錄下尋找第三方模塊
extensions: ['.js', 'css','.json'],
//在導(dǎo)入語(yǔ)句沒(méi)帶文件后綴時(shí),Webpack 會(huì)自動(dòng)帶上后綴后去嘗試訪問(wèn)文件是否存在
alias:{ //配置項(xiàng)通過(guò)別名來(lái)把原導(dǎo)入路徑映射成一個(gè)新的導(dǎo)入路徑。
bootstrap:'bootstrap/dist/css/bootstrap.css'
},
mainFields:['style','main']
//有一些第三方模塊會(huì)針對(duì)不同環(huán)境提供幾分代碼,對(duì)應(yīng)代碼標(biāo)識(shí)在package.json文件
//Webpack 會(huì)根據(jù)mainFields的配置去決定優(yōu)先采用那份代碼
},
loader加載器
module:{
//loader
rules:[//規(guī)則
{
test:/\.(png|jpg|gif)/,
use:{
//loader:'file-loader',//在js中引入圖片 file-loader 默認(rèn)會(huì)在出口文件內(nèi)部生成一張圖片,并返回的結(jié)果是一個(gè)新的圖片地址
loader:'url-loader', //url-loader 會(huì)把圖片地址轉(zhuǎn)為base64,不會(huì)發(fā)起網(wǎng)絡(luò)請(qǐng)求資源
options:{
limit:100,//規(guī)定小于100byte字節(jié)轉(zhuǎn)為base64
outputPath:'img/',//設(shè)置打包后突變的保存路徑
publicPath:''//打包后統(tǒng)一添加前綴域名,可用于CDN
}
}
},
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
},
include:path.resolve(__dirname,'src'),
exclude:/node_modules/
},
//style-loader 它時(shí)把css插入到head的標(biāo)簽中的
//loader 特點(diǎn):希望單一
//多個(gè)loader需要使用[]
//loader的順序,是從右向左,從下至上執(zhí)行
//loader還可以攜程對(duì)象的形式
{
test:/\.css$/,use:[
MiniCssExtractPlugin.loader,//不使用style-loader的插入css樣式,使用link標(biāo)簽引入的方式
'css-loader','postcss-loader']
},
{
test:/\.less$/,use:[
MiniCssExtractPlugin.loader,
'css-loader','postcss-loader','less-loader']
},
{
test:/\.scss$/,use:[
MiniCssExtractPlugin.loader,
'css-loader','postcss-loader','sass-loader']
},
]
},
externals屬性
externals:{ //該屬性規(guī)定發(fā)布時(shí),不對(duì)以下庫(kù)進(jìn)行打包到bundle.js中,
//發(fā)布時(shí)有些庫(kù)在html使用了cdn的方式引入庫(kù),所以不需要再將依賴代碼進(jìn)行打包
jquery:'$'
}
watch實(shí)時(shí)監(jiān)控打包
watch:true, //打開(kāi)實(shí)時(shí)監(jiān)控內(nèi)容改變
watchOptions:{ //監(jiān)控選項(xiàng)
poll:500,//一秒輪詢500次
aggregateTimeout:500, // 防抖 內(nèi)容修改結(jié)束保存后500毫秒后開(kāi)始打包
ignored:/node_modules/ //不需要進(jìn)行監(jiān)控的文件
}
webpack優(yōu)化點(diǎn)
- 打包代碼壓縮
- noParse,不去解析依賴庫(kù)
- 使用exclude和include去限制加載編譯的文件
- webpack.IgnorePlugin
- happypack 多線程打包
- import
//es6 草案中的語(yǔ)法。webpack中實(shí)現(xiàn)懶加載,jsonp原理實(shí)現(xiàn)動(dòng)態(tài)加載文件
import('./lazyloading.js').then((data)=>{
console.warn(data)
})
熱更新 devServer中配置hot:true,搭配webpack插件
- new webpack.NameModulesPlugin() 打印更新的模塊路徑
- new webpack.HotModuleReplacementPlugin() 熱更新插件
//熱更新,不用刷新瀏覽器,指定文件內(nèi)容發(fā)生改變會(huì)觸發(fā)
if(module.hot){
module.hot.accept('./lazyloading',()=>{
console.log('文件更新了!')
})
}
多個(gè)webpack文件公共部分合并
webpack-merge用來(lái)將一個(gè)webpack配置分成兩個(gè)配置文件,一個(gè)開(kāi)發(fā)環(huán)境一個(gè)生成環(huán)境
yarn add webpack-merge -D
三個(gè)配置文件:基礎(chǔ)配置:webpack.base.js;開(kāi)發(fā)環(huán)境配置:webpack.dev.js;生產(chǎn)環(huán)境配置:webpack.prod.js
//在開(kāi)發(fā)和生成配置文件中:
let {smart} = require('webpack-merge')
let base = require('./webpack.base')
module.exports = smart(base,{
mode:'development',
...
...
})
postcss-loader注意
使用postcss-loader給css屬性添加瀏覽器前綴,
第一:需要插件autoprefixer@7.x版本,
第二:如果autoprefixer是最新的,則需要在package.json中配置browserslist屬性(這個(gè)屬性配置能夠分享目標(biāo)瀏覽器和nodejs版本在不同的前端工具。這些工具能根據(jù)目標(biāo)瀏覽器自動(dòng)來(lái)進(jìn)行配置,)
package.json中配置browserslist屬性
"browserslist": [
"> 1%",
"last 4 version",
"not ie <=8"
]
在postcss.config.js配置
module.exports = {
plugins:[require('autoprefixer')]
}
或者在webpack,postcss-loader的option配置
{
test:/\.css$/,use:[
'style-loader',
'css-loader',{
loader:'postcss-loader',
options:{
plugins:[require('autoprefixer')]
}
}]
}