webpack 外掛總結歸類

麥樂丶發表於2018-10-26

功能類

html-webpack-plugin

自動生成html,基本用法:

new HtmlWebpackPlugin({
  filename: 'index.html', // 生成檔名
  template: path.join(process.cwd(), './index.html') // 模班檔案
})
複製程式碼

copy-webpack-plugin

拷貝資源外掛

基本用法:

new CopyWebpackPlugin([
  {
    from: path.join(process.cwd(), './vendor/'),
    to: path.join(process.cwd(), './dist/'),
    ignore: ['*.json']
  }
])
複製程式碼

webpack-manifest-plugin && assets-webpack-plugin

倆個外掛效果一致,都是生成編譯結果的資源單,只是資源單的資料結構不一致而已。

webpack-manifest-plugin 基本用法:

module.exports = {
  plugins: [
    new ManifestPlugin()
  ]
}
複製程式碼

assets-webpack-plugin 基本用法:

module.exports = {
  plugins: [
    new AssetsPlugin()
  ]
}
複製程式碼

clean-webpack-plugin

在編譯之前清理指定目錄指定內容。

基本用法:

// 清理目錄
const pathsToClean = [
  'dist',
  'build'
]
 
// 清理引數
const cleanOptions = {
  exclude:  ['shared.js'], // 跳過檔案
}
module.exports = {
  // ...
  plugins: [
    new CleanWebpackPlugin(pathsToClean, cleanOptions)
  ]
}
複製程式碼

compression-webpack-plugin

提供帶 Content-Encoding 編碼的壓縮版的資源

基本用法:

module.exports = {
  plugins: [
    new CompressionPlugin() 
  ]
}
複製程式碼

progress-bar-webpack-plugin

編譯進度條外掛

基本用法:

module.exports = {
  //...
  plugins: [
    new ProgressBarPlugin()
  ]
}
複製程式碼

程式碼相關類

webpack.ProvidePlugin

自動載入模組,如 $ 出現,就會自動載入模組;$ 預設為'jquery'的exports

用法:

new webpack.ProvidePlugin({
  $: 'jquery',
})
複製程式碼

webpack.DefinePlugin

定義全域性常量

用法:

new webpack.DefinePlugin({
  'process.env': {
    NODE_ENV: JSON.stringify(process.env.NODE_ENV)
  }
})
複製程式碼

mini-css-extract-plugin && extract-text-webpack-plugin

提取css樣式,對比:

  • mini-css-extract-plugin 為webpack4及以上提供的plugin,支援css chunk
  • extract-text-webpack-plugin 只能在webpack3 及一下的版本使用,不支援css chunk

基本用法 extract-text-webpack-plugin:

const ExtractTextPlugin = require("extract-text-webpack-plugin");
 
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin("styles.css"),
  ]
}
複製程式碼

基本用法 mini-css-extract-plugin:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
    module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '/'  // chunk publicPath
            }
          },
          "css-loader"
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css", // 主檔名
      chunkFilename: "[id].css"  // chunk檔名
    })
  ]
}
複製程式碼

編譯結果優化類

wbepack.IgnorePlugin

忽略regExp匹配的模組

用法:

new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
複製程式碼

uglifyjs-webpack-plugin

程式碼醜化,用於js壓縮

用法:

module.exports = {
  //...
  optimization: {
    minimizer: [new UglifyJsPlugin({
      cache: true,   // 開啟快取
      parallel: true, // 開啟多執行緒編譯
      sourceMap: true,  // 是否sourceMap
      uglifyOptions: {  // 醜化引數
        comments: false,
        warnings: false,
        compress: {
          unused: true,
          dead_code: true,
          collapse_vars: true,
          reduce_vars: true
        },
        output: {
          comments: false
        }
      }
    }]
  }
};
複製程式碼

optimize-css-assets-webpack-plugin

css壓縮,主要使用 cssnano 壓縮器

用法:

module.exports = {
  //...
  optimization: {
    minimizer: [new OptimizeCssAssetsPlugin({
      cssProcessor: require('cssnano'),   // css 壓縮優化器
      cssProcessorOptions: { discardComments: { removeAll: true } } // 去除所有註釋
    })]
  }
};
複製程式碼

webpack-md5-hash

使你的chunk根據內容生成md5,用這個md5取代 webpack chunkhash。

var WebpackMd5Hash = require('webpack-md5-hash');
 
module.exports = {
  // ...
  output: {
    //...
    chunkFilename: "[chunkhash].[id].chunk.js"
  },
  plugins: [
    new WebpackMd5Hash()
  ]
};
複製程式碼

SplitChunksPlugin

CommonChunkPlugin 的後世,用於chunk切割。

webpack 把 chunk 分為兩種型別,一種是初始載入initial chunk,另外一種是非同步載入 async chunk,如果不配置SplitChunksPlugin,webpack會在production的模式下自動開啟,預設情況下,webpack會將 node_modules 下的所有模組定義為非同步載入模組,並分析你的 entry、動態載入(import()、require.ensure)模組,找出這些模組之間共用的node_modules下的模組,並將這些模組提取到單獨的chunk中,在需要的時候非同步載入到頁面當中,其中預設配置如下:

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async', // 非同步載入chunk
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~', // 檔名中chunk分隔符
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,  // 
          priority: -10
        },
        default: {
          minChunks: 2,  // 最小的共享chunk數
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};
複製程式碼

編譯優化類

DllPlugin && DllReferencePlugin && autodll-webpack-plugin

dllPlugin 將模組預先編譯,DllReferencePlugin 將預先編譯好的模組關聯到當前編譯中,當 webpack 解析到這些模組時,會直接使用預先編譯好的模組。

autodll-webpack-plugin 相當於 dllPlugin 和 DllReferencePlugin 的簡化版,其實本質也是使用 dllPlugin && DllReferencePlugin,它會在第一次編譯的時候將配置好的需要預先編譯的模組編譯在快取中,第二次編譯的時候,解析到這些模組就直接使用快取,而不是去編譯這些模組。

dllPlugin 基本用法:

const output = {
  filename: '[name].js',
  library: '[name]_library',
  path: './vendor/'
}

module.exports = {
  entry: {
    vendor: ['react', 'react-dom']  // 我們需要事先編譯的模組,用entry表示
  },
  output: output,
  plugins: [
    new webpack.DllPlugin({  // 使用dllPlugin
      path: path.join(output.path, `${output.filename}.json`),
      name: output.library // 全域性變數名, 也就是 window 下 的 [output.library]
    })
  ]
}
複製程式碼

DllReferencePlugin 基本用法:

const manifest = path.resolve(process.cwd(), 'vendor', 'vendor.js.json')

module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require(manifest), // 引進dllPlugin編譯的json檔案
      name: 'vendor_library' // 全域性變數名,與dllPlugin宣告的一致
    }
  ]
}
複製程式碼

autodll-webpack-plugin 基本用法:

module.exports = {
  plugins: [
    new AutoDllPlugin({
      inject: true, // 與 html-webpack-plugin 結合使用,注入html中
      filename: '[name].js',
      entry: {
        vendor: [
          'react',
          'react-dom'
        ]
      }
    })
  ]
}
複製程式碼

happypack && thread-loader

多執行緒編譯,加快編譯速度,thread-loader不可以和 mini-css-extract-plugin 結合使用。

happypack 基本用法:


const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
const happyLoaderId = 'happypack-for-react-babel-loader';

module.exports = {
  module: {
    rules: [{
      test: /\.jsx?$/,
      loader: 'happypack/loader',
      query: {
        id: happyLoaderId
      },
      include: [path.resolve(process.cwd(), 'src')]
    }]
  },
  plugins: [new HappyPack({
    id: happyLoaderId,
    threadPool: happyThreadPool,
    loaders: ['babel-loader']
  })]
}
複製程式碼

thread-loader 基本用法:

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve("src"),
        use: [
          "thread-loader",
          // your expensive loader (e.g babel-loader)
          "babel-loader"
        ]
      }
    ]
  }
}
複製程式碼

hard-source-webpack-plugin && cache-loader

使用模組編譯快取,加快編譯速度。

hard-source-webpack-plugin 基本用法:

module.exports = {
  plugins: [
    new HardSourceWebpackPlugin()
  ]
}
複製程式碼

cache-loader 基本用法:

module.exports = {
  module: {
    rules: [
      {
        test: /\.ext$/,
        use: [
          'cache-loader',
          ...loaders
        ],
        include: path.resolve('src')
      }
    ]
  }
}
複製程式碼

編譯分析類

webpack-bundle-analyzer

編譯模組分析外掛

基本用法:

new BundleAnalyzerPlugin({
  analyzerMode: 'server',
  analyzerHost: '127.0.0.1',
  analyzerPort: 8889,
  reportFilename: 'report.html',
  defaultSizes: 'parsed',
  generateStatsFile: false,
  statsFilename: 'stats.json',
  statsOptions: null,
  logLevel: 'info'
}),
複製程式碼

stats-webpack-plugin && PrefetchPlugin

stats-webpack-plugin 將構建的統計資訊寫入檔案,該檔案可在 webpack.github.io/analyse中上傳進行編譯分析,並根據分析結果,可使用 PrefetchPlugin 對部分模組進行預解析編譯(本人也不理解這個plugin,據說優化效果不明顯,有興趣的同學請見 how-to-optimize-webpacks-build-time-using-prefetchplugin-analyse-tool)。

stats-webpack-plugin 基本用法:

module.exports = {
  plugins: [
    new StatsPlugin('stats.json', {
      chunkModules: true,
      exclude: [/node_modules[\\\/]react/]
    })
  ]
};
複製程式碼

PrefetchPlugin 基本用法:

module.exports = {
  plugins: [
    new webpack.PrefetchPlugin('/web/', 'app/modules/HeaderNav.jsx'),
    new webpack.PrefetchPlugin('/web/', 'app/pages/FrontPage.jsx')
];
}
複製程式碼

speed-measure-webpack-plugin

統計編譯過程中,各loader和plugin使用的時間。

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
 
const smp = new SpeedMeasurePlugin();
 
const webpackConfig = {
  plugins: [
    new MyPlugin(),
    new MyOtherPlugin()
  ]
}
module.exports = smp.wrap(webpackConfig);
複製程式碼

speed-measure-webpack-plugin

相關文章