【问题标题】:SSR with Lerna + React + Styled components带有 Lerna + React + Styled 组件的 SSR
【发布时间】:2021-07-31 21:29:52
【问题描述】:

我尝试使用 Lerna 及其 hoist 功能构建项目。一切都很好,在我决定将 ui 组件从 site 移动到 packages 之前,以供重用。

我有这样的文件结构

root
├── node_modules
└── packages
    ├── admin
    ├── site
    └── ui

其中uireact + styled-components 组件库,它在site 中用作依赖项

// site packages.json
...,
"dependencies": {
  ...,
  "@root/ui": "^1.0.0"
}

ui只有一个文件index.tsx

import React, { FC } from "react";
import styled from "styled-components";

const SharedComponent: FC = () => {
  return (
    <Wrapper>Hello from SharedComponent</Wrapper>
  );
};

const Wrapper= styled.div`
  color: red;
`;

export default SharedComponent;

然后我使用 tsc 编译 tsx

尝试在site中使用它

import React, { FC  } from 'react';
import SharedComponentfrom '@root/ui/dist';

const App: FC = () => {
    return (
            <>
                <SharedComponent />
                <div>Hello from Site App</div>
            </>
    );
};

export default App;

所以如果我启动 devServer 一切正常。

但是当我尝试 SSR 时,我得到了服务器端错误

UnhandledPromiseRejectionWarning: Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

我尝试在wepback 设置中声明alias 属性,如此处所述https://github.com/facebook/react/issues/14257#issuecomment-508808246

// site webpack.config.js
module.exports = {
  ...,
  resolve: {
    ...,
    alias: {
      react: path.resolve('../../node_modules/react') // path to root node_modules
    }
  },
}

但错误仍然存​​在

另外,如果我从ui 中删除styled-components,它工作正常。似乎问题出在styled-components

那么,我该如何配对lerna + styled-components + react + SSR

【问题讨论】:

  • 我最好的猜测是你的自定义 ui 库和这个设置有冲突的 React 版本。
  • @serraosays 感谢您的回复。正如我所提到的,只有当我使用styled-components 时才会出现问题。如果ui 中只有react,则可以正常工作。

标签: reactjs webpack styled-components server-side-rendering lerna


【解决方案1】:

我设法让它工作。我需要做的就是在 webpack 配置中设置 externals 字段。像这样:

externals: [
        nodeExternals(),
        nodeExternals({ additionalModuleDirs: [path.resolve(__dirname, '../../node_modules')] }),
        'express'
]

【讨论】:

    【解决方案2】:
    1. 尝试使用 dangerouseInnerHtml 来解决 css 问题。否则如果你使用 emtion.css 那么你可以试试@emotion/server

    2. 尝试使用 next/dynamic 或 React.lazy 加载动态

    3. 我仍然对重复的 React 感到困惑。如何解决这个问题。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2018-04-27
    • 2021-05-01
    • 2017-11-18
    • 1970-01-01
    • 2019-04-19
    • 2020-11-03
    • 2021-04-30
    • 2018-02-01
    • 1970-01-01
    相关资源
    最近更新 更多