如何在Rollup和Next.js中使用styled-components - 未导入CSS

3
我从公司内部的组件库中导入组件。
组件库使用rollup。

rollup.config.mjs

import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import resolve from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';
import dts from 'rollup-plugin-dts';
import peerDepsExternalPlugin from 'rollup-plugin-peer-deps-external';
import postcss from 'rollup-plugin-postcss';
import { babel } from '@rollup/plugin-babel';
import { createRequire } from 'node:module';
const requireFile = createRequire(import.meta.url);
const packageJson = requireFile('./package.json');

export default [
  {
    input: 'src/index.ts',
    output: [
      {
        file: packageJson.main,
        format: 'cjs',
        sourcemap: true,
      },
      {
        file: packageJson.module,
        format: 'esm',
        sourcemap: true,
      },
    ],

    plugins: [
      babel({ babelHelpers: 'bundled' }),
      resolve(),
      commonjs(),
      typescript({
        exclude: ['**/tests/', '**/stories/'],
      }),
      json(),
      postcss({
        extensions: ['.css'],
      }),
      peerDepsExternalPlugin(),
    ],
  },
  {
    input: 'dist/index.d.ts',
    output: [{ file: 'dist/index.d.ts', format: 'es' }],
    plugins: [dts()],
    // not sure we want this (external) option here
    external: [/\.css$/]
  },
];


然后我构建它。
从nextjs应用程序中,我在package json中有它。使用yarn link将两个仓库链接在一起(我知道yarn link是有效的)。
但是我的组件库没有将任何样式传递给我的next js应用程序。
我尝试将我的next.config.js更改为这样,但没有任何效果。
/** @type {import('next').NextConfig} */
module.exports = {
  reactStrictMode: false,
  compiler: {
    styledComponents: {
      // Enabled by default.
      cssProp: true,
    },
  },
};

这是我的 .babelrc
{
  "plugins": ["babel-plugin-styled-components"]
}

任何帮助在这里都将是难以置信的。
1个回答

3
这种通过内联样式标签将CSS注入到生成的JavaScript中的方法在Next.js中不起作用,因为它生成了两个编译版本,即服务器端和客户端代码。想象一下,你的库中有一个简单的组件:
import React from 'react';

import style from './style.css';

export function MyComponent() {
  return (
    <div className={style.root}>
      <p>Hello world</p>
    </div>
  )
}

而且,你的CSS文件是这样的:
/* style.css */
.root {
  display: flex;
  font-size: 48px;
}

然后,Rollup生成的捆绑文件将是:
import React from 'react';

// Very simplified version.
function styleInject(css) {

  var head = document.head || document.getElementsByTagName('head')[0];
  var style = document.createElement('style');
  
  style.styleSheet.cssText = css;

  head.appendChild(style);
}

// Side effects (These won't be included in the client-side bundle)
var css_248z = ".root {\n  display: flex;\n  font-size: 48px;\n}\n";
styleInject(css_248z);

function MyComponent() {
  return React.createElement(
    "div",
    { className: css_248z.root },
    React.createElement("p", null, "Hello world")
  );
}

export { MyComponent };

问题在于Next.js不会在客户端捆绑包中包含styleInject函数,而在服务器端运行此代码是没有意义的。
因此,唯一的方法是实际上为您的库生成/发出一个独立的CSS文件,然后将其包含在您的Next.js应用程序中。像这样更改rollup-plugin-postcss配置:
postcss({
  // Extract the CSS into a standalone file.
  extract: true,
  // You will have to use CSS Modules.
  modules: true,
  extensions: ['.css'],
}),

这将生成一个名为index.css的文件:
/* Name mangled */
.style_root__WnIqm {
  display: flex;
  font-size: 48px;
}

而且,捆绑的JS代码将简单地引用这个CSS类,让应用程序开发者确保CSS被正确注入。
// Bundled JS File by the Rollup after extraction
import React from 'react';

var style = { "root": "style_root__WnIqm" };

function MyComponent() {
  return React.createElement(
    "div",
    { className: style.root },
    React.createElement("p", null, "Hello world")
  );
}

export { MyComponent };

最后,在你的Next.js应用程序布局文件`src/app/layout.jsx`或`tsx`文件中,你可以导入这个CSS:
import './globals.css';

// IMPORTANT: Library import CSS
import 'my-awesome-library/index.css';

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}


你能分享一个包含这个可用版本的代码库吗? - undefined
1
@Mathiasfc,我可以花一些时间。我会看看我能否在周末完成这个任务! - undefined
1
我对一个可用的代码库也很感兴趣。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接