极客时间对于推广渠道会有返利优惠,比如山月在极客时间买了一门课,再把课程分享给好友购买,这时极客时间会向山月返利20元左右。
而我现在做了一个返利平台,你可以在上边通过山月的链接购买课程,此时极客时间会向我返利。为了共同学习,而你可以添加我的微信 (shanyue94),我将把极客时间给我的返利发一个红包全部返给你

# dev 与 devDep 的区别

# node_modules 的拓扑结构

# 基础

require('package-hello') 时,假设 package-hello 是一个 npm 库,我们是如何找到该 package 的?

  1. 寻找当前目录的 node_modules/package-hello 目录
  2. 如果未找到,寻找上一级的 ../node_modules/package-hello 目录,以此递归查找

# 很久以前: 嵌套结构

npmv2 时,node_modules 对于各个 package 的拓扑为嵌套结构。

假设:

  1. 项目依赖 package-apackage-b 两个 package
  2. package-apackage-b 均依赖 lodash@4.17.4

依赖关系以 Markdown 列表表示:

+ package-a
  + `lodash@4.17.4`
+ package-b
  + `lodash@4.17.4`

此时 node_modules 目录结构如下:

graph
  app(node_modules) ---> A(package-a)
  app          ---> B(package-b)
  A            ---> C("lodash@4.17.4")
  B            ---> D("lodash@4.17.4")

此时最大的问题

  1. 嵌套过深
  2. 占用空间过大

# 现在阶段: 平铺结构

目前在 npm/yarn 中仍然为平铺结构,但 pnpm 使用了更省空间的方法,以后将会提到

npmv3 之后 node_modules 为平铺结构,拓扑结构如下:

graph
  app(node_modules) ---> A(package-a)
  app          ---> B(package-b)
  app          ---> C("lodash@4.17.4")

# 一个问题: 以下依赖最终 node_modules 结果如何?

可参考该示例 (opens new window)

依赖关系以 Markdown 列表表示

+ package-a
  + `lodash@^4.17.4`
+ package-b
  + `lodash@^4.16.1`

答: 与上拓扑结构一致,因为二者为 ^ 版本号,他们均会下载匹配该版本号范围的最新版本,比如 @4.17.4,因此二者依赖一致。

此时如果有 lock,会有一点小问题,待稍后讨论

node_modules 目录结构如下图:

graph
  app(node_modules) ---> A(package-a)
  app          ---> B(package-b)
  app          ---> C("lodash@4.17.4")

# 再一个问题: 以下依赖最终 node_modules 结果如何?

可参考该示例 (opens new window)

+ package-a
  + `lodash@4.17.4`
+ package-b
  + `lodash@4.16.1`

答:package-b 先从自身 node_modules 下寻找 lodash,找到 lodash@4.16.1

node_modules 目录结构如下图:

graph
  app(node_modules) ---> A(package-a)
  app          ---> B(package-b)
  app          ---> C("lodash@4.17.4")
  B            ---> D("lodash@4.16.1")

# 再一个问题: 以下依赖最终 node_modules 结果如何

+ package-a
  + `lodash@4.0.0`
+ package-b
  + `lodash@4.0.0`
+ package-c
  + `lodash@3.0.0`
+ package-d
  + `lodash@3.0.0`

答:package-d 只能从自身的 node_modules 下寻找 lodash@3.0.0,而无法从 package-c 下寻找,此时 lodash@3.0.0 不可避免地会被安装两次

node_modules 目录结构如下图:

graph
  app(node_modules) ---> A(package-a)
  app          ---> B(package-b)
  app          ---> C(package-c)
  app          ---> D(package-d)
  app          ---> X("lodash@4.0.0")
  C            ---> Y("lodash@3.0.0")
  D            ---> Z("lodash@3.0.0")

# 重复的版本依赖有什么问题?

可参考 npm doppelgangers (opens new window)

  1. Install Size,安装体积变大,浪费磁盘空间
  2. Build Size,构建打包体积变大,浪费带宽,网站打开延迟,破坏用户体验 (PS: 支持 Tree Shaking 会好点)
  3. 破坏单例模式,破坏缓存,如 postcss 的许多插件将 postcss 扔进 dependencies,重复的版本将导致解析 AST 多次

# lock 与重复的版本依赖问题

# 一个问题: 以下依赖最终 node_modules 结果如何?

可参考该示例 (opens new window)

依赖关系以 Markdown 列表表示

+ package-a
  + `lodash@^4.16.0`
+ package-b
  + `lodash@^4.17.0`

答: 因为二者为 ^ 版本号,他们均会下载匹配该版本号范围的最新版本,比如 @4.17.0,因此二者依赖一致。

graph
  app(node_modules) ---> A(package-a)
  app          ---> B(package-b)
  app          ---> C("lodash@4.17.0")

# 再一个问题: 如果有 lockfile 且安装时间不一致,最终 node_modules 结果如何

依赖关系以 Markdown 列表表示:

+ package-a
  + `lodash@^4.16.0`
+ package-b
  + `lodash@^4.17.0`

安装流程如下:

  1. 首次下载 package-a,其依赖 lodash@^4.16.0,此时最新版本为 lodash@4.16.0
  2. 三个月后,下载 package-b,其依赖 lodash@4.17.0,此时最新版本为 lodash@4.17.0

问: 最终 node_modules 及 lockfile 结果如何?

graph
  app(node_modules) ---> A(package-a)
  app          ---> B(package-b)
  app          ---> C("lodash@4.17.0")

关于山月

我的项目:
我的微信:shanyue94,欢迎交流
Last Updated: 7/21/2019, 11:25:08 AM