版本要求:3.5+
mfsu 是一种基于 webpack5 新特性 Module Federation 的打包提速方案。核心原理是将应用的依赖构建为一个 Module Federation 的 remote 应用,以免去应用热更新时对依赖的编译。
因此,开启 mfsu 可以大幅减少热更新所需的时间。在生产模式,也可以通过提前编译依赖,大幅提升部署效率。
以 antd-pro 初始化项目为例:
测试过程:
yarn create umi
,选择 ant-design-pro v5 初始化项目。yarn
安装依赖,开始测试 normal 模式。.umi
缓存目录,开启 mfsu 开始测试 mfsu 模式。启用 mfsu 后,热启动得到 10 倍 提升;热更新提升 50% 以上!
随着依赖数量的增多,提升将会更加显著!
时间就是生命。 ———鲁迅
启用 mfsu production 模式时,建议在本地环境将预编译过程完成,并将产物同步到 git,这样在服务器部署的速度将会得到约 30 倍 的提升!
由于设备性能不稳定,测试可能存在部分误差
mfsu:{}
。umi dev
启动项目。在构建依赖时,会出现 MFSU 的进度条,此时应用可能会被挂起或显示依赖不存在,请稍等。mfsu.development.output
配置预编译依赖输出目录并添加到 git 中,在其他开发者启动时,就可以免去再次编译依赖的过程。~/.umi/.cache/.mfsu
下。并且使用了 webpack 缓存,减少再次编译依赖的时间。~/.mfsu/MFSU_CACHE.json
中,用于依赖的 diff。cache-control: max-age=31536000,immutable
,减少浏览器刷新拉取依赖的时间。warning: 由于预编译依赖实现了部分的 tree-shaking,不建议在打包大小敏感的项目中启用生产模式。
mfsu.production = {}
以开启生产模式。umi build
,默认情况下将会将生产依赖预编译到 ~/.mfsu-production
中。~/dist
中,mfsu 再将生产预编译依赖移动到输出目录中。~/.mfsu-production
添加到 git 中。在部署时,仅编译应用文件,速度快到飞起。为了 mfsu 发挥最好的效果,全部的依赖都应当进行预编译。
建议首次启动时,检查项目依赖是否被 mfsu 完全覆盖。我们可以借助 umi 自带的 webpack-analyze 进行依赖分析。
ANALYZE=1 umi dev
启动项目,检查是否正常启动。如果遇到问题,可以提 issue 或者检查下方常见问题。./node_modules
加载的依赖。如果没有,说明项目依赖已经都被 mfsu 覆盖。mfsu 已经完美支持 antd-pro 和 dumi,在默认的 antd-pro 中启用 mfsu,和在其他项目中使用一样简单:
mfsu: {},
请确认 mfsu:{}
被添加到 config.ts
而不是 config.dev.ts
或者 config.prod.ts
。
mfsu 的原理是将 import 和 import() 引入的依赖进行预编译,如果因为一些意料之外的语法,导致项目同时从预编译和node_modules
同时导出了一份 React,将会产生 React 的多实例问题。
例如:
// file 1import React from 'react';// compiledconst { default: React } = await import('react');// file 2var React = _interopRequireDefault('react'); // mfsu cannot recognize
由于 Hooks 的实现机制,React 将会抛出错误。
在 ANALYZE=1 umi dev
启动项目时,可以判断项目是否在 node_modules
中引入 React。如果是,需要尝试修改引入语句。
umi 是一个动态的定义,由一些固定的导出和 plugin 组成,因此无法对 umi 进行预编译。
umi 中存在的例如 react-router-dom 的 Link
等静态导出。和上方的问题类似,如果从 react-router-dom 中导出了 Context
但是使用了从 node_modules/react-router-dom 中导出的 Link
,将会产生这个问题。
在 mfsu 的内部,通过一个 babel 插件 babel-import-redirect-plugin
将 umi 导出的 Link
重定向到了 react-router-dom
解决了这个问题。
如果遇到了这个问题,请尝试 ANALYZE=1 umi dev
以分析依赖来源。