blog
blog copied to clipboard
你所不知道的模块调试技巧 - npm link
1. 背景
node 应用开发中,我们不可避免的需要使用或拆分为 npm 模块,经常遇到的一个问题是:
新开发或修改的 npm 模块,如何在项目中试验?
新同学一般会有以下几种方式:
为了方便示范,我们假设项目是 my-project
, 需要用到一个独立的 my-utils
模块
1.1 发布一个 beta 版本
- 优点:你高兴就好。
- 缺点: 无趣+无趣+无趣,麻烦+麻烦+麻烦。
1.2 直接用相对路径安装
$ cd path/to/my-project
$ npm install path/to/my-utils
- 优点:简单明了
- 缺点: 调试过程中往往需要微调,此时需要切换到 my-utils 目录修改,然后反复重新 install,很麻烦
1.3 使用软链
$ cd path/to/my-project/node_modules
$ ln -s path/to/my-utils my-utils
- 优点:软链后,两边修改直接同步
- 缺点: 指令操作麻烦,不同操作系统语法不一样
2. 正解 - npm link
但其实 npm 本身已经对此类情况提供了专门的 npm link
指令。
相关文档: https://docs.npmjs.com/cli/link
下面我们简单介绍下用法:
$ cd path/to/my-project
$ npm link path/to/my-utils
简单的替换一个单词,就搞定了,cool~
如果这两种的目录不在一起,那还有一种方法:
$ # 先去到模块目录,把它 link 到全局
$ cd path/to/my-utils
$ npm link
$
$ # 再去项目目录通过包名来 link
$ cd path/to/my-project
$ npm link my-utils
该指令还可以用来调试 node cli 模块,譬如需要本地调试我们的 egg-init,可以这样:
$ cd path/to/egg-init
$ npm link
$ # 此时全局的 egg-init 指令就已经指向你的本地开发目录了
$ egg-init # 即可
想去掉 link 也很简单:
$ npm unlink my-utils
3. 写在最后
- 该方法只是为了最后一步调试,模块本身的正确性,应该更多的通过单元测试来保证。
- 单元测试相关内容,可以参见:单元测试
👍,当年修改 node_modules 后发布了一次导致 node_modules 里面的代码直接没了给我留下了 深刻 的记忆 😂
问题是一个项目里面被 flatten 出来几千个目录,你就算开个软连,编辑器里面展开 node_modules 目录也会被卡死。
@XadillaX 这个跟 link 关系不大,是 npm@2,npm@3,cnpm 的包安装方式区别导致的吧。
这是编辑器的问题,很容易解决的,vscode 和 webstorm 配置几个 ignore 就 ok 了。(局部 ignore,不用全部屏蔽整个 node_modules)
@atian25 为什么大家都喜欢把 NPM 自身机制问题总要归结到编辑器问题上去呢 -。 -
因为 NPM 我们改变不了,只好改编辑器了 (摊手)
发自我的 iPhone
在 2017年2月28日,18:44,Flandre Scarlet [email protected] 写道:
@atian25 为什么大家都喜欢把 NPM 自身机制问题总要归结到编辑器问题上去呢 -。 -
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
呀, 感觉如果是用yarn install
的话用yarn link
会好一点的呢。具体原因不太清楚, 在yarn下载然后用npm(npm5) link感觉npm会去处理环境生成一个lock文件, 处理起来有点慢的呢, 用yarn就一秒左右就搞定了。不过确实link的方式在开发的时候确实是不错的思路。感谢分享。
那,如果我的js插件直接放到项目目录下呢
@lightWey 然后你的问题是?
🤔 我居然每次都 npm install path/to/my-project --save 一次,没有想到用 link...
有一个模块,开始是直接通过npm install gitlab地址,运行项目没错,但是在本地,我通过npm link之后,运行就出错了,
@sunlandong 这种反馈对交流是没有任何帮助的,出什么错?错误信息是啥?复现步骤是啥?挤牙膏似的交流是最没效率的。
你好,我目前也是需要把一些基础的vue组件分离出去单独做一个npm的包,试了npm link
这个办法,理论上是没有问题的,可以达到想要的目的。但是我遇到的问题可能和vuejs/babel更相关一些,由于vue组件在分离前,有webpack配置好了babel去解析,但是在分离出去之后,似乎要给新的npm模块单独做一个构建的流程?我现在只是单纯的把一些vue文件抽离了,放到另一个git仓库了,然后用一个入口文件import/export 所有的组件,然后问题是启动webpack server的时候会无限卡在等待打包的过程。我感觉就是缺了对分离出去的npm模块的解析过程。
请问有没有类似vue/react组件本地开发流程的经验分享?谢谢啦
应该没区别的,npm link
只是对目录做了一个软链而已,文件系统层面的,工具层面的应该是无感知的,除非工具那边不支持跟随软链(应该不会)。
npm link
只是在需要本地测试的时候用到的。
是否每次install
的时候都需要设置下软链,软链会不会被记录在lock.json
文件中,如果能记录是不是说明能够解决特定的npm package
放到自己的项目中维护
link 只是用于调试用的。
好吧,我本来以为能解决自己维护 package
的问题
既然提到了ln,那还是直接ln -s吧?跟ln有什么区别?
@qwIvan
-
npm link
后,该项目会被 link 到全局去,你就能测试命令行了 - 在上面那句后,可以直接
npm link pkgName
来在应用中 link,不需要 ln 复杂的相对路径。 -
ln
不同操作系统的语法不同
大神你好,我这里遇到一个问题,npm install 之后,在node_modules/.bin/ 里面没有创建软连接,都是硬链。(node V8.4.0 npm V5.3.0)这个情况是在 生成环境打包时候发现的,本地和测试环境都没问题,我还尝试过,把生成打的包下载之后,删除node_modules 和 package-lock.json文件,然后本地npm install,这样生成.bin文件夹里会自动创建软链。所以 请问一下大神,有没有碰到过这样的情况,npm 在什么情况下不会自动创建软链的?
没遇过。
@llsldwy 你那个问题很大可能是你打包的问题, tar 或 zip 的时候多了一个参数
你好 ,有个问题,我在npmlink后,不能彼此共享node_modules,执行脚本的时候找不到安装依赖
@sunha1yang 啥叫共享 node_modules?
sorry, 我表述上有点问题,我要测试pkg有一些依赖,如webpack等第三方包,我在另一个文件夹(此文件夹下有node_modules文件,pkgName需要的依赖包都存在)下npm link pkgName后,我的pkg引不到此文件下node_modules文件,然后就会报错,我的问题是如何能让我的pkg能够引到当前文件夹下的node_modules文件?
不知道我有没有表述清楚......
还是没懂,搞个 tree 图呗
这个是我的操作步骤
我指的是这样描述下。。。
.
├── app
├── config
├── node_modules
│ └── aaa -> link to ./app/xx/xx
└── package.json
目录结构是这样的:
.
├── fe
├── awt ->npm link
├── project -> 在项目目录下 npm link awt
│ ├── app
│ ├── node_modules
│ └── package.json
| └── config
└── otherproject
└── home.html
很有用,基本你上面提到的第一种方法,以及后面的都用过 哈哈
问一下,typescript的项目,怎么解决这个问题
没啥区别吧
楼主你好。我现在遇到一个问题
我现在有一个模块lib文件夹(lib中package.json库名称是"@sml/lib")跟project项目文件夹
我切换到lib下执行npm link 然后再切换到project文件夹下执行 npm link @sml/lib
在项目中引入lib后刷新就报错了。
Unable to resolve module @sml/lib
from /Users/sml2/Documents/iOSDemos/RNBaseProject/App.js
: Module @sml/lib
does not exist in the Haste module map
这是为什么呢
@sunha1yang npm link 会遇到依赖找不到的问题,不是好用(没有问题的话还是尽量使用 npm link)
https://medium.com/@vcarl/problems-with-npm-link-and-an-alternative-4dbdd3e66811
依赖找不到的问题,可以用https://nodejs.org/api/cli.html#cli_preserve_symlinks 这个解决的,朋友们
@brizer 请问这个--preserve-symlinks 是node命令,怎么使用?
@brizer 请问这个--preserve-symlinks 是node命令,怎么使用?
举个例子,你用vscode调试的时候,a依赖了b,而b是npm link的,那么在a项目的调试配置中加一句:
"runtimeArgs":[
"--preserve-symlinks"
]
就可以修改b,顺便调试a了。
@brizer 我这是一个webpack构建的web项目,比如a依赖b, a和b都依赖vue这个框架,我通过构建a跑在webpack-dev-server上,用chrome打开调试,这个我该如何操作呢
@brizer 我这是一个webpack构建的web项目,比如a依赖b, a和b都依赖vue这个框架,我通过构建a跑在webpack-dev-server上,用chrome打开调试,这个我该如何操作呢
微信 brizer1992 单独聊,没太明白你问题是什么。
@brizer 我在此处找到了问题的解决,万分感谢提供解答与搜索思路。
@VictorWu90 优秀
在webpack构建的项目中,可以使用resolve-alias字段使用绝对路径强制指定调试时第三框框架的源目录,
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue-router': resolve('node_modules/vue-router'),
vuex: resolve('node_modules/vuex'),
'vue$': resolve('node_modules/vue/dist/vue.esm.js'),
// 'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
}
请教一下,如果我的一个项目依赖了A组件,A模块又依赖了B组件,那么我如果要在项目中调试B组件,应该怎么快速的link?
cd a/node_modules && npm link c
这里有另一种方式,我们在项目里经常用到,就是直接通过 npm 的 package.json
中的依赖版本来指定。比如我当前开发的项目依赖一个组件库 element-react-dataview
,那么我会将此组件库的代码 clone 到 lib/element-react-dataview
,然后将 package.json
中的引用改成:
{
"dependencies": {
"element-react-dataview": "file:lib/element-react-dataview"
}
}
项目目录下运行 npm i
之后再删除掉 lib/element-react-dataview/package.json
(因为 npm 发布版引用的是编译后的 dist 文件,没有此情况的可以不用删除),启动项目的 webpack-dev-server 之后引用的就是对应库的源码了,可以随时修改并进行调试。
这其实也是另一种形式的 npm link
。
lerna
学到了,thx
对npm install指令和npm link指令更加理解了。
1.通过npm link
给公共组件建立软链接
2.在项目中通过npm link 包名
引入后,Module not found: Error: Can't resolve 'vue-loader/node_modules/vue-hot-reload-api
出现这个报错是什么情况,有朋友解答下么,这个依赖在vuecli创建的时候就已经有了啊
可能是 vuecli 对软链的处理不好。
可能是 vuecli 对软链的处理不好。
找到问题了,需要把webpack配置中的 symlinks设为false
,否则就会报错,为了解决这个问题头都秃了。。。
可能是 vuecli 对软链的处理不好。
找到问题了,需要把webpack配置中的
symlinks设为false
,否则就会报错,为了解决这个问题头都秃了。。。
是的,很好
wml这个才是最屌的,因为React Native 不支持 npm link,https://www.bram.us/2018/03/10/working-with-symlinked-packages-in-react-native/
Metro 不支持跟随软链: https://github.com/facebook/metro/issues/1
npm link贼好用
可能是 vuecli 对软链的处理不好。
找到问题了,需要把webpack配置中的
symlinks设为false
,否则就会报错,为了解决这个问题头都秃了。。。
💥就是这个害我浪费了半天时间
我发现 1.2 相对路径安装 修改代码后不需要重新 install 呀
在引用的项目中使用安装插件导致被引用的插件废掉,被引用的模块需要清理掉node_modules重新安装才能成功启动