如何去掉antd全局样式,给node_modules打补丁

1,376 阅读3分钟

背景

由于公司业务需要,需要新建一个npm包做部分业务功能开发,并引入了antd的部分组件,最后需要发布一个独立的npm包给使用方,并且希望打包的时候不要带上antd的全局样式,因为antd的全局样式会对使用方造成样式污染(前端主体技术栈用的vue,将react写的功能做成一个npm包嵌入到vue的页面后,如果带有antd的全局样式将会影响到vue的element ui的全局样式)。

分析

可以打开node_modules下的antd代码,找到样式文件入口如图 image.png

目录:/node_modules/antd/es/style/core/index.less ,可以看到这里import了一个全局的样式文件gloabl.less

image.png

这里面有一些覆盖全局的样式,有时候很烦人没法修改,如果能够在使用的时候直接去掉gloabl.less的引入是不是就不会有问题了?

解决

希望在打包的时候不要引入gloabl.less,这个时候就牵扯到了如何给node_modules打补丁的问题。 当然不直接在node_modules打补丁,自己搞一个antd的内部私有版本也是可行的,不过有一点绕,而且本来是一个很简单的操作,反而搞复杂了。

那打补丁有很多种方法,写个node脚本也可以做到。 在代码根目录建一个patch文件夹,新建一个compatible-antd.js文件,写入以下内容

/**
 * 屏蔽antd的全局样式,避免antd全局样式影响到使用方
 * https://github.com/fi3ework/blog/issues/44
 */
const fs = require('node:fs')
const path = require('node:path')

const antdEsStyleCoreIndex = path.resolve('./', './node_modules/antd/es/style/core/index.less')
let index = fs.readFileSync(antdEsStyleCoreIndex, 'utf-8')
index = index.replace(
	`@import 'global';`,
	`// @import 'global';`,
)
fs.writeFileSync(antdEsStyleCoreIndex, index)

然后在package.json的脚本里面添加一行

"postinstall": "node ./patch/compatible-antd.js",

image.png

那么在下次yarn或npm install的时候就会执行这个node脚本进行replace操作

这种方法弊端就在于要写脚本,且如果修改的地方比较多的时候,写起脚本来还是比较繁琐的

另外一种更合理的办法

patch-package来自动且优雅的管理你的补丁

  1. 首先 yarn add patch-package -D 安装一下patch-package

  2. 然后在你本地的/node_modules/antd/es/style/core/index.less里面手动将 @import 'global';删除掉

  3. 再执行yarn patch-package antd image.png

  4. 执行成功后会看到代码根目录多出来一个patches文件夹

image.png

  1. 同样在package.json的脚本里面添加一行"postinstall": "patch-package",即可

特别的点

由于前面讲到我需要将这个项目发布为一个独立的npm包,发布出去的构建结果里面不需要包含antd的全局样式,但开发过程中还是需要的。所以我是在prepublishOnly的时候进行打补丁,并且在publish完成之后进行回滚,所以用了--reverse

image.png

原理

patch-package的原理也非常简单,执行patch-package时会将当前node_modules下的源码与原始源码进行git diff,并在项目根目录下生成一个patch补丁文件,补丁文件包含了diff的内容,方便下次使用时进行打补丁操作

最后

前面讲到的关于“如何将react组件或页面嵌入到vue项目”,后续会作为一篇独立的文章发布出来,敬请期待哦~期待点赞收藏