Rollup打包React组件后,如何避免全局CSS模块被Webpack Tree Shaking剔除?
嘿,我遇到过几乎一模一样的问题!咱们先搞清楚为啥会这样:Webpack的Tree Shaking本质是剔除没有被直接引用的无副作用模块。你的应用是直接导入MyComponent,而不是从组件包的入口index.ts导入,Webpack就会觉得index.ts整个模块都没被用到——连它里面导入的全局CSS也被当成“无用代码”一起摇掉了。
给你几个靠谱的解决办法,按推荐程度排序:
1. 用package.json的sideEffects字段标记CSS为副作用
这是最稳妥、最符合规范的方案。在你的组件包(packages/test-css)的package.json里添加下面的配置:
"sideEffects": [ "*.css", "*.module.css" ]
Webpack会识别这个字段,知道这些CSS文件是有副作用的(毕竟注入样式到DOM是会改变页面的操作),哪怕它们所在的模块没被直接引用,也不会把它们摇掉。
2. 强制应用从组件入口文件导入组件
如果你的应用现在是直接导入myComponent.tsx(比如import MyComponent from 'test-css/src/myComponent'),改成从组件包的入口index.ts导入:
import { MyComponent } from 'test-css';
同时确保组件包的package.json里的main/module字段指向index.ts(或者打包后的入口文件)。这样Webpack会执行index.ts里的所有代码,自然就会加载全局CSS了。
3. 在Rollup配置里强化副作用保留
如果上面的方法还不行,可以在Rollup打包组件的时候,确保样式注入代码不会被标记为“纯函数”。在你的rollup.config.js里调整配置:
export default { // 其他配置... output: { // 确保输出的代码保留副作用标记 preserveModules: false, sourcemap: true, }, plugins: [ postcss({ // 确保样式注入逻辑被保留 inject: true, modules: { generateScopedName: '[name]__[local]___[hash:base64:5]', }, }), // 其他插件... ], };
这个方法主要是确保Rollup打包时,不会把样式注入的代码优化掉,让Webpack能正确识别到这些副作用。
另外说一下为啥你之前排除*.css.mjs没用:因为Webpack是先判断index.ts这个模块有没有被使用,它觉得index.ts没用,就直接跳过了这个模块里的所有导入,包括那些css.mjs文件,所以单独排除css.mjs根本没机会生效。
备注:内容来源于stack exchange,提问作者betabandido

