/*
webpack.config.js webpack的配置文件
作用: 指示 webpack 干哪些活(當(dāng)你運(yùn)行 webpack 指令時(shí)哄啄,會(huì)加載里面的配置)
所有構(gòu)建工具都是基于nodejs平臺(tái)運(yùn)行的~模塊化默認(rèn)采用commonjs。
*/
// resolve用來拼接絕對路徑的方法
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') //壓縮
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
/*
緩存:
babel緩存
cacheDirectory: true
--> 讓第二次打包構(gòu)建速度更快
文件資源緩存
hash: 每次wepack構(gòu)建時(shí)會(huì)生成一個(gè)唯一的hash值纷妆。
問題: 因?yàn)閖s和css同時(shí)使用一個(gè)hash值焰雕。
如果重新打包苟鸯,會(huì)導(dǎo)致所有緩存失效袱讹。(可能我卻只改動(dòng)一個(gè)文件)
chunkhash:根據(jù)chunk生成的hash值疲扎。如果打包來源于同一個(gè)chunk,那么hash值就一樣
問題: js和css的hash值還是一樣的
因?yàn)閏ss是在js中被引入的椒丧,所以同屬于一個(gè)chunk
contenthash: 根據(jù)文件的內(nèi)容生成hash值。不同文件hash值一定不一樣
--> 讓代碼上線運(yùn)行緩存更好使用
tree shaking:去除無用代碼
前提:1. 必須使用ES6模塊化 2. 開啟production環(huán)境
作用: 減少代碼體積
在package.json中配置
"sideEffects": false 所有代碼都沒有副作用(都可以進(jìn)行tree shaking)
問題:可能會(huì)把css / @babel/polyfill (副作用)文件干掉
"sideEffects": ["*.css", "*.less"]
多進(jìn)程打包:thread-loader
*/
module.exports = {
// webpack配置
// 入口起點(diǎn)
entry: './src/index.js',
// 輸出
output: {
// 輸出文件名 [name]:取文件名
filename: 'js/[name].[contenthash:10].js',
// 輸出路徑
// __dirname nodejs的變量壶熏,代表當(dāng)前文件的目錄絕對路徑
path: resolve(__dirname, 'build')
},
// loader的配置
module: {
rules: [
// 詳細(xì)loader配置
// 不同文件必須配置不同loader處理
/*
語法檢查: eslint-loader eslint
注意:只檢查自己寫的源代碼句柠,第三方的庫是不用檢查的
設(shè)置檢查規(guī)則:
package.json中eslintConfig中設(shè)置~
"eslintConfig": {
"extends": "airbnb-base"
}
airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint
*/
{
test: /\.js$/,
exclude: /node_modules/,
// 優(yōu)先執(zhí)行
enforce: 'pre',
loader: 'eslint-loader',
options: {
// 自動(dòng)修復(fù)eslint的錯(cuò)誤
fix: true
}
},
{
// 以下loader只會(huì)匹配一個(gè)
// 注意:不能有兩個(gè)配置處理同一種類型文件
oneOf: [
{
// 匹配哪些文件
test: /\.css$/,
// 使用哪些loader進(jìn)行處理 s
use: [
// use數(shù)組中l(wèi)oader執(zhí)行順序:從右到左,從下到上 依次執(zhí)行
// 創(chuàng)建style標(biāo)簽溯职,將js中的樣式資源插入進(jìn)行帽哑,添加到head中生效
// 'style-loader',
// 這個(gè)loader取代style-loader。作用:提取js中的css成單獨(dú)文件
MiniCssExtractPlugin.loader,
// 將css文件變成commonjs模塊加載js中僻族,里面內(nèi)容是樣式字符串
'css-loader',
/*
css兼容性處理:postcss --> postcss-loader postcss-preset-env
幫postcss找到package.json中browserslist里面的配置屡谐,通過配置加載指定的css兼容性樣式
"browserslist": {
// 開發(fā)環(huán)境 --> 設(shè)置node環(huán)境變量:process.env.NODE_ENV = development
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
// 生產(chǎn)環(huán)境:默認(rèn)是看生產(chǎn)環(huán)境
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
*/
// 使用loader的默認(rèn)配置
// 'postcss-loader',
// 修改loader的配置
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
require('postcss-preset-env')()
]
}
}
]
},
{
test: /\.less$/,
use: [
// 創(chuàng)建style標(biāo)簽,將樣式放入
'style-loader',
'css-loader',
// 將less文件編譯成css文件
// 需要下載 less-loader和less
'less-loader'
]
},
{
// 問題:默認(rèn)處理不了html中img圖片
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
// 使用一個(gè)loader
// 下載 url-loader file-loader
loader: 'url-loader',
options: {
// 圖片大小小于8kb度秘,就會(huì)被base64處理
// 優(yōu)點(diǎn): 減少請求數(shù)量(減輕服務(wù)器壓力)
// 缺點(diǎn):圖片體積會(huì)更大(文件請求速度更慢)
limit: 8 * 1024,
// 問題:因?yàn)閡rl-loader默認(rèn)使用es6模塊化解析剑梳,而html-loader引入圖片是commonjs
// 解析時(shí)會(huì)出問題:[object Module]
// 解決:關(guān)閉url-loader的es6模塊化肄梨,使用commonjs解析
esModule: false,
// 給圖片進(jìn)行重命名
// [hash:10]取圖片的hash的前10位
// [ext]取文件原來擴(kuò)展名
name: '[hash:10].[ext]',
// 打包到指定文件中
outputPath: 'imgs'
}
},
{
test: /\.html$/,
// 處理html文件的img圖片(負(fù)責(zé)引入img,從而能被url-loader進(jìn)行處理)
loader: 'html-loader'
},
// 打包其他資源(除了html/js/css資源以外的資源)
{
// 排除css/js/html資源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media'
}
},
/*
js兼容性處理:babel-loader @babel/core
1. 基本js兼容性處理 --> @babel/preset-env
問題:只能轉(zhuǎn)換基本語法侨赡,如promise高級語法不能轉(zhuǎn)換
2. 全部js兼容性處理 --> @babel/polyfill
問題:我只要解決部分兼容性問題粱侣,但是將所有兼容性代碼全部引入,體積太大了~
3. 需要做兼容性處理的就做:按需加載 --> core-js
*/
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 預(yù)設(shè):指示babel做怎么樣的兼容性處理
presets: [
[
'@babel/preset-env',
{
// 按需加載
useBuiltIns: 'usage',
// 指定core-js版本
corejs: {
version: 3
},
// 指定兼容性做到哪個(gè)版本瀏覽器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
],
// 開啟babel緩存
// 第二次構(gòu)建時(shí)油猫,會(huì)讀取之前的緩存
cacheDirectory: true
}
},
]
},
]
},
// plugins的配置
plugins: [
// 詳細(xì)plugins的配置
// html-webpack-plugin
// 功能:默認(rèn)會(huì)創(chuàng)建一個(gè)空的HTML柠偶,自動(dòng)引入打包輸出的所有資源(JS/CSS)
// 需求:需要有結(jié)構(gòu)的HTML文件
new HtmlWebpackPlugin({
// 復(fù)制 './src/index.html' 文件睬关,并自動(dòng)引入打包輸出的所有資源(JS/CSS)
template: './src/index.html',
// 壓縮html代碼
minify: {
// 移除空格
collapseWhitespace: true,
// 移除注釋
removeComments: true
}
}),
new MiniCssExtractPlugin({
// 對輸出的css文件進(jìn)行重命名
filename: 'css/built.[contenthash:10].css'
}),
// 壓縮css
new OptimizeCssAssetsWebpackPlugin(),
new WorkboxWebpackPlugin.GenerateSW({
/*
1. 幫助serviceworker快速啟動(dòng)
2. 刪除舊的 serviceworker
生成一個(gè) serviceworker 配置文件~
*/
clientsClaim: true,
skipWaiting: true
})
],
/*
1. 可以將node_modules中代碼單獨(dú)打包一個(gè)chunk最終輸出
2. 自動(dòng)分析多入口chunk中电爹,有沒有公共的文件料睛。如果有會(huì)打包成單獨(dú)一個(gè)chunk
*/
optimization: {
splitChunks: {
chunks: 'all'
// 默認(rèn)值,可以不寫~
/* minSize: 30 * 1024, // 分割的chunk最小為30kb
maxSiza: 0, // 最大沒有限制
minChunks: 1, // 要提取的chunk最少被引用1次
maxAsyncRequests: 5, // 按需加載時(shí)并行加載的文件的最大數(shù)量
maxInitialRequests: 3, // 入口js文件最大并行請求數(shù)量
automaticNameDelimiter: '~', // 名稱連接符
name: true, // 可以使用命名規(guī)則
cacheGroups: {
// 分割chunk的組
// node_modules文件會(huì)被打包到 vendors 組的chunk中屎勘。--> vendors~xxx.js
// 滿足上面的公共規(guī)則居扒,如:大小超過30kb,至少被引用一次犀概。
vendors: {
test: /[\\/]node_modules[\\/]/,
// 優(yōu)先級
priority: -10
},
default: {
// 要提取的chunk最少被引用2次
minChunks: 2,
// 優(yōu)先級
priority: -20,
// 如果當(dāng)前要打包的模塊夜惭,和之前已經(jīng)被提取的模塊是同一個(gè)铛绰,就會(huì)復(fù)用,而不是重新打包模塊
reuseExistingChunk: true
}
}*/
},
// 將當(dāng)前模塊的記錄其他模塊的hash單獨(dú)打包為一個(gè)文件 runtime
// 解決:修改a文件導(dǎo)致b文件的contenthash變化
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
},
minimizer: [
// 配置生產(chǎn)環(huán)境的壓縮方案:js和css
new TerserWebpackPlugin({
// 開啟緩存
cache: true,
// 開啟多進(jìn)程打包
parallel: true,
// 啟動(dòng)source-map
sourceMap: true
})
]
},
externals: {
// 拒絕jQuery被打包進(jìn)來 但是一定要在html中引用cdn 不然會(huì)報(bào)錯(cuò)
// 參考文檔 http://events.jianshu.io/p/aaa01bb7fa78
jquery: 'jQuery'
},
// 解析模塊的規(guī)則
resolve: {
// 配置解析模塊路徑別名: 優(yōu)點(diǎn)簡寫路徑 缺點(diǎn)路徑?jīng)]有提示
alias: {
$css: resolve(__dirname, 'src/css')
},
// 配置省略文件路徑的后綴名
extensions: ['.js', '.json', '.jsx', '.css'],
// 告訴 webpack 解析模塊是去找哪個(gè)目錄
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
},
// 模式
mode: 'development', // 開發(fā)模式
// mode: 'production'
// 開發(fā)服務(wù)器 devServer:用來自動(dòng)化(自動(dòng)編譯,自動(dòng)打開瀏覽器这嚣,自動(dòng)刷 新瀏覽器~~)
// 特點(diǎn):只會(huì)在內(nèi)存中編譯打包,不會(huì)有任何輸出
// 啟動(dòng)devServer指令為:npx webpack-dev-server
devServer: {
// 運(yùn)行代碼的目錄
contentBase: resolve(__dirname, 'build'),
// 監(jiān)視 contentBase 目錄下的所有文件吏垮,一旦文件變化就會(huì) reload
watchContentBase: true,
watchOptions: {
// 忽略文件
ignored: /node_modules/
},
// 啟動(dòng)gzip壓縮
compress: true,
// 端口號(hào)
port: 5000,
// 域名
host: 'localhost',
// 自動(dòng)打開瀏覽器
open: true,
// 開啟HMR功能
hot: true,
// 不要顯示啟動(dòng)服務(wù)器日志信息
clientLogLevel: 'none',
// 除了一些基本啟動(dòng)信息以外罐旗,其他內(nèi)容都不要顯示
quiet: true,
// 如果出錯(cuò)了九秀,不要全屏提示~
overlay: false,
// 服務(wù)器代理 --> 解決開發(fā)環(huán)境跨域問題
proxy: {
// 一旦devServer(5000)服務(wù)器接受到 /api/xxx 的請求,就會(huì)把請求轉(zhuǎn)發(fā)到另外一個(gè)服務(wù)器(3000)
'/api': {
target: 'http://localhost:3000',
// 發(fā)送請求時(shí)鼓蜒,請求路徑重寫:將 /api/xxx --> /xxx (去掉/api)
pathRewrite: {
'^/api': ''
}
}
}
},
}
/*
去入口文件 添加
1. eslint不認(rèn)識(shí) window、navigator全局變量
解決:需要修改package.json中eslintConfig配置
"env": {
"browser": true // 支持瀏覽器端全局變量
}
2. sw代碼必須運(yùn)行在服務(wù)器上
--> nodejs
-->
npm i serve -g
serve -s build 啟動(dòng)服務(wù)器娇豫,將build目錄下所有資源作為靜態(tài)資源暴露出去
*/
// 注冊serviceWorker
// 處理兼容性問題
// if ('serviceWorker' in navigator) {
// window.addEventListener('load', () => {
// navigator.serviceWorker
// .register('/service-worker.js')
// .then(() => {
// console.log('sw注冊成功了~');
// })
// .catch(() => {
// console.log('sw注冊失敗了~');
// });
// });
// }
webpack.config.js 詳解
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門鸟辅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人匪凉,你說我怎么就攤上這事再层。” “怎么了树绩?”我有些...
- 文/不壞的土叔 我叫張陵饺饭,是天一觀的道長。 經(jīng)常有香客問我瘫俊,道長悴灵,這世上最難降的妖魔是什么骂蓖? 我笑而不...
- 正文 為了忘掉前任登下,我火速辦了婚禮,結(jié)果婚禮上被芳,老公的妹妹穿的比我還像新娘畔濒。我一直安慰自己,他們只是感情好侵状,可當(dāng)我...
- 文/花漫 我一把揭開白布趣兄。 她就那樣靜靜地躺著,像睡著了一般诽俯。 火紅的嫁衣襯著肌膚如雪承粤。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抽减!你這毒婦竟也來了橄碾?” 一聲冷哼從身側(cè)響起,我...
- 序言:老撾萬榮一對情侶失蹤偎箫,失蹤者是張志新(化名)和其女友劉穎皆串,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恶复,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡谤牡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恐疲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片套么。...
- 正文 年R本政府宣布津肛,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏芳绩。R本人自食惡果不足惜撞反,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嘹害。 院中可真熱鬧吮便,春花似錦、人聲如沸髓需。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽咧擂。三九已至,卻和暖如春云芦,著一層夾襖步出監(jiān)牢的瞬間贸桶,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長得像悉稠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子耀盗,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 1叛拷、entry 2、output 3忿薇、module----rules 4.plugins 5.resolve用于自...
- webpack.config.js里的配置署浩,不再支持 module下的loaders,需要把圖一中l(wèi)oaders改...
- // path 是NodeJS內(nèi)置的模塊炊汤,無需額外的下載弊攘,直接使用即可 var path = require('p...
- 一、項(xiàng)目介紹 項(xiàng)目目錄 index.html app.js main.js package.json webpac...
- 當(dāng)項(xiàng)目開發(fā)完氓栈,想使用服務(wù)器進(jìn)行打包測試婿着。webpack.config.js和index.html頁面要進(jìn)行一些簡單...