NextJS 和组件库使用样式组件,没有正确保湿

问题描述 投票:0回答:2

我正在尝试为新的 nextJS 应用程序构建一个组件库。 nextJS 应用程序有“应用程序路由器”。

Styled-components我使用的时候工作正常,直接集成在nextJS代码中,当我想使用组件库时出现问题,我在旁边。

我做了 nextJS 推荐的所有内容,我在 next.config.js 中设置了以下内容

/** @type {import('next').NextConfig} */
const nextConfig = {
  compiler: {
    styledComponents: {
      // Enabled by default.
      cssProp: true,
    },
  },
}

module.exports = nextConfig

我还根据 nextJS 定义添加了“StyledComponentsRegistry”。

我已经配置了该库,以便它是使用汇总构建的。

首先,我尝试将样式组件保留为peerDependency,并将其添加为汇总中的“外部”。那不起作用(它在浏览器中工作正常,因为客户端代码工作正常,但在生成页面时它在控制台中给了我一个错误。它基本上给了我以下错误,因为 webpack 无法包含样式组件库

styled_components__webpack_imported_module_0__ is not a function
)

因此,我尝试将样式组件作为直接依赖项包含在内,并修改了 StyledComponentsRegistry,以包含样式组件库的版本。就像下面这样:

'use client';
 
import React, { useState } from 'react';
import { useServerInsertedHTML } from 'next/navigation';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
import { StyledComponentsServerStyleSheet, StyledComponentsStyleSheetManager } from 'skafte-cms';
 
export default function StyledComponentsRegistry({
  children,
}) {
  // Only create stylesheet once with lazy initial state
  // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
  const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
  const [cmsStyledComponentsStyleSheet] = useState(() => new StyledComponentsServerStyleSheet());
 
  useServerInsertedHTML(() => {
    const styles = styledComponentsStyleSheet.getStyleElement();
    styledComponentsStyleSheet.instance.clearTag();
    const cmsStyles = cmsStyledComponentsStyleSheet.getStyleElement();
    cmsStyledComponentsStyleSheet.instance.clearTag();
    return <>{styles}{cmsStyles}</>;
  });
 
  if (typeof window !== 'undefined') return <>{children}</>;
 
  return (
    <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
      <StyledComponentsStyleSheetManager sheet={cmsStyledComponentsStyleSheet.instance}>
        {children}
      </StyledComponentsStyleSheetManager>
    </StyleSheetManager>
  );
}

这确实有效,但是当我加载页面时,我在控制台中收到错误,告诉我样式组件没有正确水合(它只维护基于文件位置的类,而不是短类) -负责样式的标识符)

如有任何帮助,我们将不胜感激

reactjs next.js styled-components rollup
2个回答
0
投票

要在 NextJs 中充分使用样式组件,您需要:

  • 配置 next.config.js 或添加 Babel 中的配置(根据您的情况选择更佳)
module.exports = {
  compiler: {
    styledComponents: {
      // Enable display of the component name along with the generated className (needed for debugging).
      displayName: true,
      // Enable SSR support
      ssr: true,
      // Optional
      fileName: false,
    },
  },
}

// babel.config.js

module.exports = {
  plugins: [
    [
      "babel-plugin-styled-components",
      {
        displayName: true,
        fileName: false,
        ssr: true,
      },
    ],
  ],
};
  • styled-components
    包安装在您的库中作为peerDependency (
    yarn add styled-components --peer
    )。
  • 在 Rollup 配置中,使用
    rollup-plugin-peer-deps-external
    插件,它将自动从包中排除在库的 package.json 中指定为peerDependency 的依赖项。
  • 将 Babel 集成插件添加到 Rollup 配置中,并在库的根目录中创建一个
    babel.config.js
    文件,其内容类似于上面演示的内容。
  • 这是因为您在应用程序级别设置的配置仅适用于在应用程序本身内创建的组件。来自外部库的代码将无法正确处理。因此,您需要将新的 Babel 配置直接添加到库中,以便在构建 Rollup 时,
    babel-plugin-styled-components
    插件将进行必要的更改。

该库必须使用 babel-plugin-styled-components 插件,因为它将添加 withConfig 函数以及开发过程中轻松调试所需的设置和 SSR 支持,因此不存在水合作用问题。

例如(输出包):

var StyledView = styled.div.withConfig({
  displayName: "StyledView",
  componentId: "sc-10aexlr-0"
})({
  padding: 10,
  border: "1px solid teal"
});

0
投票

我遇到了同样的问题,设置与上面相同,但我收到错误消息说我需要添加“使用客户端”。理想情况下,这将使用 SSR 进行渲染,但出于某种原因,无论我尝试什么,它都不会在 NextJS 存储库的页面顶部使用“使用客户端”进行渲染。

我可以在捆绑的组件中看到 withConfig 函数,但仍然什么也没有。

任何指点将不胜感激

© www.soinside.com 2019 - 2024. All rights reserved.