常用配置項——Mode
默認值是 production(什麼都不設置的情況下);可選值有:'none' | 'development' | 'production'。
- development:會將 DefinePlugin 中 process.env.NODE_ENV 的值設置為 development,為模塊和 chunk 啓用有效的名。
- production:會將 DefinePlugin 中 process.env.NODE_ENV 的值設置為 production,為模塊和 chunk 啓用確定性的混淆名稱。
- none:不使用任何默認優化選項
常用配置項——Source Map
一、如何在 Webpack 中啓用 Source Map
在 webpack.config.js 中,通過配置 devtool 選項來控制是否生成 source map 以及生成的類型:
module.exports = {
// ...
devtool: 'source-map', // 或其他值
};
二、常見的 devtool 選項及其區別
💡 實踐建議:
- 開發/測試環境:常用
eval-cheap-module-source-map(速度快 + 能定位到原始模塊)- 生產環境:
- 如果需要錯誤監控(如 Sentry),可使用
hidden-source-map或nosources-source-map
- 通過
sentry-cli將.map文件上傳到 Sentry- 用户報錯時,Sentry 利用 source map 自動還原原始錯誤位置
- 一般不直接暴露完整
source-map,以防源碼泄露
三、Source Map 的工作原理簡述
- Webpack 在打包時根據
devtool配置生成.map文件(如main.js.map) - 在輸出的 bundle 文件(轉換後的文件)末尾添加一行魔法註釋:
//# sourceMappingURL=main.js.map
- 瀏覽器 DevTools 自動加載該
.map文件,並將壓縮代碼映射回原始源碼 - 開發者可以在 DevTools 中像調試原始代碼一樣設置斷點、查看變量等
常用配置項——Babel、Browserslist、Polyfill
見之前的文章:《身為大廠前端的你,不能不知道 Babel + Polyfill!》
常用配置項——devServer
你有沒有想過一個問題,我們幹前端的,為什麼要在構建工作內嵌一個服務器(devServer)。
原因其實有這麼兩個:
- 文件變化時完成自動構建
- 啓動一個服務查看頁面展示(最最之前我們學 html 的時候也是通過 live server 啓動的一個內置服務器查看頁面)
webpack-dev-server 在編譯之後不會寫入到任何輸出文件,而是將 bundle 文件保留在內存中。
常見配置:
devServer: {
host: '0.0.0.0', // 允許外部訪問(如手機調試)
port: 3000,
open: true, // 啓動後自動打開默認瀏覽器
hot: true, // 啓用 HMR(模塊熱更新)
static: { // 指定靜態資源目錄(如 public 文件夾)
directory: path.join(__dirname, 'public'), // 靜態資源根目錄
publicPath: '/', // 訪問路徑前綴
watch: true, // 監聽變化並刷新
},
compress: true, // 是否為靜態文件開啓 gzip壓縮,默認為false
proxy: { // 一般用於開發環境反向代理避免CORS
'/api': {
target: 'http://localhost:8080',
changeOrigin: true, // 改變請求頭中的 host
pathRewrite: {
'^/api': '', // 重寫路徑,去掉 /api 前綴
},
},
},
historyApiFallback: true, // 解決SPA頁面在路由跳轉之後,進行頁面刷新時,返回404的錯誤
}
- 默認
localhost(僅本機訪問),這裏我們在實際開發中可能會遇到一個問題,就是後端同學無法通過我們項目的 ip 地址訪問,這是因為你和他的主機處於同一網段- 設為
'0.0.0.0'可局域網訪問(常用於真機調試)hot: true:支持 HMR,若失敗則 fallback 到頁面刷新hotOnly: true:僅 HMR,編譯失敗不刷新頁面(hot: true 編譯失敗會重新刷新整個頁面)
常用配置——哈希
在我們給打包的文件進行命名的時候,會使用 placeholder 佔位符,這裏詳細説説佔位符的這幾個屬性:
hash 本身是通過 MD4 的散列函數處理後,生成一個 128 位的 hash 值(32 個十六進制)
- hash 值的生成和整個項目有關係:
- 比如我們現在有兩個入口 index.js 和 main.js;
- 它們分別會輸出到不同的 bundle 文件中,並且在文件名稱中我們有使用 hash;
- 這個時候,如果修改了 index.js 文件中的內容,那麼 hash 會發生變化,兩個文件的名稱都會發生變化;
- chunkhash 可以有效的解決上面的問題,它會根據不同的入口進行借來解析來生成 hash 值:
- 比如我們修改了 index.js,那麼 main.js 的 chunkhash 是不會發生改變的;
- contenthash 表示生成的文件 hash 名稱,只和內容有關係:
- 比如我們的 index.js,引入了一個 style.css,style.css 有被抽取到一個獨立的 css 文件中;
- 這個 css 文件在命名時,如果我們使用的是 chunkhash,那麼當 index.js 文件的內容發生變化時,css 文件的命名也會發生變化;
- 這個時候我們可以使用 contenthash,不影響 css 文件名