最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 谈一谈Webpack 的SplitChunks

    正文概述 掘金(头号前端)   2021-08-06   641

    webpack官网中,有这么一句话,我不是很认同:

    可以说,性能优化最重要的部分就是懂得如何分包了。因此,就来谈谈webpack中的分包。

    首先我们需要了解一个概念。

    什么是chunks

    一个常考的面试题是 module、chunk、bundle是什么。对于初学者,这个是很迷惑的。我们首先要知道webpack一个简单的理解:

    Webpack: 构建你的assets。左侧的资源通过webpack后,都能输出web浏览器能识别的资源! 归因于node构建了一个世界,让这个世界所有非js资源,都在js世界下的规则下处理:

    css: 本质是style下的一个字符串,webpack处理css文本后,如果要直接作为style标签插入,再使用style-loader,如果要拿出来,则通过MiniCssExtractPlugin插件进行处理。 less: 本质最终要转化成css,因此通过less-loader,转化为css,再重复上面的操作。 typescript: 浏览器是没法直接识别的,通过ts-loader。来转化为浏览器能识别的js。

    以上这些,都是为了做一件事:

    以上图webpack为划分点,我们就可以区分module和bundle。即:左边是资源就是moudle,右边的资源就是bundle。

    一个ts文件、图片、less、pug等都是一个module,而打包后的产物,总的称呼就是bundle。

    那么chunk是什么呢?

    对于打包产物bundle, 有些情况下,我们觉得太大了。 为了优化性能,比如快速打开首屏,利用缓存等,我们需要对bundle进行以下拆分,对于拆分出来的东西,我们叫它chunk。

    我们试着打包一下!

    默认配置

    现在我们创建src/index.js 和 src/a.js

    index.jsa.js
    import lodash from "lodash";,import { a } from "./a";,console.log(lodash, a);export const a = "i am aaaaaa";,console.log(a);,

    目录结构:

    谈一谈Webpack 的SplitChunks

    webpack.config.js 配置和打包结果为:

    webpack.config.js
    {, mode: "production",, entry: {, main: "./src/index.js",, },, output: {, path: path.resolve(__dirname, "dist"),, filename: "[name].js", , clean: true,, },,}谈一谈Webpack 的SplitChunks

    默认的,webpack没有进行分包,全部都打在一起了。

    一些配置字段

    Webpack 的分包主要在optimization.splitChunks属性,现在我们来尝试使用不同的配置字段来看看效果。

    optimization.splitChunks.chunks

    Chunks 有三个提供的值,分别是 async、initial、all

    async

    此值是默认的chunks值,也就是说,我们的第一次打包实际上就是实行了async,该值的意思是:对于动态加载的模块,默认配置会将该模块单独打包。使用以下语法进行动态加载(还有其他写法):

    import('lodash')
    

    修改index.js,然后运行build命令,为了文件更直观,我们将optimization.chunkIds的值设置为named

    index.js
    import { a } from "./a";,import('lodash').then(lodash => {, const res = lodash.default.add(3,4), console.log(a, res);,})谈一谈Webpack 的SplitChunks

    可以看到lodash被分出一个单独的包了。

    以下是webpack对于默认配置的说法:

    进行实验后,发现并不准确,比如两个入口引入lodash,lodash并未被抽出来

    index.jsother.js
    import lodash from "lodash";,import { a } from "./a";,console.log(lodash, a);import lodash from "lodash";,,console.log("lodash", lodash);

    配置与打包

    配置打包
    {, entry: {, main: "./src/index.js",, other: "./src/other.js",, },, optimization: {, chunkIds: "named",, },,}谈一谈Webpack 的SplitChunks默认配置只会抽出动态加载的模块,通常情况下,不是立即需要的包,可以考虑动态加载,比如导出excel的包,echarts,monaco-editor等。#### initial

    当chunk为initial或者为alll时,webpack打包遵循以下配置(取名default):

    module.exports = {
      //...
      optimization: {
        splitChunks: {
          chunks: 'initial',
          minSize: 20000,
          minRemainingSize: 0,
          minChunks: 1,
          maxAsyncRequests: 30,
          maxInitialRequests: 30,
          enforceSizeThreshold: 50000,
          cacheGroups: {
            defaultVendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
              reuseExistingChunk: true,
            },
            default: {
              minChunks: 2,
              priority: -20,
              reuseExistingChunk: true,
            },
          },
        },
      },
    };
    

    尽管你的配置可能是这样:

    {, entry: {, main: "./src/index.js",, other: "./src/other.js",, },, optimization: {, chunkIds: "named",, splitChunks: {, chunks: "initial",, },, },,}谈一谈Webpack 的SplitChunks

    只有当chunks 不为async时,webpack打包的默认配置才会是default配置

    all

    当chunks值为all时,基本跟initial值相同,我们来实验一下它的不同点;

    我们将在other.js对lodash动态引用:

    import('lodash').then(lodash => {
        const res = lodash.default.add(3,4)
        console.log(res);
    })
    

    然后分别使用chunks为all 和initial的值,看看效果:

    allinitial
    谈一谈Webpack 的SplitChunks谈一谈Webpack 的SplitChunks

    可以看到,对于两个入口文件引用lodash, 如果一个是正常引入,一个是动态引入,initial会打包成两份,而all的话,只会有一份,因此,通常情况下,all的优于initial的。

    optimization.splitChunks的其他默认配置

    {
          minSize: 20000,
          minRemainingSize: 0,
          minChunks: 1,
          maxAsyncRequests: 30,
          maxInitialRequests: 30,
          enforceSizeThreshold: 50000,
    }
    

    minSize:此配置是指,将要被分包的chunks,如果压缩前体积不足20k,将不会被拆包。 minChunks:某个chunks被多次引用,如果这个引用次数小于某个值,将不会被拆包。 ... 以上条件满足一个将会被分包。 enforceSizeThreshold:如果某个chunks的大小超过了50k,以上限制将不会生效。

    optimization.splitChunks. cacheGroups

    cacheGroups有两个默认缓存策略,也就是chunks为all和initail时的默认配置:

    cacheGroups: {
            defaultVendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10,
              reuseExistingChunk: true,
            },
            default: {
              minChunks: 2,
              priority: -20,
              reuseExistingChunk: true,
            },
     }
    

    defaultVendors 会将源代码中所有引入node_modules的文件打包成为一个大的chunks。 default 则是对于多入口引入的相同模块超过两次后,进行拆包操作,需要注意的是,我们通常操作的单页面应用,默认只有一个入口文件,如果有如下代码:

    // index.js
    import lodash from "lodash";
    import { a } from "./a";
    import { b } from "./b";
    console.log(lodash, a, b);
    
    // a.js
    export const a = "i am aaaaaa";
    console.log(a);
    import "./c";
    
    // b.js
    export const b = "i am bbbbbbbbb";
    console.log(b);
    import "./c";
    
    // c.js
    console.log("ccccccccc");
    

    a.js 和 b.js 共同引用了c.js。此时a、b、c都从属于index.js入口,虽然c.js被引用了两次,但c.js并不会分成单独的包,如果要将c.js单独打包,考虑动态加载。

    谈一谈Webpack 的SplitChunks

    通常,我们只需要默认的配置即可满足大部分需求,有的时候我们可能想单独抽出react相关代码,那么这需要以下配置。

    react: {
      name: "ReactAbout",
      test: /react/,
      priority: 1,
    },
    

    打包效果

    谈一谈Webpack 的SplitChunks

    // other.js
    
    import('lodash').then(lodash => {
        const res = lodash.default.add(3,4)
        console.log(res);
    })
    
    import('./style/a.css')
    import('./style/b.css')
    import('./style/c.css')
    
    {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
    }
    

    css

    css也是性能优化的一部分,有一种方式是通过style- loader将css以style标签的形式插入到文档,这种方式正常引用无法进行分包。但可以通过动态引入的方式分包。

    谈一谈Webpack 的SplitChunks

    另外有一个MiniCssExtractPlugin插件进行css的分包。此插件默认为每个入口单独抽出css,也可以进行cacheGroups的配置,满足条件时,会将多个入口的css打包在一起。

    css: {
      name: "css",
      test: /\.css$/,
      minChunks: 1,
      enforce: true,
    }
    

    起源地下载网 » 谈一谈Webpack 的SplitChunks

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元