Webpack3.X升級到4.X多頁面實戰和構建優化

Webpack4.x出來也有一段時間了,網上已經有不少關於Webpack4.x原理和新特性的介紹,好比零配置等,這邊就不重複了。css

最近將以前基於Webpack3.x寫的一個多頁面項目升級到4.x,記錄和總結Webpack3.x升級到4.x遇到的問題以及解決方案。html

項目預覽gif:vue

在線查看: webpack.czero.cn

區分3.x和4.x不一樣以外,也對Webpack進行了構建優化,並分別配置了Webpack3.x和Webpack4.x的基礎配置文件託管在Github,能夠用在項目中,減小配置的時間。node

Webpack3.x:github.com/czero1995/w…react

Webpack4.x:github.com/czero1995/w…jquery

項目中Webpack實現功能:

  • 多頁面入口配置
  • 使用Ejs模板實現組件化功能(共用頭部和底部)
  • 提取公共CSS文件
  • 使用HappyPack作多線程打包
  • 引入最新Babel編譯,可編譯ES7,ES8(裝飾圈@等)
  • devServer,保存自動刷新
  • 引入Less處理器
  • 配置TypeScript
  • 每次Build都先刪除掉原先Build出來的文件

區分開發環境和生產環境

開發環境: npm run dev
生產環境: npm run build
複製代碼

區分開發環境能夠提升Webpack打包效率,好比webpack

  • 開發環境中:ios

    配置調試模式devtool:cheap-source-mapgit

    配置devServer:保存自動刷新github

  • 生產環境:

    配置調試模式devtool:inline-source-map

    加載提取CSS組件

    加載PostCss插件(瀏覽器前綴,提升兼容性)

    添加每次Build時先刪除以前Build的文件

    壓縮代碼

    清空代碼註釋和空格

    加載PostCss插件

Webpack3.x和Webpack4.x的幾個明顯的區別和問題

1. 運行webpack要加參數

從4.0開始:運行webpack必定要加參數

-- mode development 或者 --mode production,

分別對應開發環境和生產環境,不然會報警告:

3.x (package.json)

"scripts": {
    "build": "webpack --optimize-minimize",
    "dev": "webpack-dev-server --config webpack.dev.config.js"
  },
複製代碼

4.x (package.json)

"scripts": {
    "build": "webpack --optimize-minimize --mode production",
    "dev": "webpack-dev-server --config webpack.dev.config.js --mode development"
  },
複製代碼

2. 移除loaders,必須使用rules

在Webpack3.x中還保留以前版本的loaders,與rules並存均可以使用,在新版中徹底移除了loaders,必須使用rules。不然會報錯,將module下面的loaders改成rules便可

3. 須要安裝webpack-cli

4.x須要安裝webpack-cli,否則運行不起來

npm install webpack-cli --save
複製代碼

4. TypeScript ts-loader版本過低

在webpack3.x中typescript使用正常,升級到webpack4.x以後就用不了typescript了,由於版本過低 修改typescript版本,個人事5.2.2,在package.json中修改ts-loader版本號,或者刪掉,從新執行 npm install ts-loader便可

5. Ejs沒法使用

Webpack結合Ejs能夠作到組件化開發,共用HTML代碼,好比多個頁面的頭部和底部,用組件引入的方式,方面後面的開發和維護。

3.x中正常使用,4.x會報ejsRenderLoder of undefined,須要修改htmlplugin的配置。 3.x爲:

template: 'ejs-render-loader!pages/index.ejs',
複製代碼

4.x爲

template: 'ejs-loader!pages/index.ejs',
複製代碼

5. text-webpack-plugin版本過低,構建失敗

在package.json中修改extract-text-webpack-plugin版本號

"extract-text-webpack-plugin": "^v4.0.0-alpha.0",
複製代碼

Webpack構建優化

區分開發環境和生產環境

  • 開發環境不須要去壓縮代碼
  • 指定調試模式devtool模式

壓縮代碼用ParalleUglifyPlugin代替自帶的UglifyJsPlugin插件

自帶的js壓縮插件是單線程執行的,而webpack-parallel-uglify-plugin能夠並行的執行 開發環境不作無心義的操做

不少配置,在開發階段是不須要去作的,咱們能夠區分出開發和線上的兩套配置,這樣在須要上線的時候再全量編譯便可,好比代碼壓縮,目錄內容清理,計算文件hash,提取css文件等

babel-loader開啓緩存

babel-loader在執行的時候,可能會產生一些運行期間重複的公共文件,形成代碼體積大多餘,同時也會減慢編譯效率

能夠加上cacheDirectory參數或使用transform-runtime插件試試

// webpack.config.js
use: [{
    loader: 'babel-loader',
    options: {
        cacheDirectory: true
    }]


// .bablerc
{
    "presets": [
        "env",
        "react"
    ],
    "plugins": ["transform-runtime"]
    
}
複製代碼

使用happypack來加速構建

happypack會採用多進程去打包構建
複製代碼

優化構建時的搜索路徑alias

使用noParse

webpack打包的時候,有時不須要解析某些模塊的加載(這些模塊並無依賴,或者並根本沒有模塊化),咱們能夠直接加上這個參數,直接跳過這種解析

module:{
noParse: /node_modules\/(jquery.js)
}
複製代碼

啓用DllPlugin和DllReferencePlugin預編譯庫文件

這是最複雜也是提高效果最明顯的一步,原理是將第三方庫文件單獨打包一次,之後的編譯都不須要在編譯打包第三方庫

拷貝靜態資源文件,引入DllPlugin和DllReferencePlugin來提早構建一些第三方庫,來優化Webpack阿寶。

而在生產環境時,就須要將提早構建好的包同步到dist中

對於commonChunkPlugin,webpack每次打包實際仍是須要去處理這些第三方庫,只是打包完以後,能把第三方庫和咱們本身的代碼分開。 而DllPlugin則是能把第三方代碼徹底分離開,即每次只打包項目自身的代碼。 在build/文件夾下新建webpack.dll.config.js文件,複製一下代碼:

const path = require("path")
	const webpack = require("webpack")
	
	module.exports = {
	    // 你想要打包的模塊的數組
	    entry: {
	        vendor: ['vue/dist/vue.esm.js', 'axios', 'vue-router', 'vuex']
	    },
	    output: {
	        path: path.join(__dirname, '../static/js'), // 打包後文件輸出的位置
	        filename: '[name].dll.js',
	        library: '[name]_library'
	    },
	    plugins: [
	        new webpack.DllPlugin({
	            path: path.join(__dirname, '.', '[name]-manifest.json'),
	            name: '[name]_library',
	            context: __dirname
	        }),
	        // 壓縮打包的文件
	        new webpack.optimize.UglifyJsPlugin({
	            compress: {
	                warnings: false
	            }
	        })
	    ]
	}
複製代碼

build/webpack.dev.config.jsbuild/webpack.prod.config.js中添加plugins

new webpack.DllReferencePlugin({
	      context: __dirname,
	      manifest: require('./vendor-manifest.json')
	}),
複製代碼

根目錄下的index.html下引入預編譯的庫

<script src="./static/js/vendor.dll.js"></script>
複製代碼

package.json/scripts下中添加dll命令

"dll": "webpack --config ./build/webpack.dll.config.js"
複製代碼

運行:

npm run dll
複製代碼

而後再

npm run dev或npm run build
複製代碼

提取公共代碼 使用CommonsChunkplugin提取公共的模塊,能夠減小文件體積,也有助於瀏覽器層的文件緩存

npm run dll
npm run dev 或npm run build
複製代碼
相關文章
相關標籤/搜索