一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
大家好,我是小十七_,下面是通俗易懂的 npm 全面总结,希望能帮助到大家查漏补缺~
内容参考自这个视频,可以结合一起看:www.youtube.com/watch?v=P3a…
npm 是什么
npm 的英文是,node package manager,是 node 的包管理工具
为什么需要 npm
就像建造汽车一样,如果发动机、车身、轮胎、玻璃等等都自己做的话,几十年也做不完。但是如果有不同的厂商,已经帮我们把各个零件都制作好,我们只负责组装,那整个过程会运作的非常快
同样的道理,如果软件的逻辑,我们都自己开发的话,写一个功能需要非常长的时间。如果使用已有的功能、工具、npm 包,快速的组装我们想要的功能,不是让事情变得非常简单吗
npm 安装的包为什么可以被引入
我们使用比如 npm install chalk 安装包时,会被安装到本地 node_modules 目录下
在实际页面 import 时,根据 node 的模块系统的实现方式,会按照这个判断:是否是核心模块(fs 等),是否是相对路径,package.json 同级目录是否有 node_modules,上级目录是否有,一直到文件系统的根目录下是否有 node_modules 文件夹。
但是这样找到的一般是文件夹,如果文件夹目录下有 package.json 文件,会读取里面的 main 字段指向的文件,如果没有,会读取 index.js 文件。
webpack 等打包工具是兼容 node 模块系统的,于是也会使用这种方式寻找模块,同时会做一些优化,比如支持配置 alias 和 external,自定义 import 的逻辑。
alias: {
Icon: path.resolve(__dirname, 'src/components/Icon.jsx'),
}
import Icon from 'Icon' // -> /path/to/src/components/Icon.jsx
npm 全局安装的位置
npm install -g @tarojs/cli
stackoverflow.com/questions/2…
那么 taro 全局安装到什么位置了呢?如果使用了 nvm,则放到了 nvm 对应版本的文件夹下
➜ ~ npm root -g
/Users/abc/.nvm/versions/node/v14.15.0/lib/node_modules
npm root -g
npm root 的作用是打印出当前工作目录下,有效的 node_modules 文件夹的位置,如果直接执行这个命令:
➜ ~ npm root
/Users/abc/node_modules
➜ ~ cd test
➜ test git:(dev) ✗ npm root
/Users/abc/test/node_modules
npm root -g 打印出的就是全局安装的 node_modules 位置
全局安装的位置
需要看是否用了 nvm:
- 没有用 nvm 的情况:
➜ ~ cd /usr/local/lib/node_modules
➜ node_modules ls
anywhere npm npm-check
- 用了 nvm 的情况,放到 nvm 对应版本的文件夹下
~/.nvm/versions/node/{version}/lib/node_modules/:
➜ ~ cd ~/.nvm/versions/node/v14.15.0/lib/node_modules
➜ node_modules git:(3d9c31d) ls
@ies @tarojs npm pnpm typeorm
which npm
➜ ~ which npm
/Users/abc/.nvm/versions/node/v14.15.0/bin/npm
which 是一个 linux 命令,在环境变量 $PATH 中查找命令对应的可执行文件
npm 安装包的结构
是平铺的结构
比如安装 react 和 react-dom 安装完成后,会发现除了它们,还有其他几个包
这是因为它们是,react、react-dom 的依赖,会被扁平的安装到 node_modules 中,可以通过 npm list 看到
➜ src git:(master) ✗ npm list
react_basic_app@0.0.1 /Users/abc/react_basic_app
├─┬ react@17.0.2
│ ├─┬ loose-envify@1.4.0
│ │ └── js-tokens@4.0.0
│ └── object-assign@4.1.1
└─┬ react-dom@17.0.2
├── loose-envify@1.4.0 deduped
├── object-assign@4.1.1 deduped
└─┬ scheduler@0.20.2
├── loose-envify@1.4.0 deduped
└── object-assign@4.1.1 deduped
另外,可以通过增加参数的方式,查看具体包的依赖情况
➜ src git:(master) ✗ npm ls object-assign
react_basic_app@0.0.1 /Users/abc/react_basic_app
├─┬ react@17.0.2
│ └── object-assign@4.1.1
└─┬ react-dom@17.0.2
├── object-assign@4.1.1 deduped
└─┬ scheduler@0.20.2
└── object-assign@4.1.1 deduped
可以发现有好几个包都依赖了 object-assign,但是 react-dom 中的两个写了 deduped,并且实际在 node_modules 中 object-assign 只安装了一份
deduped 是 deduplicated 的缩写,意思是重复项被删除
npm 会通过搜索本地包的树状结构,通过将包之间的依赖关系向上移动,来简化整体的结构,这样依赖可以在多个包之间共享了
于是,object-assign 可以只安装一份,是因为 npm 简化了他们间的依赖关系
npm 包的版本规则
比如 4.1.1
-
第一个是主要版本,代码有很大变动,不能向后兼容的修改
-
第二个是次要版本,可以向后兼容,升级后不会造成影响的修改
-
第三个是补丁版本,修改小bug,同样不会造成影响的修改
在 package 中,可以看到安装完包之后,版本前面有个符号,比如
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
^ 表示更新次要版本和补丁,不会更新主要版本,当你运行 npm update 的时候,它会自动更新。
如果想要更新主要版本,可以运行 npm i react@latest。安装特定大版本的话 npm i react@16 就会安装 react 16 版本。安装特定次要版本的话 npm i react@~16.2
package-lock.json
当和其他人协作时,如果新 clone 一个项目,只看 package.json 的话,不同人安装的 次要版本、补丁版本 可能是不同的,如果某个版本的包有什么问题,项目就可能跑不起来
package-lock.json 作用是规定安装包的特定版本,npm 会根据 package-lock.json 中的特定版本安装依赖包,保证你安装的版本和别人的相同。