动态加载

介绍

Hippy 2.2 版本之前只支持加载单个 js bundle 文件。随着业务越来越复杂,单个 js 文件体积愈发增加的体积会影响首屏启动速度。为了解决这个问题,Hippy 在 2.2 版本增添了动态加载能力,开发人员可以按需来动态引入子 js bundle 文件。

Hippy 最低版本支持 2.2

原理架构

Communication Info

范例

[React 范例]

[Vue 范例]

使用方法

安装

npm install -D @hippy/hippy-dynamic-import-plugin

使用

webpack 打包脚本 中引入插件

  1. const HippyDynamicImportPlugin = require('@hippy/hippy-dynamic-import-plugin');
  2. module.exports = {
  3. entry: {
  4. index: 'example.js',
  5. },
  6. output: {
  7. filename: 'example.output.js',
  8. strictModuleExceptionHandling: true,
  9. path: path.resolve('./dist/'),
  10. globalObject: '(0, eval)("this")',
  11. },
  12. plugins: [
  13. new HippyDynamicImportPlugin(),
  14. ],
  15. };

降级方案

在终端 SDK 不支持 dynamic import 的版本,可以使用以下两种方法阻止分包。

  • 利用 Webpack 提供的 /* webpackMode: "eager" */ magic comment 停止生成额外的chunk。具体原理可以参看 webpack magic comment
  1. // 在import()中增加magic comment例子如下:
  2. AsyncComponent: () => import(/* webpackMode: "eager" */ './dynamicImport/async-component.vue'),
  • 在 Webpack 配置中使用 webpack.optimize.LimitChunkCountPluginmaxChunks 参数。具体原理可以参看 webpack LimitChunkCountPlugin
  1. // 通过配置webpack.optimize.LimitChunkCountPlugin的maxChunks为1,dynamic import 会替换成 Promise.resolve
  2. plugins: [
  3. ...,
  4. new HippyDynamicImportPlugin(),
  5. // LimitChunkCountPlugin can control dynamic import ability
  6. // Using 1 will prevent any additional chunks from being added
  7. new webpack.optimize.LimitChunkCountPlugin({
  8. maxChunks: 1,
  9. }),
  10. ],

支持同时配置本地/网络加载分包

网络加载 hippy sdk 最低支持版本 2.5.5

网络加载 @hippy/hippy-dynamic-import-plugin 最低支持版本 2.0.0

提供以下几种模式

业务只加载 [本地] js bundle

与原有动态加载能力一样,直接使用 import() 语法即可

业务只加载 [远程] js bundle

  • webpack打包脚本配置全局 publicPath(可选)
  1. // webpack output 配置
  2. output: {
  3. ...
  4. publicPath: 'https://xxxx/hippy/hippyVueDemo/',
  5. },
  • 在业务代码引用分包的入口配置 magic commentwebpackChunkName(必须) 和 customChunkPath(可选),如果没有配置customChunkPath,会默认使用全局 publicPath; 以 Hippy-Vue 为例:
  1. // Hippy-Vue 配置,
  2. AsyncComponentFromHttp: () => import(/* customChunkPath: "https://xxx/hippy/hippyVueDemo/", webpackChunkName: "asyncComponentFromHttp" */'./dynamicImport/async-component-http.vue')
  3. .then(res => res)
  4. .catch(err => console.error('import async remote component error', err))

业务同时加载 [本地 + 远程] js bundle

  • 去除 webpack 全局配置的 publicPath(publicPath 会强制在所有 bundle 前加上配置的路径,影响本地 bundle 加载)

  • 加载远程 bundle,在业务代码引用分包的入口配置 magic commentwebpackChunkName(必须) 和 customChunkPath(必须),以 Hippy-Vue 为例:

  1. // Hippy-Vue 配置
  2. AsyncComponentFromHttp: () => import(/* customChunkPath: "https://xxx/hippy/hippyVueDemo/", webpackChunkName: "asyncComponentFromHttp" */'./dynamicImport/async-component-http.vue')
  3. .then(res => res)
  4. .catch(err => console.error('import async remote component error', err))
  • 加载本地 bundle,在业务代码引用分包的入口配置 magic commentwebpackChunkName (可选),以 Hippy-Vue 为例:
  1. // Hippy-Vue 配置
  2. AsyncComponentFromLocal: () => import(/* webpackChunkName: "asyncComponentFromLocal" */'./dynamicImport/async-component-local.vue')
  3. .then(res => res)
  4. .catch(err => console.error('import async local component error', err)),