For AI agents: the complete documentation index is available at /next/zh/llms.txt, the full documentation bundle is available at /next/zh/llms-full.txt, and this page is available as Markdown at /next/zh/react/code-splitting.md.
  • 简体中文
  • 代码拆分

    Rspack 支持代码分割特性,允许让你对代码进行分割,控制生成的资源体积和资源数量来获取资源加载性能的提升。

    Rspack - 代码分割

    懒加载组件

    通常,我们使用静态 import 来导入组件:

    import LazyComponent from './LazyComponent.jsx';
    
    export function App() {
      return (
        <view>
          <LazyComponent />
        </view>
      );
    }

    如果要将“加载组件代码”延迟至该组件被渲染时,可以将此 import 替换为:

    - import LazyComponent from './LazyComponent.jsx'
    + import { lazy } from '@lynx-js/react'
    + const LazyComponent = lazy(() => import('./LazyComponent.jsx'))

    此代码依赖于动态 import()。使用此模式要求导入的懒加载组件必须作为默认导出(Default Export)进行导出。

    现在,由于你的组件代码按需加载,你还需要指定在加载期间应显示的内容。你可以通过将懒加载组件或其任何父组件包装在 <Suspense> 边界中来实现这一点:

    src/App.tsx
    import { Suspense, lazy } from '@lynx-js/react';
    
    const LazyComponent = lazy(() => import('./LazyComponent.jsx'));
    
    export function App() {
      return (
        <view>
          <Suspense fallback={<text>Loading...</text>}>
            <LazyComponent />
          </Suspense>
        </view>
      );
    }

    按需懒加载

    在此示例中,LazyComponent 的代码在尝试渲染它之前不会被加载。如果 LazyComponent 尚未加载,则会在其位置显示“Loading...”。例如:

    src/App.tsx
    import { Suspense, lazy, useState } from '@lynx-js/react';
    
    const LazyComponent = lazy(() => import('./LazyComponent.jsx'));
    
    export function App() {
      const [shouldDisplay, setShouldDisplay] = useState(false);
      const handleClick = () => {
        setShouldDisplay(true);
      };
      return (
        <view>
          <view bindtap={handleClick}>Load Component</view>
          {shouldDisplay && (
            <Suspense fallback={<text>Loading...</text>}>
              <LazyComponent />
            </Suspense>
          )}
        </view>
      );
    }
    与 Web 的区别

    在 Lynx 中,CSS 的作用域限定于每个 Bundle。由于懒加载组件会生成自己的 Bundle(请参阅构建输出文件的输出结构),因此它们的行为与 Web 上的有所不同。主 Bundle 中定义的全局 CSS 不会影响懒加载组件,反之亦然。

    错误处理

    使用 ErrorBoundary

    如果加载完成,懒加载组件本质上也是一个 React 组件,因此 React 中的错误处理实践仍然适用。

    细节请参考 React - Catching rendering errors with an error boundary

    懒加载独立项目

    你还可以延迟加载在独立的 Rspeedy 项目中构建的模块。

    术语表

    • 生产者:一个向其他 Lynx 应用程序提供模块以供使用的应用程序。
    • 消费者:一个从其他生产者中消费模块的应用程序。

    创建一个独立的生产者项目

    使用 create-rspeedy 创建一个独立项目:

    pnpm create rspeedy@latest

    lynx.config.js 中将 pluginReactLynxexperimental_isLazyBundle 选项设置为 true

    import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin';
    import { defineConfig } from '@lynx-js/rspeedy';
    
    export default defineConfig({
      source: {
        entry: './src/index.tsx',
      },
      plugins: [
        pluginReactLynx({
          experimental_isLazyBundle: true,
        }),
      ],
    });

    最后修改 src/index.tsx 来导出 App 组件:

    src/index.tsx
    import { App } from './App.jsx';
    
    export default App;

    修改消费者项目

    要加载 Producer 项目,请在入口的开头添加对 @lynx-js/react/experimental/lazy/import 的导入:

    src/index.tsx
    import '@lynx-js/react/experimental/lazy/import';
    import { root } from '@lynx-js/react';
    
    import { App } from './App.jsx';
    
    root.render(<App />);

    这将提供生产者所需的基本 API。

    然后,可以使用动态 import() 加载生产者:

    src/App.tsx
    import { Suspense, lazy } from '@lynx-js/react';
    
    const LazyComponent = lazy(
      () =>
        import('https://<host>:<port>/path/to/[name]lynx.bundle', {
          with: { type: 'component' },
        }),
    );
    
    export function App() {
      return (
        <view>
          <Suspense fallback={<text>Loading...</text>}>
            <LazyComponent />
          </Suspense>
        </view>
      );
    }

    开发生产者项目

    建议在生产者项目中创建一个单独的消费者入口:

    src/Consumer.tsx
    import { Suspense, lazy, root } from '@lynx-js/react';
    
    // You may use static import if you want
    const App = lazy(() => import('./App.jsx'));
    
    root.render(
      <Suspense>
        <App />
      </Suspense>,
    );

    然后,创建一个单独的 lynx.config.consumer.js

    lynx.config.consumer.js
    import { pluginReactLynx } from '@lynx-js/react-rsbuild-plugin';
    import { defineConfig } from '@lynx-js/rspeedy';
    
    export default defineConfig({
      source: {
        entry: './src/Consumer.tsx',
      },
      plugins: [pluginReactLynx()],
    });

    使用 npx rspeedy dev --config lynx.config.consumer.js 来开始开发生产者项目。

    懒加载 bundle 的加载器

    懒加载 bundle 有两种加载方式,用哪一种在构建期决定,并通过 __LAZY_BUNDLE_FETCHER__ 宏暴露给你的代码。

    加载器拉取方式
    FetchBundlelynx.fetchBundle,以及 import(..., { with: { mode } }) 提示
    QueryComponent旧的 lynx.QueryComponent 路径

    默认取值跟随 engineVersion3.9 及以上为 FetchBundle,否则为 QueryComponentengineVersion 默认是 3.2,因此未把它调高到 3.9 的构建会使用 QueryComponent

    环境变量 REACT_LAZY_BUNDLE_FETCHER 可以覆盖这个选择:

    REACT_LAZY_BUNDLE_FETCHER=QueryComponent rspeedy build
    • QueryComponent:即使 engineVersion 已经是 3.9 及以上,也强制走旧加载器。
    • FetchBundle:只有在 engineVersion3.9 及以上时才接受。声明的版本更低时构建会直接报错,因为旧宿主没有 lynx.fetchBundle / lynx.loadScript
    • 其他取值会被忽略,回落到由 engineVersion 推导出的结果。
    版本范围

    FetchBundle 加载器和上述选择逻辑从 @lynx-js/react@0.123.0 / @lynx-js/react-rsbuild-plugin@0.18.0 起提供,这两个包同步发布。更早的版本一律使用 QueryComponent

    除非另有说明,本项目采用知识共享署名 4.0 国际许可协议进行许可,代码示例采用 Apache License 2.0 许可协议进行许可。