1. 程式人生 > >webpack由淺入深——(webpack優化配置)

webpack由淺入深——(webpack優化配置)

webpack系列文章

開發優化

開發時的優化主要在於減少webpack編譯打包的時間

Dllplugin

隨著react和vue的火熱,現在很多專案都是基於react和vue建立的。以react為例子,寫程式碼的時候毫無疑問會多次引入react和react-dom。

import React,{Component} from 'react';
import ReactDoM,{render} from 'react-dom';
複製程式碼

這樣會存在一個問題,react和reat-dom中的程式碼基本不會修改,所以使用者編寫程式碼修改時,這些程式碼也會重新編譯和打包,這樣就很浪費時間,Dllplugin一次編譯打包後就會生成一份不變的程式碼供其他模組引用,節省開發時編譯打包的時間。

  • 配置webpack.dll.config.js
const path = require('path');
const webpack = require('webpack');
module.exports ={
  entry: {
    vendor: ['react', 'redux', 'react-router'],
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].dll.js',
    library: '[name]_[hash]'    //提供全域性的變數
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, 'dist', '[name].manifest.json'),
      name: '[name]_[hash]',
    }),
  ],
};
複製程式碼
  • 配置script
"scripts": {
    "dev": "webpack-dev-server",
    "build": "webpack",
    "dll":"webpack --config webpack.dll.config.js"
  },
複製程式碼
  • 配置webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: 'index_bundle.js',
  },
  plugins: [
    new webpack.DllReferencePlugin({
      context: path.join(__dirname),
      manifest:path.resolve(__dirname,'dist','vendor.manifest.json')
    }),
    new HtmlWebpackPlugin(),
    new AddAssetHtmlPlugin({
      filepath: path.resolve(__dirname,'dist','vendor.manifest.json')
    }),
  ],
};
複製程式碼

結構會生成這樣的頁面

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
    <script type="text/javascript" src="vendor-manifest.json"></script>
    <script type="text/javascript" src="index_bundle.js"></script>
  </body>
</html>
複製程式碼

happyPack

webpack支援多個執行緒進行同時進行打包,以便提高編譯打包的速度,但是需要注意,如果專案比較簡單,不要採用這種方式,因為執行緒時需要cpu的花銷的,簡單的專案而使用多執行緒編譯打包,不僅不能加快打包的速度,反而會降低打包的速度

const path = require('path');
cosnt HappyPack = require('happypack');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: 'index_bundle.js',
  },
  module:{
      rules:[
      {
        test: /\.js$/,
        loader: 'happypack/loader?id=js',
        exclude: /node_modules/,
        include: path.resolve(__dirname,'src')
      },
      {
        test: /\.css$/,
        loader: 'happypack/loader?id=css',
        exclude: /node_modules/,
        include: path.resolve(__dirname,'src')
      }] 
  },
  plugins: [
    new HappyPack({
      id: 'js',
      threadPool: happyThreadPool,
      loaders: [ 'babel-loader' ]
    }),
    new HappyPack({
      id: 'css',
      threadPool: happyThreadPool,
      loaders: [ 'style-loader', 'css-loader', 'less-loader' ]
    })
  ]
}
複製程式碼

程式碼優化

程式碼優化主要在於模組化管理程式碼,減少不必要的程式碼

tree-shaking

tree-shaking會將一些沒有用到的程式碼自動刪除掉,這是webpack4內部自帶的功能,這裡有一個前提就是程式碼必須採用es6的模組方式import,不然沒有辦法使用tree-shaking

//a.js
export a = ()=>'a';
export b = ()=>'b';
複製程式碼
//index.js
import {a} from './a'
console.log(a());
複製程式碼

最後打後的程式碼會刪除掉b

變數提升

webpack會將某些程式碼進行優化,以更簡潔的方式來替代。

//c.js
export default 'kbz'
複製程式碼
//index.js
import c from './c'
console.log(c); 
//這兩行會簡化為 var c = 'kbz'
複製程式碼
const path = require('path');
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin')
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: 'index_bundle.js',
  },
  module:{
  },
  plugins: [
    new ModuleConcatenationPlugin()
  ]
}
複製程式碼

抽離公共程式碼

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  entry: {
      //兩個模組都引用了c模組和d模組
      pageA:'./src/pageA',  
      pageB:'./src/pageB',
  },
  output: {
    path: path.resolve(__dirname,'dist'),
    filename: '[name].js',
  },
  optimization:{
      splitChunks:{
          cacheGroups:{
              common:{
                chunks:'initial',
                minChunks:2,    //用兩個模組以上同時引用的模組才會抽離出來
                minSize:0       //限制大小,太小了沒必要抽離
              }
          }
      }
  },
  plugins:[
    new HtmlWebpackPlugin()
  ]
}
複製程式碼
//pageA.js pageB.js
import './pageC'
import './pageD'
複製程式碼
//pageC.js
console.log('c')
複製程式碼
console.log('d')
複製程式碼

生成的頁面

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
    <script type="text/javascript" src="common~pageA~pageB.js"></script>
    <script type="text/javascript" src="pageA.js"></script>
    <script type="text/javascript" src="pageB.js"></script>
  </body>
</html>

作者:夢想攻城獅 連結:https://juejin.im/post/5bd128b56fb9a05ce1729333 來源:掘金 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。