【问题标题】:Dynamically import components for static site generation动态导入组件以生成静态站点
【发布时间】:2021-09-29 16:29:57
【问题描述】:

我有一个动态页面树,每个页面都有自己的内容,使用不同的组件。

页面在构建时使用 Next.js 的静态站点生成进行静态预渲染。我使用以下组件来处理组件的数量:

import React from "react";
import { Data } from "../../types/data";
import { Block } from "../../css/content";

const componentList: Record<string, any> = {
    BlockA: require("../molecule/BlockA").BlockA,
    BlockB: require("../molecule/BlockB").BlockB,
    BlockC: require("../organism/BlockC").BlockC,
    BlockD: require("../molecule/BlockD").BlockD,
    BlockE: require("../organism/BlockE").BlockE,
    BlockF: require("../atom/BlockF").BlockF,
    BlockG: require("../organism/BlockG").BlockG,
    ...
};

interface TemplateProps {
    data: Data.Main;
    props?: any;
}

export const Template: React.FC<TemplateProps> = ({ data, props = {} }) => {
    return (
        <React.Fragment>
            {data.content.map((item, index) => {
                const Component = componentList[item.component.type];

                if (!Component) return null;

                return (
                    <Block key={index}>
                        <Component {...item.component} {...props} />
                    </Block>
                );
            })}
        </React.Fragment>
    );
};

这可以正常工作,但会导入所有块,即使特定页面不需要它们,也会增加第一次加载 js 的大小。如何防止这种情况发生并在构建时按需动态导入组件?

使用 next/dynamic 可以解决这个问题,但 AFAIK 会阻止组件被静态预渲染 - 我们不想错过这一点。

【问题讨论】:

  • 碰巧,你试过dynamic imports吗?
  • @YevgenGorbunkov 是的,但是 AFAIK 动态导入将在客户端进行,并且不会在构建时预渲染。
  • “动态导入将在客户端进行” - 只有在 next/dynamic 调用中传递 ssr: false 时才会如此。

标签: javascript reactjs typescript next.js


【解决方案1】:

你应该使用React.lazy

import React from "react";
import { Data } from "../../types/data";
import { Block } from "../../css/content";

const componentList: Record<string, any> = {
  BlockA: React.lazy(() => import("../molecule/BlockA").BlockA)
};

interface TemplateProps {
  data: Data.Main;
  props?: any;
}

export const Template: React.FC<TemplateProps> = ({ data, props = {} }) => {
  return (


    <React.Suspense fallback={<div>loading</div>}>

      {data.content.map((item, index) => {
        const Component = componentList[item.component.type];

        if (!Component) return null;

        return (
          <Block key={index}>
            <Component {...item.component} {...props} />
          </Block>
        );
      })}
    </React.Suspense>
  );
};

请记住,您需要使用React.lazy 和React.Suspense。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 2021-04-05
    • 1970-01-01
    • 2017-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多