webpack 异步组件的缺陷

1,780 阅读1分钟
原文链接: www.zybuluo.com

webpack本身自带切割代码(code splitting)的功能,脚本按需加载,简单好用

用法如下:

require.ensure(["module-a", "module-b"], function(require) {
    var a = require("module-a")
    // ...
})
//或
require(['./my-async-component'], resolve, reject) //vue组件自带错误回掉方法

但是,该功能也不是完美的,在3g、4g网络下出现了无法加载异步组件的问题!!!坑爹呀!!!

经过分析,得出下面的结论:

1、运营商3g、4g网络 阶段性断网 ,尤其 联通 最严重
2、webpack本身 无法捕获异步组件加载失败 的情况 (webpack2支持捕获组件状态

既然第一个问题无法解决,那我们就解决第二个问题。

1、 安装 require-error-handler-webpack-plugin 插件,用它捕获异步组件的加载失败的状态

var  requireErrorHandlerPlugin = require('require-error-handler-webpack-plugin'),
    JsonpMainTemplatePlugin = require('webpack/lib/JsonpMainTemplatePlugin')

2、 使用这个插件

plugins: [
    new requireErrorHandlerPlugin.JsonpErrorHandlerPlugin(JsonpMainTemplatePlugin),
    new requireErrorHandlerPlugin.RequireEnsureErrorHandlerPlugin(),
    new requireErrorHandlerPlugin.AMDRequireErrorHandlerPlugin()
]

3、项目中使用方法(这个方法不能完全遏制,但是可以减少加载失败的概率)

export default {
    components:{
        a: (resolve, reject) => {
            const tryMax = 15
            let tryCount = 0,
                _time = null //隔1.5秒执行一次
            getComponents()
            //递归调用组件
            function getComponents() {
                require(['../view/a'], (response) => {
                    //成功后执行
                    resolve(response)
                }, () => {
                    //异步组件加载失败后调用
                    tryCount += 1
                    if (tryCount > tryMax) { // 若超出最大尝试次数则 reject
                        reject()
                    } else {
                        _time = setInterval(() => {
                            clearInterval(_time)
                            getComponents()
                        }, 1500)
                    }
                })
            }
        }
    }
}

当项目访问量很大,甚至超过 1000万 pv/天的访问量,就会发现一些恶心的问题,而这些问题的暴露都要感谢我们的用户,因为你们,我才会知道运营商网络的不稳定性,知道了我们代码中的缺陷