[关闭]
@buluoXu 2016-08-28T15:22:39.000000Z 字数 2130 阅读 2531

webpack 异步组件的缺陷

webpack


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

用法如下:

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

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

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

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

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


方法一(不可分离公共代码):

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

  1. // webpack.config.js
  2. var requireErrorHandlerPlugin = require('require-error-handler-webpack-plugin'),
  3. JsonpMainTemplatePlugin = require('webpack/lib/JsonpMainTemplatePlugin')

2、 使用这个插件

  1. // webpack.config.js
  2. plugins: [
  3. new requireErrorHandlerPlugin.JsonpErrorHandlerPlugin(JsonpMainTemplatePlugin),
  4. new requireErrorHandlerPlugin.RequireEnsureErrorHandlerPlugin(),
  5. new requireErrorHandlerPlugin.AMDRequireErrorHandlerPlugin()
  6. ]

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

  1. // app.vue
  2. export default {
  3. components:{
  4. a: (resolve, reject) => {
  5. const tryMax = 15
  6. let tryCount = 0,
  7. _time = null //隔1.5秒执行一次
  8. getComponents()
  9. //递归调用组件
  10. //因为运营商网络会出现短暂的断网现象,所以每隔1500ms就唤醒一次,对多唤醒11次
  11. function getComponents() {
  12. require(['../view/a'], (response) => {
  13. //成功后执行
  14. resolve(response)
  15. }, () => {
  16. //异步组件加载失败后调用
  17. tryCount += 1
  18. if (tryCount > tryMax) { // 若超出最大尝试次数则 reject
  19. reject()
  20. } else {
  21. _time = setInterval(() => {
  22. clearInterval(_time)
  23. getComponents()
  24. }, 1500)
  25. }
  26. })
  27. }
  28. }
  29. }
  30. }

方法二(推荐,可分离公共代码):

1、 安装 async-module-loader 插件,用它捕获异步组件的加载失败的状态

  1. // webpack.config.js
  2. var AsyncModulePlugin = require('async-module-loader/plugin')

2、 使用这个插件

  1. // webpack.config.js
  2. plugins: [
  3. new AsyncModulePlugin()
  4. ]

3、项目中使用方法

  1. // common.js
  2. //按需加载组件的公共方法,因为运营商网络会出现短暂的断网现象,所以每隔1500ms就唤醒一次,对多唤醒11次
  3. function getComponents(requireModel, tryMax, tryCount, resolve, reject) {
  4. let _time = null
  5. requireModel(function onLoad(response) {
  6. resolve(response)
  7. }, function onError() {
  8. tryCount += 1
  9. if (tryCount > tryMax) { // 若超出最大尝试次数则 reject
  10. reject()
  11. } else {
  12. _time = setInterval(() => {
  13. clearInterval(_time)
  14. getComponents(requireModel, tryMax, tryCount, resolve, reject)
  15. }, 1500)
  16. }
  17. })
  18. }
  19. // app.vue
  20. export default {
  21. components:{
  22. a: (resolve, reject) => {
  23. //调用方式
  24. getComponents(require('async-module!./view/Login'), 10, 0, resolve, reject)
  25. },
  26. b: (resolve, reject) => {
  27. //调用方式
  28. getComponents(require('async-module!./view/help'), 10, 0, resolve, reject)
  29. }
  30. }
  31. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注