全自动分包
开发者不再需要关心小程序的单包 2M 限制。
应用代码可按照标准 Web 规则互相引用。
在实际产物中,主包引用分包,分包引用主包,分包引用分包,循环依赖引用,全部都没有问题。
只需决定“何时加载某功能”,而不必思考“这个功能该放哪个包”。
需要随 App 或页面一起启动的代码照常使用静态 import:
import { initializeStore } from './store'
initializeStore()从 App、页面及其依赖通过静态导入可达的模块会保留在主包。
在功能入口使用 import():
async function openReport() { const { createReport } = await import('./features/report') return await createReport()}只需要在功能入口使用一次动态 import()。这表明该模块可以被异步加载(和 Web 规则一致)。
该功能内部继续使用普通静态引用:
import { collectData } from './collect-data'import { renderPdf } from './render-pdf'
export function createReport() { return renderPdf(collectData())}动态 import() 后面的静态依赖也会参与全自动拆包,不需要把每个文件都改成动态导入。
即使 静态依赖超过 2M 大小限制也没关系。
实际上,vpt 会分析所有依赖的引用关系,重写并解耦它们,把它们放置在合适的位置。
使用 React.lazy
Section titled “使用 React.lazy”import { lazy, Suspense } from 'react'import { View } from 'virtual:taro/components'
const Report = lazy(() => import('./features/report.tsx'))
function ReportEntry() { return ( <Suspense fallback={<View>正在加载报表…</View>}> <Report /> </Suspense> )}./features/report.tsx 默认导出 React 组件。首次渲染 <Report /> 时会触发动态导入。
如何异步加载页面
Section titled “如何异步加载页面”页面就是一个普通组件。
和 Web 一样,做个骨架屏,然后通过 React.lazy() 和 <Suspense> 去动态加载真正的页面组件。这个组件就会被自动分包。
当然,页面内容也可以使用原生组件;按照原生组件设置后,可以通过同样的 <Suspense> 按需加载。
适合按需加载的通常是大型编辑器、图表、报表、导出工具或其他低频功能。应在完整功能的入口使用 import(),而不是逐个动态导入小型工具模块。
功能内部保持静态导入,只有确实需要更晚加载的部分才继续使用下一层 import()。
全自动位置规划:指最终可能在主包,也可能在分包。当然,应用代码不需要关心这些分包信息。
| 源码关系 | 结果 |
|---|---|
| App、页面及其静态依赖 | 小程序要求同步启动,所以保留在主包 |
仅通过动态 import() 到达的功能入口 | 参与全自动位置规划 |
动态 import() 后面的静态依赖 | 参与全自动位置规划;若同时也是启动依赖,则留在主包 |
按需功能内部的下一层动态 import() | 参与全自动位置规划 |
import type | 构建时移除,不影响位置规划 |
原生组件与其他资源
Section titled “原生组件与其他资源”小程序原生组件会参与位置规划。vpt 会把原生组件目录的文件体积计入声明模块,并将目录输出到该模块最终所属的主包或分包。接入方式、类型 schema 和动态加载示例参见原生组件。 只要整个原生组件的目录不超过 2M,可以完全交给 vpt 自动规划。
固定 App 样式入口、它导入的全局样式、图片、字体和其他普通构建资源暂不参与位置规划;对这些资源的自动规划已列入后续版本。
位置规划算法、跨分包加载方式和小程序运行时原理参见模块系统。