日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

趁webpack5还没出,先升级成webpack4吧

發(fā)布時(shí)間:2023/12/31 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 趁webpack5还没出,先升级成webpack4吧 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

上一次將webpack1升級(jí)到3,也僅是?半年前,前端工具發(fā)展變化太快了,如今webpack4已經(jīng)灰常穩(wěn)定,傳說(shuō)性能提升非常高,值得升級(jí)。

一直用著的webpack3越來(lái)越慢,一分多鐘的編譯時(shí)間簡(jiǎn)直不能忍,升級(jí)之后在幾個(gè)系統(tǒng)和幾臺(tái)電腦上評(píng)測(cè),平均提高了7-9倍,生產(chǎn)模式的最突出

?

升級(jí)之后完整的 webpack4項(xiàng)目配置DEMO??已經(jīng)放到Github中,歡迎圍觀 star ~

關(guān)于如何升級(jí)到V4已經(jīng)有很多優(yōu)秀的文章,結(jié)合官方文檔你也可以升級(jí)起來(lái)

本文僅說(shuō)說(shuō)本次升級(jí)主要做的改動(dòng)優(yōu)化點(diǎn),或者坑

?

webpack4升級(jí)完全指南? ? webpack4 changelog? ?React 16 加載優(yōu)化性能

?

1. 移除了commonchunk插件,改用了optimization屬性進(jìn)行更加靈活的配置 ,不過(guò)稍微不注意,就會(huì)有問(wèn)題,如

Uncaught Error: only one instance of babel-polyfill is allowed

?

如果一個(gè)頁(yè)面存在多個(gè)entry入口文件,即頁(yè)面引用了多個(gè)模塊時(shí),默認(rèn)會(huì)產(chǎn)生多個(gè)獨(dú)立的common區(qū)

所以記得將common設(shè)為公有,如

optimization: {runtimeChunk: {name: 'common'},

2. 默認(rèn)的生產(chǎn)模式noEmitOnError為true,導(dǎo)致代碼檢查工具報(bào)錯(cuò)之后無(wú)法將檢查結(jié)果寫(xiě)入文件中

按需將其設(shè)置為false即可

optimization: {noEmitOnErrors: false,

3. 默認(rèn)的提取公共模塊機(jī)制可能會(huì)產(chǎn)生意外的結(jié)果,盡量取消默認(rèn)后再自定義

在多頁(yè)面應(yīng)用中,假設(shè)某個(gè)頁(yè)面的css文件重寫(xiě)了樣式,就有可能使這個(gè)重寫(xiě)流入到公共樣式中,在另一個(gè)頁(yè)面被引用而導(dǎo)致布局出錯(cuò)。這時(shí)樣式是不需要提取出來(lái)的,除非特殊情況

比如可以將default設(shè)置為false,或者表現(xiàn)得更強(qiáng)烈一點(diǎn)

optimization: {splitChunks: {chunks(chunk) {// 不需要提取公共代碼的模塊return !(configs.commonChunkExcludes || []).includes(chunk.name);},name: 'common',minChunks: 2,cacheGroups: {default: false,styles: {name: 'common',test: /\.scss|css$/,chunks: 'initial',// 不生成公共樣式文件minChunks: 999999,enforce: true}}}

4. 將css文件提取的 ExtractTextWebpackPlugin 插件?替換成?mini-css-extract-plugin

?升級(jí)指南里說(shuō)著這個(gè)新插件不兼容web-dev-server,不過(guò)目前還沒(méi)遇到,碰到的幾個(gè)坑開(kāi)始以為是它提取出的問(wèn)題,后來(lái)發(fā)現(xiàn)并不是..

5. 正確地使用?optimization.concatenateModules ,需要關(guān)閉babel的module模塊轉(zhuǎn)換

6. 看起來(lái)似乎 loader 的 exclude 和 include 配置失效了,不知道是為何

7. 加入編譯結(jié)果消息彈出提示,更友好,引入?webpack-build-notifier

長(zhǎng)長(zhǎng)的編譯結(jié)果,看起來(lái)很乏味,開(kāi)發(fā)人員并不能知道什么時(shí)候編譯好了

new WebpackBuildNotifierPlugin({title: processEntity,suppressSuccess: false,suppressCompileStart: false,suppressWarning: false,activateTerminalOnError: true}),

? ??

在win10上看比較醒目直觀,但在win7上僅是狀態(tài)欄的氣泡彈出

不過(guò)在編譯結(jié)果的內(nèi)容提示還不夠完善,可以改進(jìn)?

?

8. webpack-dev-server的端口自動(dòng)獲取空閑端口,多webpack項(xiàng)目共存時(shí)很方便

因基本所有獲取空閑端口的npm包都是異步的,原理都是以端口開(kāi)啟服務(wù)器,如果開(kāi)啟成功則表示這個(gè)端口空閑。

但項(xiàng)目的webpack配置是直接 module.export一個(gè)配置項(xiàng)的,不是使用NodeJS API的方式,嘗試切換為這種方式時(shí)發(fā)現(xiàn)竟然與HMR不同兼容,就此作罷

嘗試尋找同步直接獲取空閑端口的辦法,想出了一個(gè)簡(jiǎn)單的,直接執(zhí)行 netstat -an 命令列出當(dāng)前進(jìn)程端口再正則匹配即可,奈思~

1 let execSync = require('child_process').execSync, 2 // 已使用的端口 3 usedPorts = [], 4 // (初始)可使用的端口 5 freePort = 10000, 6 // 可用端口范圍 7 portStart = 10000; 8 portEnd = 30000, 9 // 查詢最大步 10 maxStep = 100000; 11 12 /** 13 * 獲取隨機(jī)端口 14 * @return {[type]} [description] 15 */ 16 function getRandomPort() { 17 return Math.floor(Math.random() * (portEnd - portStart) + portStart); 18 } 19 20 function getFreePort() { 21 console.log('Finding free port...'); 22 23 let stepIndex = 0, 24 res = '', 25 portSplitStr = ':'; 26 27 try { 28 res = execSync('netstat -an', { 29 encoding: 'utf-8' 30 }); 31 usedPorts = res.match(/\s(0.0.0.0|127.0.0.1):(\d+)\s/g); 32 33 if (!usedPorts) { 34 usedPorts = res.match(/\s(\*|127.0.0.1)\.(\d+)\s/g); 35 portSplitStr = '.'; 36 } 37 38 usedPorts = usedPorts.map(item => { 39 let port = item.split(portSplitStr); 40 port = port.slice(-1)[0]; 41 return parseInt(port.slice(0, -1), 10); 42 }); 43 44 usedPorts = [...new Set(usedPorts)]; 45 46 let portAvaliable = false; 47 while (!portAvaliable) { 48 freePort = getRandomPort(); 49 50 if (!usedPorts.includes(freePort)) { 51 portAvaliable = true; 52 console.log('Use port ' + freePort + ' for devServer\n'); 53 } 54 55 if (++stepIndex > maxStep) { 56 console.log('Cannot find free port for devServer\n'); 57 break; 58 } 59 } 60 } catch(e) { 61 console.log('Cannot find free port for devServer\n'); 62 console.log(e); 63 } 64 65 return freePort; 66 } 67 68 module.exports = getFreePort; View Code

?

9. 編譯的dos進(jìn)程窗添加標(biāo)題,多個(gè)webpack項(xiàng)目執(zhí)行時(shí),在任務(wù)欄小窗區(qū)分更方便

也比較簡(jiǎn)單,直接設(shè)置即可

process.title = `${configs.versionControl || 'branch'}--${configs.name || 'anonymous'}--[${process.env.NODE_ENV}]`,

不過(guò)在使用git bash時(shí),這樣設(shè)置是無(wú)效的

使用?node-bash-title 即可

require('node-bash-title')(`${configs.versionControl || 'branch'}--${configs.name || 'anonymous'}--[${process.env.NODE_ENV}]`);

10. 引入?dllplugin動(dòng)態(tài)鏈接庫(kù)方案,將第三方庫(kù)單獨(dú)打包,再鏈入我們的webpack項(xiàng)目中

可以參考介篇文章

新建一個(gè)webpack.dll.config.js配置文件

let path = require('path'); let webpack = require('webpack');module.exports = {entry: {// 需要預(yù)配置動(dòng)態(tài)鏈接的庫(kù) vendor: ['babel-polyfill',// 'echarts''react',// 'redux',// 'react-redux','react-dom',// 'react-router' ]},// 啟用sourceMap// devtool: 'cheap-module-source-map', output: {path: path.resolve(__dirname, './'),filename: '[name].js',library: '[name]_library_wcr'},plugins: [new webpack.DllPlugin({path: path.join(__dirname, './', '[name].manifest.json'),name: '[name]_library_wcr'})] }

執(zhí)行一次,將第三方包打包出來(lái),如果該配置文件有改動(dòng)的,也需要再次打包

使用?DllReferencePlugin 插件鏈接這個(gè)manifest清單引用

new webpack.DllReferencePlugin({manifest: require(path.join(__dirname, './dll/', 'vendor.manifest.json')),}),

使用?add-asset-html-webpack-plugin 這個(gè)插件將vendor庫(kù)插入到頁(yè)面中

需要注意的是,默認(rèn)它會(huì)將vendor插入到所有htmlWebpackPlugin設(shè)置的頁(yè)面中,所有我們需要通過(guò)files屬性定義好

如果有父頁(yè)面的,則只插入生成的父頁(yè)面中即可

// 動(dòng)態(tài)鏈接庫(kù)引用配置 if (configs.vendorDllOpen) {let addAssetHtmlPluginOption = {filepath: require.resolve('./dll/vendor.js'),includeSourcemap: false,hash: true};if (configs.vendorDllInsertFiles !== 'all') {Object.assign(addAssetHtmlPluginOption, {files: configs.vendorDllInsertFiles});}commonConfig.plugins.push(new webpack.DllReferencePlugin({manifest: require(path.join(__dirname, './dll/', 'vendor.manifest.json')),}),new AddAssetHtmlPlugin(addAssetHtmlPluginOption)); }

不過(guò)它的hash控制不能設(shè)定位數(shù),不夠優(yōu)雅

注意這里是由 htmlWebpackPlugin調(diào)用的ejs-loader 解析源頁(yè)面文件的配置生成的

<% for(var key in htmlWebpackPlugin.files.js) { %><script src="<%= htmlWebpackPlugin.files.js[key] %>"></script><% } %>

?

11. 使用?webpack-bundle-analyzer ?分析打包結(jié)果

// 打包模塊分析 if (process.argv.includes('--analysis')) {commonConfig.plugins.push(new BundleAnalyzerPlugin({analyzerMode: 'server',analyzerHost: '127.0.0.1',analyzerPort: require('./getFreePortSync')(),reportFilename: 'report.html',defaultSizes: 'parsed',openAnalyzer: true,generateStatsFile: false,statsFilename: 'stats.json',statsOptions: null,logLevel: 'info'})); }

?

?12. 引入代碼檢查工具套件,關(guān)于這部分,可移步 這里

?

?13. 將配置文件再抽取,抽出核心部分與和業(yè)務(wù)相關(guān)的多變動(dòng)的部分

形成如下結(jié)構(gòu),一般來(lái)說(shuō)只需要變動(dòng) webpack.config.js 這個(gè)配置即可

?

總結(jié)

以上是生活随笔為你收集整理的趁webpack5还没出,先升级成webpack4吧的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。