您好,登錄后才能下訂單哦!
簡(jiǎn)介
讀了《深入淺出webpack》總結(jié)一下常用的webpack的構(gòu)建優(yōu)化策略,可通過(guò)以下手段來(lái)提升項(xiàng)目構(gòu)建時(shí)的速度
更精準(zhǔn)的loader規(guī)則
將loader規(guī)則寫清楚
僅讓需要處理的文件,進(jìn)入loader處理環(huán)節(jié),如下
rules: [{ // 正則盡量準(zhǔn)確 test: /\.js$/, // 使用緩存,緩存后在文件未改變時(shí)編譯會(huì)更快(緩存查找原理見補(bǔ)充1) use: ['babel-loader?cacheDirectory'], // 指定需要處理的目錄 include: path.resolve(__dirname, 'src') // 理論上只有include就夠了,但是某些情況需要排除文件的時(shí)候可以用這個(gè),排除不需要處理文件 // exclude: [] }]
更精準(zhǔn)的查找目錄
將查找路徑設(shè)置精確
理論上我們項(xiàng)目的第三方依賴均應(yīng)在自己的工程的node_modules下,所以我們可以設(shè)置查找目錄,減少node的默認(rèn)查找(默認(rèn)查找方式見補(bǔ)充2)
module.exports = { resolve: { // 指定當(dāng)前目錄下的node_modules目錄 modules: [path.resolve(__dirname, 'node_modules')] } }
更精準(zhǔn)的擴(kuò)展名
數(shù)量更多類型的文件盡量放在前面
平時(shí)寫代碼,我們都習(xí)慣直接寫文件名,而不去寫擴(kuò)展名,那么解析則按照下面屬性進(jìn)行解析
module.exports = { extensions: ['.js', '.jsx', '.ts', '.tsx'], }
默認(rèn)值
extensions: [".js", ".json"]
使用動(dòng)態(tài)鏈接庫(kù)預(yù)編譯大模塊
使用動(dòng)態(tài)鏈接庫(kù),提前編譯大模塊
原理請(qǐng)見補(bǔ)充3
新建一個(gè)文件webpack_dll.config.js,內(nèi)容如下
const path = require('path'); const webpack = require('webpack'); // 復(fù)用的大模塊放在這里,這樣每次都不需要重新編譯了 const vendors = [ 'react', 'react-dom', 'lodash' ]; module.exports = { mode: 'development', output: { path: path.resolve(__dirname, './dist'), filename: '[name].js', library: '[name]', }, entry: { vendors, }, plugins: [ new webpack.DllPlugin({ path: path.resolve(__dirname, './dist/manifest.json'), name: '[name]', }), ], };
執(zhí)行webpack --config webpack_dll.config.js
進(jìn)行首次編譯(如果更新版本需要再次編譯)
然后在你的webpack配置文件中引入manifest.json
plugins: [ new webpack.DllReferencePlugin({ manifest: require('./dist/manifest.json') }) ],
多進(jìn)程處理文件
使用HappyPack同時(shí)處理多個(gè)loader編譯任務(wù)
為了發(fā)揮多核CPU電腦的功能,利用HappyPack將任務(wù)分發(fā)給多個(gè)子進(jìn)程并發(fā)執(zhí)行
const path = require('path'); const HappyPack = require('happypack'); // 共享5個(gè)進(jìn)程池 const happyThreadPool = HappyPack.ThreadPool({ size: 5 }); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, module: { // noParse: [/react\.production\.min\.js$/], rules: [{ test: /\.js$/, // 和下面插件id一直,happypack才可以找到 use: ['happypack/loader?id=babel'], include: path.resolve(__dirname, 'src') }] }, plugins: [ // 插件可以實(shí)例化多個(gè) new HappyPack({ // 與上面對(duì)應(yīng) id: 'babel', // 實(shí)際要使用的loader loaders: ['babel-loader?cacheDirectory'], // 默認(rèn)開啟進(jìn)程數(shù) threads: 3, // 是否允許happyPack打印日志 verbose: true, // 共享進(jìn)程數(shù),如果你使用超過(guò)一個(gè)happyplugin,官方建議共享進(jìn)程池 threadPool: happyThreadPool }) ], };
原理見補(bǔ)充4
多進(jìn)程壓縮文件
使用ParallelUglifyPlugin多進(jìn)程同時(shí)壓縮文件
ParallelUglifyPlugin是在UglifyJS基礎(chǔ)上,增加了多進(jìn)出處理的能力,加快了壓縮速度
import ParallelUglifyPlugin from 'webpack-parallel-uglify-plugin'; module.exports = { plugins: [ new ParallelUglifyPlugin({ test, include, exclude, cacheDir, workerCount, sourceMap, uglifyJS: { }, uglifyES: { } }), ], };
減少監(jiān)聽文件
減少監(jiān)聽文件
原理見補(bǔ)充5
當(dāng)我們使用webpack的watch功能進(jìn)行文件監(jiān)聽時(shí),更好的方式是控制監(jiān)聽目錄,如下,排除node_modules減少對(duì)該目錄監(jiān)聽,減少編譯所需要循環(huán)的文件,提高檢查速度
module.export = { watchOptions: { ignored: /node_modules/ } }
其他沒(méi)那么重要的優(yōu)化
更精準(zhǔn)的mainFields
默認(rèn)的這個(gè)值查找方式見官網(wǎng)點(diǎn)擊此處
看了下react和lodash,只有一個(gè)main,目前來(lái)看使用es6看來(lái)還不普遍,所以這個(gè)值目前可能不太重要
module.exports = { resolve: { mainFields: ['main'] } }
第三方庫(kù)映射
為什么這個(gè)不重要,我發(fā)現(xiàn)react直接導(dǎo)出的index.js則是根據(jù)環(huán)境判斷使用哪份代碼,目測(cè)來(lái)看并不需要進(jìn)行循環(huán)依賴的處理
通過(guò)依賴,則可以直接使用打包后代碼,而不需webpack去循環(huán)依賴
resolve: { mainFields: ["main"], alias: { 'react': path.resolve(__dirname, './node_modules/react/cjs/react.production.min.js') } }
不使用inline模式的devServer
原理見補(bǔ)充6
默認(rèn)情況下,應(yīng)用程序啟用內(nèi)聯(lián)模式(inline mode)。這意味著一段處理實(shí)時(shí)重載的腳本被插入到你的包(bundle)中,并且構(gòu)建消息將會(huì)出現(xiàn)在瀏覽器控制臺(tái)。
當(dāng)使用inline模式時(shí),devServer會(huì)向每個(gè)Chunk中注入一段重載的腳本代碼,但是其實(shí)一個(gè)頁(yè)面只需要一次,所以當(dāng)Chunk過(guò)多時(shí),可以將inline設(shè)置為false
module.export = { devServer: { inline: false } }
補(bǔ)充
補(bǔ)充1-cacheDirectory原理
當(dāng)有設(shè)置cacheDirectory時(shí),指定的目錄將用來(lái)緩存loader的執(zhí)行結(jié)果。之后的 webpack 構(gòu)建,將會(huì)嘗試讀取緩存,來(lái)避免在每次執(zhí)行時(shí),可能產(chǎn)生的、高性能消耗的Babel重新編譯過(guò)程。如果設(shè)置了一個(gè)空值 (loader: 'babel-loader?cacheDirectory') 或者 true (loader: babel-loader?cacheDirectory=true),loader 將使用默認(rèn)的緩存目錄 node_modules/.cache/babel-loader,如果在任何根目錄下都沒(méi)有找到 node_modules 目錄,將會(huì)降級(jí)回退到操作系統(tǒng)默認(rèn)的臨時(shí)文件目錄。
補(bǔ)充2-node的默認(rèn)查找方式
補(bǔ)充3-動(dòng)態(tài)鏈接庫(kù)思想
大量項(xiàng)目中可以復(fù)用的模塊只需要被編譯一次,在之后的構(gòu)建過(guò)程中被動(dòng)態(tài)鏈接庫(kù)包含的模塊將不會(huì)重新編譯,而是直接使用動(dòng)態(tài)鏈接庫(kù)中的代碼。(注:如果升級(jí)依賴的模塊版本,需要重新編譯動(dòng)態(tài)鏈接庫(kù))
補(bǔ)充4-HappyPack原理
webpack構(gòu)建中,需要大量的loader轉(zhuǎn)換操作,很耗時(shí),由于nodejs是單線程的,如果想更好利用cpu的多核能力,可以開啟多個(gè)進(jìn)程,同時(shí)對(duì)文件進(jìn)行處理;可以看到在配置文件中,我們每次將文件交給happypack-loader去處理,然后由happypack去調(diào)度來(lái)執(zhí)行文件的處理(happypack采用哪個(gè)loaders進(jìn)行處理,是通過(guò)id知道的)
補(bǔ)充5-文件監(jiān)聽原理
webpack會(huì)從入口觸發(fā),將所有的依賴項(xiàng)放到一個(gè)list里邊,然后每次修改文件內(nèi)容,回去遍歷整個(gè)list里邊的文件,看是否有編輯時(shí)間的變化,如果有的話則進(jìn)行編譯
補(bǔ)充6-自動(dòng)刷新原理
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。