TurboRepo外部组件在NextJS中样式不生效问题及解决方案
TurboRepo Monorepo组件样式在Next.js构建后失效问题及解决方案
我用TurboRepo管理的monorepo中维护了一系列可独立发布、版本化的原子组件包。这些组件在内部使用时一切正常,但作为外部包导入Next.js应用(/apps/web)并完成构建后,组件样式完全无法生效。
示例组件(Button)
Button组件包包含Button.tsx和Button.module.scss文件,组件代码如下:
import styles from './Button.module.scss'; const Button = forwardRef<HTMLButtonElement, ButtonProps>( ( { className, ...restProps }, ref ) => { return ( <button className={styles.base} ref={ref} {...restProps}> ... </button> ); } );
组件包Vite配置(vite.config.js)
import path from 'path'; import react from '@vitejs/plugin-react'; import { defineConfig } from 'vite'; import dts from 'vite-plugin-dts'; export default defineConfig({ build: { minify: 'terser', lib: { formats: ['es', 'cjs'], entry: path.resolve(__dirname, 'src/index.ts'), name: 'Button', fileName: format => `button.${format}.js`, }, rollupOptions: { // externalize deps that shouldn't be bundled // into your library external: ['react', 'react-dom'], output: { exports: 'named', sourcemap: true, format: 'es', preserveModules: true, }, treeshake: true, }, }, plugins: [ react(), dts({ copyDtsFiles: true, exclude: ['**/node_modules'], insertTypesEntry: true, }), ], });
组件包package.json配置片段
{ "name": "@company/components__button", "version": "0.0.1", "types": "./dist/index.d.ts", "exports": { ".": { "import": "./dist/button.es.js", "require": "./dist/button.cjs.js" } }, "files": ["dist/**"] }
问题现象
在Next.js应用中通过"@company/components__button": "workspace:*"导入组件后,运行时组件DOM节点能正常显示生成的类名(例如<button class="_base_3rp5a_4" type="submit">create an account</button>),但页面返回的CSS中仅包含Next.js应用自身的样式,组件包的样式完全未被纳入。我已经遵循TurboRepo官方打包指南操作,但问题仍未解决,想确认是配置遗漏还是Next.js无法处理动态类名关联的样式?
最终解决方案
- 创建
@company/components__css包,通过脚本从各组件包的dist目录获取生成的style.css文件 - 在该CSS包的package.json中添加所有组件包作为依赖,确保TurboRepo按以下顺序构建:
- 先构建所有组件包,在其dist目录生成对应的CSS文件
- 再构建CSS包,合并所有组件的CSS生成自身的index.css,并在monorepo环境下移除组件包dist中的style.css
- 在Next.js应用中添加该CSS包依赖,并在globals.scss中通过
@import url('@company/components__css');导入全局样式,组件样式即可正常生效
内容的提问来源于stack exchange,提问作者ShakurOo
相关产品推荐
相关产品推荐

