local 方式 npm install 在子目录中「重复」安装 express

2015-04-08 19:39:21 +08:00
 lvii

——

目录结构:

  1. nodejs 主目录:~/code/nodejs/
  2. nodejs 子项目:~/code/nodejs/sub_folder

主目录 安装 express

gentoo ~/code/nodejs $ npm install express --save
express@4.12.3 node_modules/express
├── merge-descriptors@1.0.0
├── utils-merge@1.0.0
├── cookie-signature@1.0.6
├── methods@1.1.1
├── cookie@0.1.2
├── fresh@0.2.4
├── escape-html@1.0.1
├── range-parser@1.0.2
├── content-type@1.0.1
├── finalhandler@0.3.4
├── vary@1.0.0
├── parseurl@1.3.0
├── serve-static@1.9.2
├── content-disposition@0.5.0
├── path-to-regexp@0.1.3
├── depd@1.0.0
├── qs@2.4.1
├── on-finished@2.2.0 (ee-first@1.1.0)
├── debug@2.1.3 (ms@0.7.0)
├── etag@1.5.1 (crc@3.2.1)
├── send@0.12.2 (destroy@1.0.3, ms@0.7.0, mime@1.3.4)
├── type-is@1.6.1 (media-typer@0.3.0, mime-types@2.0.10)
├── accepts@1.2.5 (negotiator@0.5.1, mime-types@2.0.10)
└── proxy-addr@1.0.7 (forwarded@0.1.0, ipaddr.js@0.1.9)

子目录 安装 express-generator

测试 express-generator 的 子目录 : ~/code/nodejs/test

gentoo ~/code/nodejs $ mkdir test && cd test

gentoo ~/code/nodejs/test $ npm install express-generator --save
npm WARN prefer global express-generator@4.12.1 should be installed with -g
express-generator@4.12.1 ../node_modules/express-generator
├── sorted-object@1.0.0
├── commander@2.6.0
└── mkdirp@0.5.0 (minimist@0.0.8)

express-generator 是安装在 nodejs 开发 主目录 下的 ~/code/nodejs/node_modules 目录:

gentoo /home/i/code/nodejs 
$ tree -L 2 ~/code/nodejs/node_modules/
/home/i/code/nodejs/node_modules/
├── express
│   ├── History.md
│   ├── index.js
│   ├── lib
│   ├── LICENSE
│   ├── node_modules
│   ├── package.json
│   └── Readme.md
└── express-generator
    ├── bin
    ├── LICENSE
    ├── node_modules
    ├── package.json
    ├── README.md
    └── templates

但发现在 主目录子目录 下的 node_modules 都有安装 express

主目录 的 express 目录树:

主目录 下的 express 目录树,比 子目录 多安装了 debug 包:

gentoo /home/i/code/nodejs
$ tree -L 2 node_modules/express
node_modules/express
├── History.md
├── index.js
├── lib
│   ├── application.js
│   ├── express.js
│   ├── middleware
│   ├── request.js
│   ├── response.js
│   ├── router
│   ├── utils.js
│   └── view.js
├── LICENSE
├── node_modules
│   ├── accepts
│   ├── content-disposition
│   ├── content-type
│   ├── cookie
│   ├── cookie-signature
│   ├── debug                   <--
│   ├── depd
│   ├── escape-html
│   ├── etag
│   ├── finalhandler
│   ├── fresh
│   ├── merge-descriptors
│   ├── methods
│   ├── on-finished
│   ├── parseurl
│   ├── path-to-regexp
│   ├── proxy-addr
│   ├── qs
│   ├── range-parser
│   ├── send
│   ├── serve-static
│   ├── type-is
│   ├── utils-merge
│   └── vary
├── package.json
└── Readme.md

28 directories, 11 files

子目录 的 express 目录树:

gentoo /home/i/code/nodejs/test
$ tree -L 2 node_modules/express/
node_modules/express/
├── History.md
├── index.js
├── lib
│   ├── application.js
│   ├── express.js
│   ├── middleware
│   ├── request.js
│   ├── response.js
│   ├── router
│   ├── utils.js
│   └── view.js
├── LICENSE
├── node_modules
│   ├── accepts
│   ├── content-disposition
│   ├── content-type
│   ├── cookie
│   ├── cookie-signature
│   ├── depd
│   ├── escape-html
│   ├── etag
│   ├── finalhandler
│   ├── fresh
│   ├── merge-descriptors
│   ├── methods
│   ├── on-finished
│   ├── parseurl
│   ├── path-to-regexp
│   ├── proxy-addr
│   ├── qs
│   ├── range-parser
│   ├── send
│   ├── serve-static
│   ├── type-is
│   ├── utils-merge
│   └── vary
├── package.json
└── Readme.md

27 directories, 11 files

WHY

为什么 子目录 不能复用 主目录 的 express 还要重复安装呢?

——

4474 次点击
所在节点    Node.js
6 条回复
qiu8310
2015-04-08 20:31:10 +08:00
目录树太多了,看的不是很明白,但我最近遇到类似问题:

如果模块 a 依赖于 b,c; 而模块 b 也依赖于 c;
当我在安装模块 b 的时候,c 模块就只会安装 1 次,并且是在 a 模块下。

看你好像是分两次安装,第二次安装的时候估计不会检查你当前目录的父目录是否已经安装了你要依赖的模块吧。

不知道这样理解对不对。
zhaoace
2015-04-09 13:49:19 +08:00
唔,这个树展开的话每个都是当前根节点的所有依赖。
为神马不能复用呢? 因为版本不一定一样啊。。。

每个项目的依赖内容都完整搞下来,这样文件夹会大一点,但是项目的path清晰了,里面的依赖版本独立了,整个项目的可移植性也变强了。

想象一下你把某个项目做完,整个项目folder撸走,换个地方还能run是不是有点小激动呢?
lvii
2015-04-09 16:22:43 +08:00
@qiu8310 兄。
1. 我先在 父目录 安装 express
2. 然后在 子目录 安装 express-generator 。express-generator 以来 express
3. 安装 express-generator 时,没有检查,父目录已经安装过 express 又在 子目录 下 重复 安装了一遍 express

@zhaoace 兄。你的意思,这是正常现象。npm 使用 local 方式安装,不会检查 local 路径下已经有安装过的 package 即使版本满足依赖。。。。
zhaoace
2015-04-10 08:40:27 +08:00
你应该这么理解这个问题。
无论是你的父目录还是子目录还是express还是express-generator都是独立的项目,而每个项目的自己的依赖都在自己的目录里,不会往上回溯的。

所以如果子目录里面用了express-generator,而express-generator自己有任何依赖的内容的话,要不然是从express-generator的目录下面查找,要不然就是去global path里面查找了,不会特地查看项目上游的path里面有没有相关内容的。

甚至说express-generator依赖了某个npm,他都不会关心你的子项目里有没有,只关心express-generator的目录下面以及global下面有没有。

:D
zhaoace
2015-04-10 08:45:37 +08:00
再多嘴说一句吧,你的依赖打开的太浅了。 你仔细去看下依赖的依赖就看明白了。。。

悲伤的故事。。。
lvii
2015-04-15 13:24:18 +08:00
@zhaoace 这样。。。原来是依赖查找路径的杯桑故事。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/182387

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX