Rollup+Babel无法转译css prop为styled component问题求助
我正在开发一个面向npm的React组件库,技术栈包含React、TypeScript、styled-components,采用Babel和Rollup进行构建。当前遇到的问题是:使用css prop给原生元素添加样式时,样式未被正确转译;但通过styled.span这类包装组件的写法可以正常工作。在普通React应用中css prop功能正常,因为Babel插件会自动转译带css prop的元素,但在Rollup+Babel的构建流程中该功能失效。
以下是针对性的修复步骤:
1. 修正Babel插件配置的语法错误
你的Rollup配置中,Babel插件数组错误地将@babel/plugin-transform-runtime嵌套在了babel-plugin-styled-components的配置数组内,导致插件无法正常加载。同时移除重复的react-app预设,避免冲突:
babel({ babelHelpers: 'runtime', plugins: [ [ 'babel-plugin-styled-components', { namespace: 'react-ui', displayName: true, fileName: true, transpileTemplateLiterals: true, ssr: false, }, ], "@babel/plugin-transform-runtime" // 单独声明插件 ], presets: ['@babel/preset-react', '@babel/preset-typescript'], extensions: ['.js', '.jsx', '.ts', '.tsx'], exclude: 'node_modules/**', }),
2. 调整Rollup插件顺序并清理重复项
Rollup插件按顺序执行,需确保typescript插件在babel之前运行,同时移除重复引入的peerDepsExternal插件,修正postcss插件的错误配置:
plugins: [ peerDepsExternal(), resolve({ browser: true }), commonjs({ include: 'node_modules/**' }), typescript({ tsconfig: './tsconfig.json', typescript: typescriptEngine, sourceMap: true, exclude: [ 'coverage', '.storybook', 'storybook-static', 'config', 'dist', 'node_modules/**', '*.cjs', '*.mjs', '**/__snapshots__/*', '**/__tests__', '**/*.test.js+(|x)', '**/*.test.ts+(|x)', '**/*.mdx', '**/*.story.ts+(|x)', '**/*.story.js+(|x)', '**/*.stories.ts+(|x)', '**/*.stories.js+(|x)', 'setupTests.ts', 'vitest.config.ts', ], }), babel({ // 上述修正后的Babel配置 }), postcss({ minimize: true, // 移除plugins中的'babel-plugin-styled-components',postcss仅支持postcss生态插件 }), ],
3. 更新TypeScript的JSX转换配置
旧的react JSX模式不支持styled-components css prop的自动转译,需切换到新的自动JSX运行时:
{ "compilerOptions": { // ...其他配置 "jsx": "react-jsx" // 替换原有的"react" } }
4. 简化构建命令避免重复处理
原build命令存在多次重复编译的问题,直接使用Rollup的typescript插件处理TypeScript即可:
"scripts": { "build": "rimraf dist && rollup -c --bundleConfigAsCjs" },
5. 清理无用依赖
babel-plugin-css-prop属于冗余依赖,styled-components的css prop转译已由babel-plugin-styled-components处理,可直接卸载该包。
完成以上修改后,重新执行构建命令,css prop即可被正确转译。
内容的提问来源于stack exchange,提问作者Tottzi

