本地调试npm包之npm link

我们在开发一个npm包的过程中,一般需要在另一个项目里先测试该包的功能是否达到预期。

但我们不太可能每次一改好代码就执行 npm publish 发布到 npm 仓库,所以 npm 给我们提供了 npm-link 这个命令来进行本地化开发调试。

它允许你将本地npm包链接到另一个项目,使得你可以在不发布到npm仓库的情况下,直接在其他项目中使用你的本地包。

背后原理

为方便表述,后文均假设你开发的包名为:js-tracker,需要使用的项目目录为 /examples

在你 my-pkg 的根目录通过 npm link 将该包注册为全局npm包,相当于你使用 npm install xxx -g。

但是js-tracker这个包跟其他全局npm包长得不太一样(如上图),它其实只是一个软连接(如下图),指向的其实是你刚执行npm link命令的目录。

在你需要使用js-tracker包的项目目录 /examples 执行 npm link js-tracker,相当于在 /examples/node_modules 目录中创建一个符号链接,软链接到全局npm目录中的js-tracker包。

基本用法

  1. 在你本地js-tracker包的根目录运行:
bash 复制代码
npm link

这会在全局的npm目录中创建一个符号链接,指向你的本地包。每次更新完你js-tracker包,都需要在包的根目录重新执行 npm link。

如果还没有生效,重启vscode 试试。

  1. 在需要使用这个本地包的项目根目录(/examples)运行:
bash 复制代码
npm link [package-name]

这里的package-name是你的npm包名,相当于刚我们说的js-tracker。

成功执行这两条命令,你就可以在 /examples 项目中直接使用你本地的js-tracker包来进行调试了。

当你对本地包做了更改后,只需在js-tracker包的根目录中运行一下npm link,/examples 项目中的包将自动更新,非常方便。

使用的注意点

虽然使用npm link并不难,主要是些理解成本,但还是有一些问题需要注意。

1. 不需要在package.json中填写相应的依赖项

你使用本地包的目录 /examples,无需在package.json中添加你本地调试包(js-tracker)的任何依赖。

因为前面原理中讲到了,你本地调试的包通过npm link其实已经是作为全局npm包了,所以无需你在自己项目去指定npm局部依赖。

如果你项目已经使用该包的依赖项来安装了,会运行报错,操作方法是:

  • 删除package.json的有关你包的依赖项
  • 删除node_modules文件夹
  • 执行npm link [your-package]
  • 最后再执行 npm i 来安装你的项目npm依赖

2. npm link异常报错

这个错误点击npm的错误日志进去看提示是操作权限不足,但实际上删除掉node_modules文件夹后,错误就解决了。

3. 本地调试发现 /lib/index.js 中没有抛出default变量

打包后正常发npm包引用没有问题,但是通过npm link的方式软链接引用我们npm包就报错如下:

仔细分析/lib/index.js,发现里面确实没有default导出。但改成import Tracker from "js-tracker/lib/index.mjs";就可以正常运行,说明很有可能我们指定的包入口文件不对。

经尝试,将我们包package.json指定的默认入口文件去掉文件后缀名即可正常运行。

因为去掉了后缀名,ESM的用法会自动去去找符合条件的mjs文件(/lib/index.mjs)。有兴趣的同学可以了解下ESM和CommonJs规范的区别。

还有一种方法,可以通过设置module字段来指定ESM方式所引用的入口文件:

json 复制代码
// package.json
{
    // ...
    "module": "lib/index.mjs",
}

调试完你要调试的 npm 包后,记得及时解除全局 link 软连接,不然后面你的包发上线了,你本地都获取不到最新的npm包代码。

解除方法是,在你的npm包目录(/js-tracker)执行:

bash 复制代码
npm unlink [package-name]

本地调试npm包的其他方式

除了npm link,本地调试npm包还有其他两种常见方式:

  1. npm install path/to/my-package (传送门
  2. 指定工作区间 workspaces

第1种其实比较好理解,就是npm安装的时候将你包的全路径(相对路径)给带上。

第2种是npm7以上才支持的workspaces特性,通过指定npm工作区间这种方式来实现调试本地npm包。

个人认为,第2种在前端工程化的角度上会显得更加合理,也会省去需要npm link,然后再npm unlink的麻烦。

这块内容后续等我实践完再另开一篇内容分享(先种个草)。


npm link 官方文档:docs.npmjs.com/cli/v10/com...

相关推荐
腾讯TNTWeb前端团队1 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪5 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试