Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

你所不知道的模块调试技巧 - npm link #17

Open
atian25 opened this issue Jan 24, 2017 · 62 comments
Open

你所不知道的模块调试技巧 - npm link #17

atian25 opened this issue Jan 24, 2017 · 62 comments
Labels

Comments

@atian25
Copy link
Owner

atian25 commented Jan 24, 2017

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. 写在最后

  • 该方法只是为了最后一步调试,模块本身的正确性,应该更多的通过单元测试来保证。
  • 单元测试相关内容,可以参见:单元测试
@atian25 atian25 changed the title 你所不知道的调试技巧 - npm link 你所不知道的模块调试技巧 - npm link Jan 24, 2017
@rccoder
Copy link

rccoder commented Feb 9, 2017

👍,当年修改 node_modules 后发布了一次导致 node_modules 里面的代码直接没了给我留下了 深刻 的记忆 😂

@XadillaX
Copy link

问题是一个项目里面被 flatten 出来几千个目录,你就算开个软连,编辑器里面展开 node_modules 目录也会被卡死。

@atian25
Copy link
Owner Author

atian25 commented Feb 28, 2017

@XadillaX 这个跟 link 关系不大,是 npm@2,npm@3,cnpm 的包安装方式区别导致的吧。

这是编辑器的问题,很容易解决的,vscode 和 webstorm 配置几个 ignore 就 ok 了。(局部 ignore,不用全部屏蔽整个 node_modules)

@XadillaX
Copy link

@atian25 为什么大家都喜欢把 NPM 自身机制问题总要归结到编辑器问题上去呢 -。 -

@atian25
Copy link
Owner Author

atian25 commented Feb 28, 2017 via email

@monkindey
Copy link

呀, 感觉如果是用yarn install的话用yarn link会好一点的呢。具体原因不太清楚, 在yarn下载然后用npm(npm5) link感觉npm会去处理环境生成一个lock文件, 处理起来有点慢的呢, 用yarn就一秒左右就搞定了。不过确实link的方式在开发的时候确实是不错的思路。感谢分享。

@lightWey
Copy link

那,如果我的js插件直接放到项目目录下呢

@atian25
Copy link
Owner Author

atian25 commented Aug 16, 2017

@lightWey 然后你的问题是?

@ahonn
Copy link

ahonn commented Aug 16, 2017

🤔 我居然每次都 npm install path/to/my-project --save 一次,没有想到用 link...

@sunlandong
Copy link

有一个模块,开始是直接通过npm install gitlab地址,运行项目没错,但是在本地,我通过npm link之后,运行就出错了,

@atian25
Copy link
Owner Author

atian25 commented Nov 27, 2017

@sunlandong 这种反馈对交流是没有任何帮助的,出什么错?错误信息是啥?复现步骤是啥?挤牙膏似的交流是最没效率的。

@renyuanz
Copy link

你好,我目前也是需要把一些基础的vue组件分离出去单独做一个npm的包,试了npm link这个办法,理论上是没有问题的,可以达到想要的目的。但是我遇到的问题可能和vuejs/babel更相关一些,由于vue组件在分离前,有webpack配置好了babel去解析,但是在分离出去之后,似乎要给新的npm模块单独做一个构建的流程?我现在只是单纯的把一些vue文件抽离了,放到另一个git仓库了,然后用一个入口文件import/export 所有的组件,然后问题是启动webpack server的时候会无限卡在等待打包的过程。我感觉就是缺了对分离出去的npm模块的解析过程。

请问有没有类似vue/react组件本地开发流程的经验分享?谢谢啦

@atian25
Copy link
Owner Author

atian25 commented Dec 11, 2017

应该没区别的,npm link 只是对目录做了一个软链而已,文件系统层面的,工具层面的应该是无感知的,除非工具那边不支持跟随软链(应该不会)。

npm link 只是在需要本地测试的时候用到的。

@AsceticBoy
Copy link

是否每次install的时候都需要设置下软链,软链会不会被记录在lock.json文件中,如果能记录是不是说明能够解决特定的npm package放到自己的项目中维护

@atian25
Copy link
Owner Author

atian25 commented Feb 7, 2018

link 只是用于调试用的。

@AsceticBoy
Copy link

好吧,我本来以为能解决自己维护 package 的问题

@qwIvan
Copy link

qwIvan commented Apr 7, 2018

既然提到了ln,那还是直接ln -s吧?跟ln有什么区别?

@atian25
Copy link
Owner Author

atian25 commented Apr 8, 2018

@qwIvan

  1. npm link 后,该项目会被 link 到全局去,你就能测试命令行了
  2. 在上面那句后,可以直接 npm link pkgName 来在应用中 link,不需要 ln 复杂的相对路径。
  3. ln 不同操作系统的语法不同

@llsldwy
Copy link

llsldwy commented Apr 17, 2018

大神你好,我这里遇到一个问题,npm install 之后,在node_modules/.bin/ 里面没有创建软连接,都是硬链。(node V8.4.0 npm V5.3.0)这个情况是在 生成环境打包时候发现的,本地和测试环境都没问题,我还尝试过,把生成打的包下载之后,删除node_modules 和 package-lock.json文件,然后本地npm install,这样生成.bin文件夹里会自动创建软链。所以 请问一下大神,有没有碰到过这样的情况,npm 在什么情况下不会自动创建软链的?

@atian25
Copy link
Owner Author

atian25 commented Apr 17, 2018

没遇过。

@atian25
Copy link
Owner Author

atian25 commented Jun 26, 2018

@llsldwy 你那个问题很大可能是你打包的问题, tar 或 zip 的时候多了一个参数

@sunha1yang
Copy link

你好 ,有个问题,我在npmlink后,不能彼此共享node_modules,执行脚本的时候找不到安装依赖

@atian25
Copy link
Owner Author

atian25 commented Jun 27, 2018

@sunha1yang 啥叫共享 node_modules?

@sunha1yang
Copy link

sorry, 我表述上有点问题,我要测试pkg有一些依赖,如webpack等第三方包,我在另一个文件夹(此文件夹下有node_modules文件,pkgName需要的依赖包都存在)下npm link pkgName后,我的pkg引不到此文件下node_modules文件,然后就会报错,我的问题是如何能让我的pkg能够引到当前文件夹下的node_modules文件?

不知道我有没有表述清楚......

@qq912276337
Copy link

楼主你好。我现在遇到一个问题
我现在有一个模块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
这是为什么呢

@zhbhun
Copy link

zhbhun commented Dec 19, 2018

@sunha1yang npm link 会遇到依赖找不到的问题,不是好用(没有问题的话还是尽量使用 npm link)

https://medium.com/@vcarl/problems-with-npm-link-and-an-alternative-4dbdd3e66811

@VictorWu90
Copy link

@brizer 请问这个--preserve-symlinks 是node命令,怎么使用?

@VictorWu90
Copy link

@brizer 我这是一个webpack构建的web项目,比如a依赖b, a和b都依赖vue这个框架,我通过构建a跑在webpack-dev-server上,用chrome打开调试,这个我该如何操作呢

@VictorWu90
Copy link

@brizer 我在此处找到了问题的解决,万分感谢提供解答与搜索思路。

@VictorWu90
Copy link

在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')
        }
    }

@orangeyyy
Copy link

请教一下,如果我的一个项目依赖了A组件,A模块又依赖了B组件,那么我如果要在项目中调试B组件,应该怎么快速的link?

@atian25
Copy link
Owner Author

atian25 commented Oct 9, 2019

cd a/node_modules && npm link c

@mytharcher
Copy link

这里有另一种方式,我们在项目里经常用到,就是直接通过 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

@foxundermoon
Copy link

lerna

@fireairforce
Copy link

学到了,thx

@coconilu
Copy link

coconilu commented Mar 8, 2020

对npm install指令和npm link指令更加理解了。

@Mr-xue
Copy link

Mr-xue commented Apr 20, 2020

1.通过npm link给公共组件建立软链接
2.在项目中通过npm link 包名引入后,Module not found: Error: Can't resolve 'vue-loader/node_modules/vue-hot-reload-api出现这个报错是什么情况,有朋友解答下么,这个依赖在vuecli创建的时候就已经有了啊

@atian25
Copy link
Owner Author

atian25 commented Apr 20, 2020

可能是 vuecli 对软链的处理不好。

@Mr-xue
Copy link

Mr-xue commented Apr 21, 2020

可能是 vuecli 对软链的处理不好。

找到问题了,需要把webpack配置中的 symlinks设为false,否则就会报错,为了解决这个问题头都秃了。。。

@youngjuning
Copy link

wml这个才是最屌的,因为React Native 不支持 npm link,https://www.bram.us/2018/03/10/working-with-symlinked-packages-in-react-native/

@youngjuning
Copy link

Metro 不支持跟随软链: facebook/metro#1

@littlepoolshark
Copy link

npm link贼好用

@tian0o0
Copy link

tian0o0 commented Sep 28, 2020

可能是 vuecli 对软链的处理不好。

找到问题了,需要把webpack配置中的 symlinks设为false,否则就会报错,为了解决这个问题头都秃了。。。

💥就是这个害我浪费了半天时间

@afishhhhh
Copy link

我发现 1.2 相对路径安装 修改代码后不需要重新 install 呀

@LS-LILEI
Copy link

LS-LILEI commented Jun 6, 2021

在引用的项目中使用安装插件导致被引用的插件废掉,被引用的模块需要清理掉node_modules重新安装才能成功启动

@wmasfoe
Copy link

wmasfoe commented Sep 5, 2022

npm yarn pnpm 这三个的 link 都是互通的吗?
我有个场景:项目用 yarn 的 monorepo,组件库用的 pnpm 的 monorepo

我在组件库使用:

  • pnpm build
  • yarn link,输出:Registered "xxx-design-monorepo".

项目中使用:

  • yarn link "xxx-design-monorepo",输出:Invalid destination; Can't link the project to itself.

版本:

  • yarn: 3.0.1
  • pnpm: 7.3.0
  • node: 14.20.0

@atian25
Copy link
Owner Author

atian25 commented Sep 5, 2022

不要混用包管理器

@wmasfoe
Copy link

wmasfoe commented Sep 5, 2022

不要混用包管理器

这玩意是我可以左右的吗🙈🙈,yarn 用的 learnpnpm 用自带的 monorepo
项目分别有 package-lock.json / yarn.lock。👀

@wmasfoe
Copy link

wmasfoe commented Sep 8, 2022

npm yarn pnpm 这三个的 link 都是互通的吗? 我有个场景:项目用 yarn 的 monorepo,组件库用的 pnpm 的 monorepo

我在组件库使用:

  • pnpm build
  • yarn link,输出:Registered "xxx-design-monorepo".

项目中使用:

  • yarn link "xxx-design-monorepo",输出:Invalid destination; Can't link the project to itself.

版本:

  • yarn: 3.0.1
  • pnpm: 7.3.0
  • node: 14.20.0

组件库 yarn link 之后,在一般项目里 (不是 lerna 架构)yarn link "xxx-design-monorepo" 就没问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests