Hyperapp / Webpack - 如何编码拆分组件
Hyperapp / Webpack - How to code split component
为了减少我的应用程序的初始负载,我尝试进行代码拆分。
例如,我成功拆分了 twilio-video,以便在用户按下“call”
时加载和初始化
import('twilio-video').then(Video => {
Video.connect(twilioInfo.data.token, options).then(room => {
...
});
});
Webpack 正确拆分代码并在需要时加载。
现在我想对组件或路由做同样的事情(当我们站在登录页面时不加载用户配置文件)。
有没有等价于
const OtherComponent = React.lazy(() => import('./OtherComponent'));
或
const Home = lazy(() => import('./routes/Home'));
或任何其他方式在路由路径被击中时加载组件?
以前很难。这些天来,Webpack Module Federation 让人喘不过气来。
他们 tons of samples to get you started. For example, the basic-host-remote sample 有一个适合您需要的简单场景。只需将整个 Github 存储库 cd
提取到此示例中,然后 运行 它(如每个示例的 README
中所述)。
密切关注“网络”选项卡。除非明确请求,否则不会加载组件。
基本示例
The basic-host-remote sample 有两个独立的包:app1
和 app2
。
app1
想使用来自 app2
的组件
- 它将
app2
添加到 its WMF config 中的 remotes
app2
提供了一个 Button
组件
app2
exposes
Button
在 its WMF config.
- app1/src/App.js 动态加载按钮。 (它在初始渲染期间这样做,使按需加载不那么明显。)
- 到时候,
app1
使用动态请求组件 import
。
- 它使用 React.lazy 包装负载,如下所示:
const RemoteButton = React.lazy(() => import("app2/Button"));
- 例如,您可以在
useEffect
或 Route.render
回调等中执行此操作
app1
可以在加载后使用 Button
。加载时,它使用 Suspense
显示加载消息:
<React.Suspense fallback={<LoadingScreen />}>
<RemoteButton />
</React.Suspense>
- 或者,不使用
lazy
和 Suspense
,您可以只接受从 import(...)
语句返回的承诺,并以您喜欢的任何方式处理异步加载。当然,WMF
并不局限于react
,可以动态加载任何模块。
- 请注意,
app1
和 app2
具有相同的 shared
设置,确保这些共享依赖项仅加载一次,而不是 bundled/duplicated远程加载代码:
{
// ...
shared: { react: { singleton: true }, "react-dom": { singleton: true } },
}
注意WMF
动态加载必须使用动态import
(即import(...)
),因为:
- 非动态导入将始终在加载时解析(因此使其成为非动态依赖项),并且
- "dynamic
require
" 不能被 webpack 打包,因为浏览器没有 commonjs
的概念(除非你使用一些 hack,在这种情况下,你会丢失相关的 "loading promise
").
WMF 样本
WMF 需要一些学习,但它的所有样本都具有以下共同元素:
- 每个样本都有多个独立的包。
- 每个包都有自己的
webpack.config.js
- 每个包通常充当主机(动态提供组件)或此类组件的消费者,或两者兼而有之。
- 在
development
模式下,您通常会使用完美集成的 webpack-dev-server
提供所有服务。
- 注意:在
production
模式下,您需要对配置进行一些小的调整。当 webpack-dev-server
不在画面中时,您的构建只是将一些额外的 remoteEntry.js
文件添加到构建输出中。
- 您可以使用
shared
配置轻松配置如何处理常见依赖项。 (通常你希望他们作为单身人士,意思是,每个人都应该共享共同的依赖,而不是打包他们自己的。)
- 如果你想坚持把所有东西都放在一个包裹里,那大概也是可以的。只是
expose
它并将它自己的(独立的)组件添加到它自己的 remotes
。不确定它是否有效,但值得一试。
最后的话
同样,这需要一些学习曲线,但我发现它绝对值得。感觉像是我见过的最复杂的动态构建 + 加载系统之一。
最烦人的是,WMF 目前在 Webpack 页面上仍然没有适当的 API 文档,但我相信它很快就会出现。目前,只有一个不太完美的collection of conceptual notes。
WMF作者本人promises to provide better documentation soon™️.
幸运的是,对于学习,the samples 非常好,积极维护并且仍在增强。
为了减少我的应用程序的初始负载,我尝试进行代码拆分。 例如,我成功拆分了 twilio-video,以便在用户按下“call”
时加载和初始化import('twilio-video').then(Video => {
Video.connect(twilioInfo.data.token, options).then(room => {
...
});
});
Webpack 正确拆分代码并在需要时加载。
现在我想对组件或路由做同样的事情(当我们站在登录页面时不加载用户配置文件)。 有没有等价于
const OtherComponent = React.lazy(() => import('./OtherComponent'));
或
const Home = lazy(() => import('./routes/Home'));
或任何其他方式在路由路径被击中时加载组件?
以前很难。这些天来,Webpack Module Federation 让人喘不过气来。
他们 tons of samples to get you started. For example, the basic-host-remote sample 有一个适合您需要的简单场景。只需将整个 Github 存储库 cd
提取到此示例中,然后 运行 它(如每个示例的 README
中所述)。
密切关注“网络”选项卡。除非明确请求,否则不会加载组件。
基本示例
The basic-host-remote sample 有两个独立的包:app1
和 app2
。
app1
想使用来自app2
的组件- 它将
app2
添加到 its WMF config 中的
remotes
- 它将
app2
提供了一个Button
组件app2
exposes
Button
在 its WMF config.
- app1/src/App.js 动态加载按钮。 (它在初始渲染期间这样做,使按需加载不那么明显。)
- 到时候,
app1
使用动态请求组件import
。 - 它使用 React.lazy 包装负载,如下所示:
const RemoteButton = React.lazy(() => import("app2/Button"));
- 例如,您可以在
useEffect
或Route.render
回调等中执行此操作
- 例如,您可以在
app1
可以在加载后使用Button
。加载时,它使用Suspense
显示加载消息:<React.Suspense fallback={<LoadingScreen />}> <RemoteButton /> </React.Suspense>
- 或者,不使用
lazy
和Suspense
,您可以只接受从import(...)
语句返回的承诺,并以您喜欢的任何方式处理异步加载。当然,WMF
并不局限于react
,可以动态加载任何模块。 - 请注意,
app1
和app2
具有相同的shared
设置,确保这些共享依赖项仅加载一次,而不是 bundled/duplicated远程加载代码:
{ // ... shared: { react: { singleton: true }, "react-dom": { singleton: true } }, }
- 或者,不使用
注意WMF
动态加载必须使用动态import
(即import(...)
),因为:
- 非动态导入将始终在加载时解析(因此使其成为非动态依赖项),并且
- "dynamic
require
" 不能被 webpack 打包,因为浏览器没有commonjs
的概念(除非你使用一些 hack,在这种情况下,你会丢失相关的 "loadingpromise
").
WMF 样本
WMF 需要一些学习,但它的所有样本都具有以下共同元素:
- 每个样本都有多个独立的包。
- 每个包都有自己的
webpack.config.js
- 每个包通常充当主机(动态提供组件)或此类组件的消费者,或两者兼而有之。
- 在
development
模式下,您通常会使用完美集成的webpack-dev-server
提供所有服务。- 注意:在
production
模式下,您需要对配置进行一些小的调整。当webpack-dev-server
不在画面中时,您的构建只是将一些额外的remoteEntry.js
文件添加到构建输出中。
- 注意:在
- 您可以使用
shared
配置轻松配置如何处理常见依赖项。 (通常你希望他们作为单身人士,意思是,每个人都应该共享共同的依赖,而不是打包他们自己的。) - 如果你想坚持把所有东西都放在一个包裹里,那大概也是可以的。只是
expose
它并将它自己的(独立的)组件添加到它自己的remotes
。不确定它是否有效,但值得一试。
最后的话
同样,这需要一些学习曲线,但我发现它绝对值得。感觉像是我见过的最复杂的动态构建 + 加载系统之一。
最烦人的是,WMF 目前在 Webpack 页面上仍然没有适当的 API 文档,但我相信它很快就会出现。目前,只有一个不太完美的collection of conceptual notes。
WMF作者本人promises to provide better documentation soon™️.
幸运的是,对于学习,the samples 非常好,积极维护并且仍在增强。