使用 Lerna + React + Styled 组件的 SSR

SSR with Lerna + React + Styled components

我正在尝试使用 Lerna 及其 hoist 功能来构建 uild 项目。在我决定将 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

我成功了。我需要做的就是在 webpack 配置中设置 externals 字段。像这样:

externals: [
        nodeExternals(),
        nodeExternals({ additionalModuleDirs: [path.resolve(__dirname, '../../node_modules')] }),
        'express'
]
  1. 尝试使用 dangeraleInnerHtml 来解决css问题。否则如果你使用 emtion.css 那么你可以尝试 @emotion/server

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

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