如何在rollup和next.js中使用样式化组件- css未导入

fsi0uk1n  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(125)

我有从我的组件库导入到我的公司内部的组件。
组件库使用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应用程序中,我把它放在json包中。使用yarn link链接两个仓库(我知道yarn link是有效的)。
但是没有一个样式会通过我的组件库传递到我的下一个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"]
}

任何帮助都是不可思议的。

ia2d9nvy

ia2d9nvy1#

这种通过样式标签将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生成的bundle文件将是:

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.jsxtsx中,可以导入以下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>
  );
}

相关问题