以前學習過webpack3的知識,可是webpack4升級後仍是有不少變更的,因此此次從新整理一下webpack4的知識點,方便之後複習。css
此次學習webpack4不只僅要會配置,記住核心API,最好還要理解一下webpack更深層次的知識,好比打包原理等等,因此可能會省略一些比較基礎的內容,可是但願我能夠經過這次學習掌握webpack,更好地應對之後的工做。html
若是Node進行了版本更新,性能方面有所提高,webpack運行在node的基礎上,性能也會跟着有所提高。vue
若是更新Npm和Yarn,模塊之間遇到相互引用的狀況下,新版本的包管理工具可能會更快的幫咱們分析包依賴,作一些包的引用。node
好比咱們使用babel-loader的時候,不須要對node_modules也進行編譯。react
exclude: /node_modules/webpack
由於一般來講,node_modules裏面的js一般都被編譯過了,咱們再去從新編譯一次就會形成浪費。web
好比,咱們在打包線上代碼時,會壓縮css,就會使用optimize-css-assets-webpack-plugin這個插件,可是在開發環境中,咱們不須要壓縮css,因此在兩個配置文件中,作出不一樣的配置。npm
打包線上代碼的配置:json
在本地開發配置文件中就能夠不加這個plugin。瀏覽器
另外咱們在使用插件時,最好使用社區中驗證過,性能比較好的插件。由於有一些我的開發的插件,性能得不到保證,會對打包速度有影響。
有時候咱們引入一個文件,想配置成不寫文件後綴的引入方式,就須要用到這個配置項。
這樣webpack在引入文件時,就會去找後綴名爲js和jsx的文件。
可是若是咱們配置了不少類型的文件後綴,那麼webpack打包時每次都要重複找這個文件,對性能就會有損耗,因此咱們只把邏輯文件配置在extensions裏面。
如今咱們想引用一個文件夾下的index.js文件,有什麼方法讓webpack默認引入index.js文件呢
就能夠寫成
也能夠多加配置
就能夠寫成
可是若是配置特別多,也是會影響到weback打包速度的。
咱們在寫react和vue的時候,經常會配置alias,經過給目錄設置別名,webpack打包的時候就能找到目錄。
至關於
咱們在開發過程當中,不免引入第三方模塊(好比lodash),而每次在打包的時候,都會從新去分析每一個引入的包,分析完以後把他們打包到咱們的代碼中。其實第三方模塊引入後,一般是不會改變的,咱們能夠把他們單獨打包生成一個文件,只在第一次打包的時候分析他們,之後再打包時直接用分析的結果(實際是把第三方模塊打包成文件,經過全局變量輸出)。
咱們先在webpack.config.js目錄中(若是分環境打包,就在配置文件的目錄中),新建一個webapck.dll.js。
假設咱們此次引入了lodash這個第三方模塊,那麼要在webpack.dll.js中增長配置
而後須要在package.json中增長一個命令。
而後咱們繼續完善代碼,先安裝一個插件
cnpm install add-asset-html-webpack-plugin --save
複製代碼
而後在webpack.common.js中引入插件
而後增長使用一個插件,意思是,向html中增長一個資源,這個資源的目錄是dll下的vendor.dll.js。
而後咱們啓動npm run dev,發現這控制檯中輸入vendor,會出現一個函數,咱們第一步就達成了,如今須要讓咱們的代碼使用這個全局變量。
打開webpack.dll.js,增長以下配置。
意思是,要用DLLPlugin分析這個庫,這個庫就是咱們輸出的全局變量。
分析後會生成一個映射關係文件,咱們能夠配置文件生成的路徑
這樣打包出來就會多出一個文件。
而後在webpack.common.js中增長一個插件,幫咱們處理映射關係,而且目錄指向咱們生成的json文件,這樣他底層就會自動去全局變量中拿vendor。若是映射關係不存在,纔會去node_modules中分析代碼。
而後進行打包就能看到效果了
使用前
使用後
若是有多個映射關係文件,就要配置多份,也能夠寫成下面這種形式。
這樣node會自動分析dll目錄下有幾個文件,幫咱們自動去添加兩個插件。
經過Tree Shaking對冗餘代碼的刪除。配置SplitChunksPlugin對大文件進行拆分,拆分紅一些小文件。
ParallelUglifyPlugin能夠把對JS文件的串行壓縮變爲開啓多個子進程並行執行
首先安裝webpack-parallel-uglify-plugin
cnpm i -D webpack-parallel-uglify-plugin
複製代碼
在plugins中配置
new ParallelUglifyPlugin({
workerCount: 3, //開啓幾個子進程去併發的執行壓縮。默認是當前運行電腦的 CPU 核數減去1
uglifyJS: {
output: {
beautify: false, //不須要格式化
comments: false, //不保留註釋
},
compress: {
warnings: false, // 在UglifyJs刪除沒有用到的代碼時不輸出警告
drop_console: true, // 刪除全部的 `console` 語句,能夠兼容ie瀏覽器
collapse_vars: true, // 內嵌定義了可是隻用到一次的變量
reduce_vars: true, // 提取出出現屢次可是沒有定義成變量去引用的靜態值
}
}
})
複製代碼
HappyPack就能讓Webpack把任務分解給多個子進程去併發的執行,子進程處理完後再把結果發送給主進程。
首先安裝happypack
cnpm i happypack@next -D
複製代碼
在module中配置:
module: {
rules: [{
test: /\.js$/,
//把對.js文件的處理轉交給id爲babel的HappyPack實例
use: 'happypack/loader?id=babel',
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
}, {
//把對.css文件的處理轉交給id爲css的HappyPack實例
test: /\.css$/,
use: 'happypack/loader?id=css',
include: path.resolve(__dirname, 'src')
}]
}
複製代碼
在plugins中配置
plugins: [
//用惟一的標識符id來表明當前的HappyPack是用來處理一類特定文件
new HappyPack({
id: 'babel',
//如何處理.js文件,和rules裏的配置相同
loaders: [{
loader: 'babel-loader',
query: {
presets: [
"env", "react"
]
}
}]
}),
new HappyPack({
id: 'css',
loaders: ['style-loader', 'css-loader'],
threads: 4, //表明開啓幾個子進程去處理這一類型的文件
verbose: true //是否容許輸出日子
})
]
複製代碼
結合以前的sourceMap文章,在不一樣環境用不一樣的sourceMap打包。
在日常開發中,推薦使用cheap-module-eval-source-map,這樣報錯提示比較徹底,打包速度也比較快。
而線上代碼若是也須要map映射的話,推薦使用cheap-module-source-map,這樣報錯提示會更好一些。
除了這些方法,其實還有不少提高打包速度的方法,這須要咱們在日常不斷的積累,因此咱們在平常開發中,要善於總結,把使用到的好的方法都記錄下來,爲之後的工做打下堅實的基礎。