npm 包管理器
npm 入门
什么是 npm?
npm 是 Node.js 的标准包管理器。新版的 node.js 已经集成了 npm。可以通过输入 npm -v 来测试是否成功安装;如果你安装的是旧版本的 npm,可以很容易得通过 npm 命令来升级,命令如下:
1
2
3
4
sudo npm install npm -g
# 如果是 Window 系统使用以下命令即可:
npm install npm -g
npm init
1
npm init
通过
npm init命令为你的应用创建一个package.json文件,该命令要求你输入几个参数,例如此应用的名称、版本号、描述、指定的入口文件,你可以直接按回车键接受大部分默认设置即可。
npm init 命令的作用是将文件夹初始化为一个包,交互式创建 package.json 文件。 package.json 文件是包的配置文件,每个包都必须要有, package.json 文件内容:
1
2
3
4
5
6
7
8
9
10
11
{
"name": "1-npm", #包的名字
"version": "1.0.0", #包的版本
"description": "", #包的描述
"main": "index.js", #包的入口文件
"scripts": { #脚本配置
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "", #作者
"license": "ISC" #开源证书
}
npm 安装模块 npm install
npm 安装 Node.js 模块语法格式如下:npm install <Module Name>
示例:使用 npm 命令安装常用的 Node.js web 框架模块 express:
1
2
npm install express
# npm在哪个目录下执行命令,node_modules目录就在哪生成
安装好之后,express 包就放在了工程目录下的 node_modules 目录中,因此在代码中只需要通过 require(‘express’) 的方式就好,无需指定第三方包路径。
1
var express = require('express');
全局安装与本地安装
npm 的包安装分为本地安装(local)、全局安装(global)两种,从敲的命令行来看,差别只是有没有 -g 而已,比如:
1
2
npm install express # 本地安装
npm install express -g # 全局安装
如果出现以下错误:
npm err! Error: connect ECONNREFUSED 127.0.0.1:8087
解决办法为:
npm config set proxy null
本地安装
- 将安装包放在
node_modules下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成node_modules目录。 - 可以通过
require()来引入本地安装的包。
全局安装
- 将安装包放在
/usr/local(Windows 下的$HOME\AppData\Roaming\npm) 下或者你 node 的安装目录 - 可以直接在命令行里使用。
npm install -S/-D/-g 区别
主要区别就是依赖配置写入 package.json 文件的位置不同而已;
npm install 本身就有一个别名 npm i
-S –save
语法:` npm i module_name -S
即 npm install module_name --save 写入 dependencies,发布到生产环境
这样安装是局部安装的,会写进 package.json 文件中的 dependency 里。 dependencies: 表示生产环境下的依赖管理; 说白了你安装一个库如果是用来构建你的项目的,比如 echarts、element-ui,是实际在项目中起作用,就可以使用 -s 来安装
-D –save-dev
语法:npm i module_name -D
即 npm install module_name –save-dev 写入 devDependencies,发布到开发环境
这样安装是局部安装的,会写进 package.json 文件中的 devDependencies 里。 devDependencies :表示开发环境下的依赖管理 如果你安装的库是用来打包的、解析代码的,比如 webpack、babel,就可以用 -d 来安装,项目上线了,这些库就没用了
-g –global?
语法:npm i module_name -g
即 global 全局安装 (命令行使用)
npm install module_name -g,表示全局安装,安装一次过后,你就可在其他地方直接用啦
不加参数
npm i module_name 即 本地安装 (将安装包放在当前目录下的 node_modules 目录下)
npm5 开始通过 npm install module_name 什么都不加 和 npm install module_name –save 一样,都是局部安装并会把模块自动写入 package.json 中的 dependencies 里。
注意:-D,-S 分别是 –save-dev 和 –save 的简写,默认就是 -S,可以省略不写
查看安装信息 list
1
npm list -g # 查看所有全局安装的模块
如果要查看某个模块的版本号,可以使用命令如下:npm list xxx
package.json 文件
package.json 位于模块的目录下,用于定义包的属性,以 express 模块的 package.json 来看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{
"name": "express",
"description": "Fast, unopinionated, minimalist web framework",
"version": "4.18.2",
"author": "TJ Holowaychuk <tj@vision-media.ca>",
"contributors": [
"Aaron Heckmann <aaron.heckmann+github@gmail.com>",
"Ciaran Jessup <ciaranj@gmail.com>",
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Guillermo Rauch <rauchg@gmail.com>",
"Jonathan Ong <me@jongleberry.com>",
"Roman Shtylman <shtylman+expressjs@gmail.com>",
"Young Jae Sim <hanul@hanul.me>"
],
"license": "MIT",
"repository": "expressjs/express",
"homepage": "http://expressjs.com/",
"keywords": [
"express",
"framework",
"sinatra",
"web",
"http",
"rest",
"restful",
"router",
"app",
"api"
],
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.1",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.5.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.2.0",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.7",
"qs": "6.11.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.18.0",
"serve-static": "1.15.0",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"devDependencies": {
"after": "0.8.2",
"connect-redis": "3.4.2",
"cookie-parser": "1.4.6",
"cookie-session": "2.0.0",
"ejs": "3.1.8",
"eslint": "8.24.0",
"express-session": "1.17.2",
"hbs": "4.2.0",
"marked": "0.7.0",
"method-override": "3.0.0",
"mocha": "10.0.0",
"morgan": "1.10.0",
"multiparty": "4.2.3",
"nyc": "15.1.0",
"pbkdf2-password": "1.2.1",
"supertest": "6.3.0",
"vhost": "~3.0.2"
},
"engines": {
"node": ">= 0.10.0"
},
"files": [
"LICENSE",
"History.md",
"Readme.md",
"index.js",
"lib/"
],
"scripts": {
"lint": "eslint .",
"test": "mocha --require test/support/env --reporter spec --bail --check-leaks test/ test/acceptance/",
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"test-tap": "mocha --require test/support/env --reporter tap --check-leaks test/ test/acceptance/"
}
}
package.json 属性说明
- name - 包名。
- version - 包的版本号。
- description - 包的描述。
- homepage - 包的官网 url 。
- author - 包的作者姓名。
- contributors - 包的其他贡献者姓名。
- dependencies - 依赖包列表。如果依赖包没有安装,npm 会自动将依赖包安装在 node_module 目录下。
- devDependencies 开发阶段的依赖,不打包进去
- repository - 包代码存放的地方的类型,可以是 git 或 svn,git 可在 Github 上。
- main - main 字段指定了程序的主入口文件,
require('moduleName')就会加载这个文件。这个字段的默认值是模块根目录下面的index.js。 - keywords - 关键字
scripts
可以通过配置 package.json 中的 scripts 属性来启动项目
1
2
3
4
5
6
{
"scripts": {
"server": "node server.js",
"start": "node index.js",
},
}
配置完成之后,执行命令启动项目:
npm run server npm run start
不过 start 比较特别,使用时可以省略 run
npm start
npm run 有自动向上级目录查找的特性,跟 require 函数一样
devDependencies 与 dependencies 有什么区别呢?
- devDependencies 表示
开发环境下的依赖管理,里面的插件只用于开发环境(开发时依赖),不用于生产环境,例如 vite、sass 插件等 (打包后就跟他没关系了); - dependencies 表示
生产环境下的依赖管理,里面的插件只用于生产环境(运行时依赖),是需要发布到生产环境的,例如 vue、element-plus 等等。
这种说法不能说完全错误,但至少是不够清晰的,我们很难因此真正理解它们,所以就会在日常工作中经常踩依赖包版本的坑。
甚至有一种精简化后更广为流传的说法:dependencies = 生产依赖,devDependencies = 开发依赖,更是对我们产生了误导。
开发 Web 应用 时,即使将所有依赖声明在 devDependencies 中,也不会影响应用的成功构建、打包与运行。
因此 dependencies = 生产依赖,devDependencies = 开发依赖 的说法是片面的。 我们常说的 ” 生产环境 “、” 开发环境 “ 是构建时行为,构建并不是包管理器的职责,而是 webpack、rollup、vite 的工具的工作,此时包管理器起的作用仅仅是执行脚本而已。 各种包管理器处理 dependencies 和 devDependencies 差异的行为都发生在依赖安装时期,即 npm install 的过程中。
包管理器将以项目的 package.json 为起点,安装所有 dependencies 与 devDependencies 中声明的依赖。但是对于这些一级依赖项具有的更深层级依赖,在深度遍历的过程中,只会安装 dependencies 中的依赖,忽略 devDependencies 中的依赖。
为什么会这样呢?因为包管理器认为:作为包的使用者,我们当然不用再去关心它们开发构建时的依赖,所以会为我们忽略 devDependencies。 而 dependencies 是包产物正常工作所依赖的内容,当然有必要安装。
回到 Web 应用 开发的场景,Web 应用 的产物往往部署到服务器,不会发布到 npm 仓库供其他用户使用,而包管理器对于一级依赖,无论 dependencies 还是 devDependencies 都会悉数安装。这种情况下, dependencies 与 devDependencies 可能真的只有语义化约定的作用了。
卸载模块 uninstall
npm uninstall express
卸载后,你可以到 /node_modules/ 目录下查看包是否还存在,或者使用以下命令查看:
npm ls
更新模块 update
$ npm update express
搜索模块 search
$ npm search express
创建模块 init
创建模块,package.json 文件是必不可少的。我们可以使用 NPM 生成 package.json 文件,生成的文件包含了基本的结果。
- 按照提示来输入基本信息,在最后输入 “yes” 后会生成 package.json 文件。
1
npm init
- 在 npm 资源库中注册用户(使用邮箱注册):
1
npm adduser
- 发布模块
1
npm publish
版本号
NPM 使用 语义版本号 来管理代码:语义版本号分为 X.Y.Z 三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。
- 如果只是修复 bug,需要更新 Z 位。
- 如果是新增了功能,但是向下兼容,需要更新 Y 位。
- 如果有大变动,向下不兼容,需要更新 X 位。
版本号有了这个保证后,在申明第三方包依赖时,除了可依赖于一个固定版本号外,还可依赖于某个范围的版本号。例如 "argv": "0.0.x" 表示依赖于 0.0.x 系列的最新版 argv。
NPM 支持的所有版本号范围指定方式可以查看官方文档。
NPM 常用命令
- NPM 提供了很多命令,例如 install 和 publish,使用 npm help 可查看所有命令。
- 使用
npm help <command>可查看某条命令的详细帮助,例如 npm help install。 - 在 package.json 所在目录下使用
npm install.-g可先在本地安装当前命令行程序,可用于发布前的本地测试。 - 使用
npm update <package>可以把当前目录下 node_modules 子目录里边的对应模块更新至最新版本。 - 使用
npm update <package> -g可以把全局安装的对应命令行程序更新至最新版。 - 使用
npm cache clear可以清空 NPM 本地缓存,用于对付使用相同版本号发布新版本代码的人。 - 使用
npm unpublish <package>@<version>可以撤销发布自己发布过的某个版本代码。
npx
npm 从 5.25.2 版开始,增加了 npx 命令。
npx 的作用
npm只能管理包的依赖,npx则可以快捷的运用包中的命令行工具和其他可执行文件,让项目内部安装的模块用起来更方便。- 当执行
npx <command>相关命令的时候,npx会先本地找(可以是项目中的也可以是本机的)寻找这个command。- 找到了:就用本地的版本
- 没找到:直接下载最新版本(这里是在缓存里),完成命令要求
- 使用完之后就会完全清除,不会在本机或项目留下任何东西
- 这样就不会污染本机、永远使用最新版本的
dependency
.npmrc
什么是.npmrc
.npmrc,可以理解成 npm running configuration, 即 npm 运行时配置文件。可以在.npmrc 中进行配置:从哪里下载、下载到电脑什么路径等。不止存在一个.npmrc 文件,而是有多个。在我们安装包的时候,npm 按照如下顺序读取这些配置文件:
.npmrc 位置
- 项目配置文件 (
/project/.npmrc, Windows:"C:\\Users\\Administrator\\AppData\\Roaming\\npm\\etc\\npmrc"):你可以在项目的根目录下创建一个.npmrc 文件,只用于管理这个项目的 npm 安装。 - 用户配置文件 (
~/.npmrc):在你使用一个账号登陆的电脑的时候,可以为当前用户创建一个.npmrc 文件,之后用该用户登录电脑,就可以使用该配置文件。可以通过 npm config get userconfig 来获取该文件的位置。 - 全局配置文件 (
$PREFIX/etc/npmrc): 一台电脑可能有多个用户,在这些用户之上,你可以设置一个公共的.npmrc 文件,供所有用户使用。该文件的路径为:$PREFIX/etc/npmrc,使用 npm config get prefix 获取$ PREFIX。如果你不曾配置过全局文件,该文件不存在。 - npm 内嵌配置文件 (
/path/to/npm/npmrc):最后还有 npm 内置配置文件,基本上用不到
如何设置.npmrc?
1、设置项目配置文件 在项目的根目录下新建 .npmrc 文件,在里面以 key=value 的格式进行配置。比如要把 npm 的源配置为淘宝源,可以参考一下代码:
1
registry=https://registry.npm.taobao.org
2、设置用户配置文件 直接通过 npm config get userconfig 命令找到该文件的路径,然后直接仿照上述方法该文件,也可以通过 npm config set 命令继续设置,命令如下:
1
2
config set registry https://registry.npm.taobao.org
# 最终,命令行会帮助我们修改对应的配置文件。只不过使用命令行更加快捷。
删除,直接编辑 .npmrc 删除,或只用命令:
1
npm config delete registry
3、设置全局配置文件 方法和设置用户配置文件如出一辙,只不过在使用命令行时需要加上 -g 参数。
1
npm config set registry https://registry.npm.taobao.org -g
常用的 npm 设置命令
1
2
3
4
5
6
7
npm config set <key> <value> [-g|--global] //给配置参数key设置值为value;
npm config get <key> //获取配置参数key的值;
npm config delete <key> //删除置参数key及其值;
npm config list [-l] //显示npm的所有配置参数的信息;
npm config edit //编辑配置文件
npm get <key> //获取配置参数key的值;
npm set <key> <value> [-g|--global] //给配置参数key设置值为value;
.npmrc 模板
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ===============================
# npm 用户全局配置 —— happy coder 等命令全局可用
# ===============================
# 全局安装目录(避免 sudo 权限问题)
prefix=/Users/xxx/.npm-global
# 国内高速源(原 npm 官方源网络不稳定)
registry=https://registry.npmmirror.com
# 启用严格 SSL 校验(更安全)
strict-ssl=true
# 安装依赖时锁定精确版本
save-exact=true
# 设置缓存路径(可选)
cache=/Users/xxx/.npm-global/cache
# 日志级别(info / warn / error)
loglevel=info
# 不显示进度条(可选,节省输出)
progress=false
问题
npm install 运行卡住不动
npm config set registry http://registry.cnpmjs.org
npm root 权限问题
在 Mac 上全局 (-g) 安装包时,需要 root 权限,用下面 shell 脚本可修复,mac_npm_fix.sh:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/bin/bash
# ===============================
# Mac NPM 权限修复 + 无 sudo 全局安装环境配置
# ===============================
# 目的:
# 1. 解决 npm 安装全局包需要 sudo 权限的问题
# 2. 配置一个自己的全局安装目录 ~/.npm-global
# 3. 确保 shell 能找到这些全局包的命令
# ===============================
set -e # 遇到错误立即退出(更安全)
echo "📦 1. 检测当前用户和组..."
USER_NAME=$(whoami) # 当前登录用户
GROUP_NAME=$(id -gn) # 当前用户组
echo "当前用户: $USER_NAME"
echo "当前用户组: $GROUP_NAME"
echo "🔧 2. 修复 npm 缓存目录权限..."
# npm 在执行时会缓存一些文件到 ~/.npm,如果权限不对会导致安装失败
if [ -d "$HOME/.npm" ]; then
sudo chown -R "$USER_NAME":"$GROUP_NAME" "$HOME/.npm"
echo "✅ 已修复 ~/.npm 权限"
else
echo "ℹ ~/.npm 目录不存在,跳过"
fi
echo "🔧 3. 修复全局安装目录权限..."
# ~/.npm-global 是我们自定义的全局安装目录,避免写到 /usr/local 需要 sudo
if [ -d "$HOME/.npm-global" ]; then
sudo chown -R "$USER_NAME":"$GROUP_NAME" "$HOME/.npm-global"
echo "✅ 已修复 ~/.npm-global 权限"
else
echo "📁 创建 ~/.npm-global 目录"
mkdir -p "$HOME/.npm-global"
sudo chown -R "$USER_NAME":"$GROUP_NAME" "$HOME/.npm-global"
fi
echo "⚙️ 4. 设置 npm 全局安装目录为 ~/.npm-global ..."
# -----------------------------
# 第4步:只影响 npm 的安装位置
# 意思是以后 npm install -g xxx 会把包放到 ~/.npm-global/bin(可执行文件) 和 ~/.npm-global/lib(包文件)
# -----------------------------
npm config set prefix "$HOME/.npm-global"
# 额外:写入到用户级配置文件 ~/.npmrc,保证长期生效
grep -q "prefix=" "$HOME/.npmrc" || echo "prefix=$HOME/.npm-global" >> "$HOME/.npmrc"
echo "🌍 5. 将 ~/.npm-global/bin 添加到 PATH ..."
# -----------------------------
# 第5步:影响 shell 找命令的路径
# npm 安装后,可执行文件在 ~/.npm-global/bin,如果 PATH 里没有这个目录,执行命令会提示 not found
# 所以必须把这个目录加到 PATH,这样比如输入 happy 就能找到 ~/.npm-global/bin/happy
# -----------------------------
for rcfile in "$HOME/.zshrc" "$HOME/.bashrc"; do
if [ -f "$rcfile" ]; then
grep -q ".npm-global/bin" "$rcfile" || echo 'export PATH=$HOME/.npm-global/bin:$PATH' >> "$rcfile"
fi
done
echo "➡️ 6. 请运行: source ~/.zshrc 或重新打开终端以使 PATH 生效"
echo "🚀 7. 完成!现在你可以无 sudo 全局安装 npm 包了"
echo "例如: npm i -g @anthropic-ai/claude-code happy-coder"
其他 js 包管理器
见 [[其他 js 包管理器]]


