代码支解与懒加载情况下(code-splitting+lazyload)抽离懒加载模块的公用模块代码

媒介

我们清晰,在 webpack 中经由过程CommonsChunkPlugin 能够将 entry 的进口文件中援用屡次的文件抽离打包成一个公用文件,从而削减代码反复冗余

    entry: {
        main: './src/main.js',
        user: './src/user.js'
    },
    ......
    new webpack.optimize.CommonsChunkPlugin({
        name: "commons",
        filename: 'common.js',
        minChunks: 2,
    })
    
    // 打包天生一个文件common.js ,包括main.js 和 user.js 中援用两次及以上的模块代码

那末题目来了,当运用了相似 vue-router 的代码支解+懒加载功用的时刻,每一个路由对应的.vue文件中,配合援用了屡次的模块,要怎样抽离出代码支解模块的公用模块代码出来呢?

题目现实场景

举个栗子

// 懒加载路由文件 routes.js
const
    Index = () => import(/* webpackChunkName: "index" */ "page/index/Index.vue"),
    User = () => import(/* webpackChunkName: "userIndex" */ "page/user/Index.vue"),
    UserDetail = () => import(/* webpackChunkName: "userDetail" */ "page/user/Detail.vue"),
    ...
// page/index/Index.vue 首页路由文件
<template>首页</template>
<script>
    import pub from 'script/public.js'
    ...
</script>
// page/index/Index.vue 用户页路由文件
<template>用户页</template>
<script>
    import pub from 'script/public.js'
    ...
</script>

上述运用了vue-router懒加载打包出来的 首页路由文件index.js 和 用户页文件userIndex.js 都邑包括一份 public.js的代码,反复了。

那末题目就是,在代码支解的代码中,怎样自动抽离大众代码? 就像CommonsChunkPlugin的结果一样,CommonsChunkPlugin怎样在 code-splitting 的场景上运用呢 ?

解决计划

如题目所示,存在两个运用了webpack code-splitting 和 懒加载的路由文件,路由文件都运用了公用的public.js模块。

// page/index/Index.vue 首页路由文件
<template>首页</template>
<script>
    import pub from 'script/public'
    ...
</script>
// 用户页
// page/index/Index.vue 用户页路由文件
<template>用户页</template>
<script>
    import pub from 'script/public'
    ...
</script>

要将 public.js公用模块抽离,有三种解决计划

计划一,CommonsChunkPlugin 签字模块

手动将一切共用的模块抽离在一个文件。
建立文件commons.js

// commons.js
import pub from 'public'

webpack.config.jsCommonsChunkPlugin插件指定commons 的entry

// webpack.config.js
entry:{
    main: 'src/main.js',
    commons: 'src/commons.js'
},
...
    new webpack.optimize.CommonsChunkPlugin({
        name: "commons",   // 和 entry的commons对应,
        filename: 'common.bundle.js', // 抽离大众文件
        minChunks: Infinity,
    })

如许,假如路由文件或其他模块运用到了 commons.js中的模块,都不会反复加载代码,而是在common.bundle.js中猎取。

计划二,CommonsChunkPlugin 设置 children 属性

官方文档CommonsChunkPlugin 中 children属性诠释

Move common modules into the parent chunk

With Code Splitting, multiple child chunks of an entry chunk can have common dependencies. To prevent duplication these can be moved into the parent. This reduces overall size, but does have a negative effect on the initial load time. If it is expected that users will need to download many sibling chunks, i.e. children of the entry chunk, then this should improve load time overall.

可知,设置 children 为 true 能够将code-splitting的模块的依靠模块抽离到父模块,如许做的效果就是,确切抽离公用模块,降低了代码反复,削减了代码体积。然则同时,抽离到父模块,也意味着假如有一个懒加载的路由 ShopList.vue 没有用到public.js 模块,然则现实上引入了父模块,也为这ShopList.vue也引入了public.js的代码。

这就须要CommonsChunkPluginasync 属性。

计划三(最好实践),childrenasync 左右开弓

Extra async commons chunk

Similar to the above one, but instead of moving common modules into the parent (which increases initial load time) a new async-loaded additional commons chunk is used. This is automatically downloaded in parallel when the additional chunk is downloaded.

设置了async, 会将上述懒加载的路由文件公用的模块代码,抽离打包成一个零丁的文件,而且该文件是按需加载的,假如某个路由没有运用到这些公用模块,是不会加载进来的。

举个例子:
首页路由模块(接见途径/index),援用了 public模块
用户路由模块(接见途径/user),援用了 public模块
购物车模块(接见途径/shop),没有援用 public模块

那末,打包天生的文件大概是

main.js - 根进口文件
index.js - 首页路由文件
user.js - 用户路由文件
shop.js - 购物车路由文件
0.js - 抽离路由的公用模块文件

接见url/index,加载的依靠文件是main.js + index.js + 0.js
接见url/user,加载的依靠文件是main.js + user.js + 0.js
接见url/shop,加载的依靠文件是main.js + shop.js
基本解决了 lazy load + code-splitting 情况下的公用模块抽离。

以下附上简朴的webpack.config.js设置代码

entry: {
    main: './src/main.js'
},
...
plugins: [
    ...
    new webpack.optimize.CommonsChunkPlugin({
        name: "main",
        minChunks: 2,
        children: true,
        // deepChildren: true,
        async: true,
    })
]

The CommonsChunkPlugin has been removed in webpack v4 legato. To learn how chunks are treated in the latest version, check out the SplitChunksPlugin.

PS: webpack 4 已将CommonsChunkPlugin烧毁,解决计划仅能在webpack 3 以下运用。

参考资料

commons-chunk-plugin
CommonChunkPlugin: Feature – Select statically imported modules from chunks that were created from a dynamic import (require.ensure / System.import / import(“..”))

    原文作者:微雨微语
    原文地址: https://segmentfault.com/a/1190000014221669
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞