当前位置: 首页 > Web前端 > HTML

设置NPMRegistry的4个姿势

时间:2023-03-27 22:52:09 HTML

前言前段时间,由于团队使用的monorepo项目是Lerna,所以就在思考如何改造。最终整体技术选择为PNPM+Changeset+Turborepo。相应的,在本次选型的背景下,也需要支持原来使用的Lerna的能力。其中,比较有意思的是需要将Package发布到私有Registry。因为这里选择了Changeset,所以最终执行发布的命令会是:pnpmchangesetpublish这时候就涉及到一个问题,项目中的私有Registry应该配置在哪里呢?这里我们也不急于寻找答案,先来了解一下配置私有注册中心的4个姿势。1全局注册表我们可以通过设置npm或者pnpmconfig来设置全局注册表,例如:#npmnpmconfigsetregistry=http://localhost:2000#或者pnpmpnpmconfigsetregistry=http://localhost:2000这样,在代码层面,可以通过process.env.npm_config_registry读取这里的配置。2.npmrc无论是npm还是pnpm,默认都会从项目的.npmrc文件中读取配置,所以当我们需要发布包走私私有Registry时,可以这样设置:registry=http://localhost:20003--当registry执行npmpublish或pnpmpublish时,我们也可以使用--registry选项告诉相应的包管理工具用什么Registry来发布包,例如:#npmnpmpublish--registry=http://localhost:2000#orpnpmpnpmpublish--registry=http://localhost:20004PublishConfigPublishConfig指的是我们要执行publish命令的项目package.json中的publishConfig.registry,通知Registry的npm或pnpm发布,例如:{..."publishConfig":{"registry":"http://localhost:2000"}...}5Changesetpublish的原理在了解了设置私有Registry的四种姿势后,我们回到文章开头的这个问题,如何让pnpmchangesetpublish知道将包发布到指定的私有Registry吗?如果你认为你可以选择以上4种类型中的一种,那么你可能需要踩一些坑。首先,我们需要知道的是,pnpmchangesetpublish命令的本质是执行变更集的发布。那么,也就是上面4种设置Registry的方式,很可能不会全部生效,因为Changeset有自己的publish机制。在这个过程中,它主要会做这三件事:1.首先,获取PackageInfo,它会从指定的Registry中获取PackageInfo。例如,如果要获取rollup的PackageInfo,它将如下所示:npminforollup--registry="https://registry.npmjs.org/"--json2。其次,根据上面得到的PackageInfo中的versions字段(是一个包含所有发布版本的数组),对比本地package.json的version字段,判断当前版本是否已经发布3.最后,如果当前version没有发布,它会根据当前使用的包管理工具执行publish命令,此时会构造一个它认为应该发布的Registry地址,然后重写env上的配置。相应的代码将是这样的://packages/cli/src/commands/publish/npm-utilsconstenvOverride={npm_config_registry:getCorrectRegistry()};let{code,stdout,stderr}=awaitspawn(//动态包管理工具,例如pnpm、npm、yarnpublishTool.name,["publish",opts.cwd,"--json",...publishFlags],{env:Object.assign({},process.env,envOverride)});可以看到,整个变更集发布过程还是非常简单易懂的。并且,非常重要的是,这个过程涉及通过一个名为getCorrectRegistry()的函数获取Registry,它的定义将是这样的://packages/cli/src/commands/publish/npm-utils。tsfunctiongetCorrectRegistry(packageJson?:PackageJSON):string{constregistry=packageJson?.publishConfig?.registry??process.env.npm_config_registry;返回!注册表||注册表===“https://registry.yarnpkg.com”?"https://registry.npmjs.org":registry;}这样看了之后,我想大家明白为什么上面提到的4种设置Registry的方式不是都有效了。因为Changeset中只支持publishConfig或者env配置Registry,如果你尝试其他两种方式,它会发布到https://registry.yarnpkg.com或者https://registry.npmjs.org,而在第一步获取包信息可能会失败。结语我觉得文章很短,但是传达的知识点还是挺有意思的。至于上面提到的PNPM+Changeset+Turborepo技术选型,至少目前我体验还是很流畅的,无论是依赖安装,多包任务执行,Version还是Publish等方面都非常出色。所以,有兴趣同学们可以试一试。最后,如果文中有任何不当或表达错误的地方,欢迎各位同学提Issue~喜欢通过阅读本文,有收获,点个赞,这会成为我继续分享的动力,谢谢~我是五六,喜欢创新和捣鼓源码,专注于源码(Vue3、Vite)、前端工程、跨端技术的学习和分享,欢迎关注我的微信公众号代码中心或GitHub。