Hyperapp/Webpack - 如何编码拆分组件 [英] Hyperapp / Webpack - How to code split component

查看:23
本文介绍了Hyperapp/Webpack - 如何编码拆分组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了减少我的应用程序的初始负载,我尝试进行代码拆分.例如,我成功地拆分了 twilio-video,以便在用户按下呼叫"时加载和初始化

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 让它喘不过气来.

他们有大量示例来帮助您入门.>

例如,基本-主机远程示例 有一个适合您需要的简单场景.只需将整个 Github 存储库、cd 提取到此示例中,然后运行它(如每个示例的 README 中所述).

留意网络标签.组件在明确请求之前不会加载.

基本示例

basic-host-remotesample 有两个独立的包:app1app2.

  1. app1 想使用 app2
  2. 的组件

  1. app2 提供了一个 Button 组件

  1. app1/src/App.js 动态加载按钮.(它在初始渲染期间这样做,使得按需加载不那么明显.)
  2. 时机成熟时,app1 使用动态 import 请求组件.
  3. 它使用 React.lazy 包装负载,如下所示:

    const RemoteButton = React.lazy(() => import(app2/Button"));

    • 例如,您可以在 useEffectRoute.render 回调等中执行此操作.
  4. app1 可以使用该 Button,一旦它被加载.加载时,它使用 Suspense 显示加载消息:

    <React.Suspense fallback={<LoadingScreen/>}><远程按钮/></React.Suspense>

  • 或者,您可以不使用 lazySuspense,而是使用 import(...) 语句返回的承诺,然后以您喜欢的任何方式处理异步加载.当然,WMF 完全不限于react,可以动态加载任何模块.
  • 请注意,app1app2 具有相同的 shared 设置,确保这些共享依赖项仅加载一次,并且未与远程加载的代码捆绑/复制:

    {//...共享:{反应:{单例:真},反应DOM":{单例:真}},}

另一方面,WMF动态加载必须使用动态import(即import(...)),因为:>

  1. 非动态导入将始终在加载时解析(因此使其成为非动态依赖项),并且
  2. "动态require"不能被 webpack 捆绑,因为浏览器没有 commonjs 的概念(除非你使用了一些 hacks,在这种情况下,你将失去相关的加载 promise").

WMF 示例

WMF 需要一些学习,但它的所有样本都具有以下共同元素:

  1. 每个示例都有多个独立的包.
  2. 每个包都有自己的webpack.config.js
  3. 每个包通常充当主机(动态提供组件)或此类组件的使用者,或两者兼而有之.
  4. development 模式下,您通常使用集成良好的webpack-dev-server 提供所有内容.
    • 注意:在 production 模式下,您需要对配置进行一些小的调整.当 webpack-dev-server 不在画面中时,您的构建只会在构建输出中添加一些额外的 remoteEntry.js 文件.
  5. 您可以使用 shared 配置轻松配置如何处理公共依赖项.(通常您希望它们充当单例,这意味着每个人都应该共享公共依赖项,而不是打包自己的依赖项.)
  6. 如果你想坚持把所有东西都放在一个包里,那可能也是可能的.只需公开它并将它自己的(独立的)组件添加到它自己的遥控器.不确定它是否有效,但值得一试.

最后的话

同样,这需要一点学习曲线,但我发现这绝对值得.感觉就像我见过的最复杂的动态构建 + 加载系统之一.

最烦人的是,WMF 目前在 Webpack 页面上仍然没有适当的 API 文档,但我相信它很快就会出现.目前,只有一个不太完善的概念笔记集..>

WMF 作者本人 承诺提供很快就会有更好的文档™️.

幸运的是,对于学习,示例真的很好,很积极保持并仍在增强.

To reduce the initial load of my app, i try to do code splitting. For exemple, i successfully split twilio-video, to load and initialize when user press "call"

import('twilio-video').then(Video => {
    Video.connect(twilioInfo.data.token, options).then(room => {
        ...
    });
});

Webpack correctly split the code and load it when needed.

Now i would like to do the same with components, or routes (to not load user profil while we stand on login page). Is there any equivalent of

const OtherComponent = React.lazy(() => import('./OtherComponent'));

or

const Home = lazy(() => import('./routes/Home'));

or any other way to load component when a route path is hitted?

解决方案

It used to be very difficult. These days, Webpack Module Federation makes it a breathe.

They have tons of samples to get you started.

For example, the basic-host-remote sample has a simple scenario that fits your need. Just fetch the entire Github repo, cd into this sample, and run it (as explained in each sample's README).

Keep an eye open for the Network tab. Components are not loaded until they are explicitely requested.

Basic Example

The basic-host-remote sample has two separate packages: app1 and app2.

  1. app1 wants to use components from app2

  1. app2 provides a Button component

  1. app1/src/App.js loads the button dynamically. (It does so during initial render, making the on-demand loading a lot less obvious.)
  2. When the time comes, app1 requests a component using dynamic import.
  3. It wraps the load using React.lazy, like so:

    const RemoteButton = React.lazy(() => import("app2/Button"));
    

    • E.g., you can do this in a useEffect, or a Route.render callback etc.
  4. app1 can use that Button, once it's loaded. While loading, it shows a loading message, using Suspense:

    <React.Suspense fallback={<LoadingScreen />}>
      <RemoteButton />
    </React.Suspense>
    

  • Alternatively, instead of using lazy and Suspense, you can just take the promise returned from the import(...) statement and handle the asynchronous loading any way you prefer. Of course, WMF is not at all restricted to react and can load any module dynamically.
  • Note that both, app1 and app2 have the same shared setup, making sure that those shared dependencies are only loaded one time, and not bundled/duplicated with remotely loaded code:

    {
      // ...
      shared: { react: { singleton: true }, "react-dom": { singleton: true } },
    }
    

On the flip side, WMF dynamic loading must use dynamic import (i.e. import(...)), because:

  1. non-dynamic imports will always resolve at load time (thus making it a non-dynamic dependency), and
  2. "dynamic require" cannot be bundled by webpack since browsers have no concept of commonjs (unless you use some hacks, in which case, you will lose the relevant "loading promise").

WMF Samples

WMF takes a bit of learning, but all its samples have the following common elements:

  1. Every sample has multiple independent packages.
  2. Each package has its own webpack.config.js
  3. Each package usually acts as a host (which provides components dynamically) or a consumer of such components, or both.
  4. In development mode, you usually serve up everything using the nicely integrated webpack-dev-server.
    • NOTE: In production mode, you want to make some small adjustments to your config. When webpack-dev-server is out of the picture, your build just adds some additional remoteEntry.js files to your build output.
  5. You can easily configure what to do with common dependencies, using the shared configuration. (Usually you want them to act as singletons, meaning, everyone should share common dependencies, and not pack their own.)
  6. If you want to insist on keeping everything in one package, that is probably also possible. Just expose it and add its own (independent) components to its own remotes. Not sure if it works, but its worth trying.

Final Words

Again, it will take a bit of a learning curve, but I find it's definitely worth it. Feels like one of the most sophisticated dynamic build + load systems I have seen.

Most annoyingly, WMF still does not currently have proper API documentation on the Webpack page, but I'm sure it'll come soon enough. Currently, there is only a not all too polished collection of conceptual notes.

The WMF author himself promises to provide better documentation soon™️.

Luckily, for learning, the samples are really good, actively maintained and still being enhanced.

这篇关于Hyperapp/Webpack - 如何编码拆分组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆