分离公共资源

150 阅读2分钟

实际项目中我们需要让一些公共资源只打包一次,避免浪费,同时避免有些文件过大,这就使用到了公共资源的分离。

比如我们在react项目中,就需要将react、react-dom进行分离,让它不打包进bundle文件。

一、使用html-webpack-externals-plugin  

可以使用html-webpack-externals-plugin对cdn引入的第三方库进行分离。

在plugins中增加配置:

new HtmlWebpackExternalsPlugin({
    externals: [
      {
        module: 'react',
        entry: 'XXX', // react cdn地址
        global: 'React'
      }
    ]
})

记得在html文件中引入对应的第三方包。

二、使用SplitChunksPlugin

webpack4内置的插件,用来代替CommonsChunkPlugin插件的。

chunks之间是根据依赖图的关系进行关联的,CommonsChunkPlugin根据这种关系来避免重复依赖,但是也只能做到这里了,并不能进行进一步的优化。

默认情况下,该插件只会影响按需加载的chunks,因为要修改inital chunks需要修改html中的文件引入。

配置:

 optimization: {    minimize: true,    minimizer: [`...`, new CssMinimizerPlugin()],    splitChunks: {      chunks: "async",      minChunks: 2,      cacheGroups: {        commons: {          test: /(react|react-dom)/,          name: "vendors",          chunks: "all",        },      },    },  },

在htmlWebpackPlugin中增加chunks属性,该值是一个数组,表示在该chunk中要使用到的包:

 new HtmlWebpacPlugin({    template: `./src/index/index.html`,    chunks: ["vendors", 'index'], })

它会将react、react-dom从打包好的业务代码js中拆分出来。减少业务代码文件的体积,并且直只打包一次。

chunks的值由三种:

  • async:对异步引入的包进行分离(默认)。
  • inital:对同步引入的包进行分离。
  • all:对所有引入的库进行分离(推荐)。

all时chunk可以在同步和异步chunk之间共享。

minChunks是指文件被用的次数。 

html-webpack-externals-plugin插件已经被弃用了,所以建议使用splitChunksPlugin。

在打包js的时候,会生成一个txt文件,不想要这个文件,可以在TerserPlugin中配置extractComments为false。

三、css的分离

使用mini-css-extract-plugin,配置如下:

const path = require("path");
const HtmlWebpacPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {  
    mode: "development",  
    entry: "./src/index.js",  
    output: {    
       path: path.join(__dirname, "dist"),
       filename: "[name]_[chunkhash:8].js",
    },
    module: {
       rules: [
         {
           test: /\.css/,
           use: [MiniCssExtractPlugin.loader, "css-loader"],
         },
         {
           test: /\.js$/,
           use: "babel-loader",
         },
         {
           test: /\.(jpg|png|jpeg|gif)$/,
           use: {
             loader: "file-loader",
             options: {
                name: "[name]_[hash].[ext]",
                outputPath: "imgs/",
            },
         },
       },
     ],
   },
   plugins: [
     new HtmlWebpacPlugin({ template: "./src/index.html" }),
     new MiniCssExtractPlugin({ filename: "[name]_[contenthash:8].css" }),
  ],
};

使用mini-css-extract-plugin时,要关闭style-loader,因为style-loader的作用是将生成的css以style标签的形式插入到head中,而mini-css-extract-plugin则是将css抽离成一个文件,所以它们功能互斥。