当前位置 : 首页 » 文章分类 :  开发  »  NPM使用笔记

NPM使用笔记

NPM(Node Package Manager) 是随同 NodeJS 一起安装的包管理工具,能解决 NodeJS 代码部署上的很多问题。

常见的使用场景有以下几种:
允许用户从 NPM 服务器下载别人编写的第三方包到本地使用。
允许用户从 NPM 服务器下载并安装别人编写的命令行程序到本地使用。
允许用户将自己编写的包或命令行程序上传到 NPM 服务器供别人使用。
通过输入 npm -v 来测试 npm 是否成功安装


npm install 安装模块

npm 的包安装分为本地安装(local)、全局安装(global)两种,从敲的命令行来看,差别只是有没有 -g 而已:

  • npm install -g 模块名称 全局安装,用于安装全局可用的命令行工具,例如 claude-code, hexo
  • npm install 模块名称 本地安装,用于安装仅在某个项目(文件夹)内使用的依赖

npm install pkg 本地安装(默认)

本地安装(Local Installation) 是默认安装方式。
安装在​​当前项目(运行 npm 命令时所在的目录)目录​​下的 ./node_modules 文件夹中,如果没有 node_modules 目录会自动创建。
用于为​​特定项目​​提供依赖。依赖信息记录在项目的 package.json 文件的 dependenciesdevDependencies 中。

安装之前,npm install 会先检查 node_modules 目录之中是否已经存在指定模块。如果存在,就不再重新安装了,即使远程仓库已经有了一个新版本,也是如此。
如果你希望,一个模块不管是否安装过,npm 都要强制重新安装,可以使用 -f--force 参数: npm install <packageName> --force

特点:

  • 项目隔离性:​​ 每个项目拥有独立的 node_modules,依赖版本互不影响(避免版本冲突)。
  • 版本控制:​​ package.json + package-lock.json 锁定了精确依赖版本,保证不同环境(开发、生产)一致性。
  • 依赖引用:​​ 项目代码通过 require('package_name')ES6 import 引入本地安装的包。
  • ​​启动脚本:​​ 在 package.json 的 scripts 中定义的项目命令(如 npm start, npm test)可直接使用本地安装的 CLI 工具(无需全局安装)。
  • 适用场景:​​ Web 框架(React, Vue, Angular)、功能库(Lodash, Axios)、构建工具(Webpack, Babel - 作为项目依赖时)、测试库(Jest, Mocha)等。

npm install -g pkg 全局安装

通过 -g 参数指定 全局安装(Global Installation)
安装在​​系统全局目录​​中(与具体项目无关)。​
​核心目的是为了安装供​​命令行(CLI)工具​​在终端/命令行中​​全局使用​​。

通过 npm root -g 命令可查看全局安装路径,例如:

  • /opt/homebrew/lib/node_modules Mac 上
  • /usr/local/lib/node_modules Unix 上
  • %AppData%\npm\node_modules Windows 上

特点:

  • 全局可用性:​​ 安装后,其提供的​​命令行命令​​可在系统任何路径下执行(需确保全局安装目录在系统的 PATH 环境变量中)。
  • 非代码依赖:​​ 在项目代码中​​不能​​通过 require 或 import 引入全局安装的包(除非项目本地也安装了)。
  • 版本单一性:​​ 整个系统通常只有一个版本,可能导致不同项目对全局工具版本要求不同时产生冲突。
  • 适用场景:​​ 提供​​终端命令​​的工具包

典型的全局工具包括:

  • 脚手架工具:create-react-app, vue-cli, @angular/cli, expo-cli
  • 构建/任务工具:gulp-cli, grunt-cli
  • 包管理工具:yarn, pnpm (可以用npm安装它们自身)
  • 实用工具:nodemon (自动重启Node应用), http-server (快速启动静态服务器), typescript (tsc命令)
  • 跨项目工具:eslint, prettier (若需全局使用其CLI)

npm install -g npm@latest 升级全局npm版本

全局升级 npm 自身的版本到最新版
npm install -g npm@latest


使用 package.json

​npm 5.0.0 及以上版本​​中,npm install <package_name> 命令默认就会将依赖包及其版本添加到 package.json 文件中的 dependencies 部分。

npm install 模块 安装指定模块,从 npm 5 开始,npm install <package_name> ​​自动等效于​​ npm install <package_name> --save 这意味着不需要显式添加 --save 选项,npm 就会把依赖写入 package.json

npm install 模块 --save 安装好后写入 package.json 的 dependencies 中(生产环境依赖)

npm install 模块 --save-dev 安装好后写入 package.json 的 devDepencies 中(开发环境依赖)

npm install <Module Name> --save 安装的同时,将信息写入 package.json 中。
项目路径中如果有 package.json 文件时,直接使用 npm install 方法就可以根据 dependencies 配置安装所有的依赖包


npm install --unsafe-perm

就是说 npm 出于安全考虑不支持以 root 用户运行,即使你用 root 用户身份运行了,npm 会自动转成一个叫 nobody 的用户来运行,而这个用户几乎没有任何权限。这样的话如果你脚本里有一些需要权限的操作,比如写文件(尤其是写 /root/.node-gyp ),就会崩掉了。

为了避免这种情况,要么按照 npm 的规矩来,专门建一个用于运行 npm 的高权限用户;要么加 –unsafe-perm 参数,这样就不会切换到 nobody 上,运行时是哪个用户就是哪个用户,即使是 root。

一劳永逸的方法:
npm config set unsafe-perm 针对当前用户的
npm config -g set unsafe-perm 全局的

https://docs.npmjs.com/misc/config#unsafe-perm

permission denied 问题

npm install 的时候,经常会碰到一个非常匪夷所思的错误,那就是:即使使用了 sudo,也可能会报权限错误 permission denied。

例如 sudo npm update hexo

$ sudo npm update hexo
Password:

> fsevents@1.2.9 install /Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents
> node install

node-pre-gyp WARN Using needle for node-pre-gyp https download
node-pre-gyp WARN Pre-built binaries not installable for fsevents@1.2.9 and node@10.4.0 (node-v64 ABI, unknown) (falling back to source compile with node-gyp)
node-pre-gyp WARN Hit error EACCES: permission denied, mkdir '/Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents/lib'
gyp ERR! configure error
gyp ERR! stack Error: EACCES: permission denied, mkdir '/Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents/build'
gyp ERR! System Darwin 17.7.0
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64/fse.node" "--module_name=fse" "--module_path=/Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64" "--napi_version=3" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v64"
gyp ERR! cwd /Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents
gyp ERR! node -v v10.4.0
gyp ERR! node-gyp -v v5.0.3
gyp ERR! not ok

解决方法:
在npm install的时候,同时使用sudo--unsafe-perm
sudo npm install --unsafe-perm

$ sudo npm install --unsafe-perm
Password:

> fsevents@1.2.9 install /Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents
> node install

node-pre-gyp WARN Using needle for node-pre-gyp https download
[fsevents] Success: "/Users/si.ma/git/madaimeng_backup/node_modules/hexo-fs/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64/fse.node" is installed via remote

> fsevents@1.2.9 install /Users/si.ma/git/madaimeng_backup/node_modules/nunjucks/node_modules/fsevents
> node install

node-pre-gyp WARN Using needle for node-pre-gyp https download
[fsevents] Success: "/Users/si.ma/git/madaimeng_backup/node_modules/nunjucks/node_modules/fsevents/lib/binding/Release/node-v64-darwin-x64/fse.node" is installed via remote
added 138 packages from 35 contributors and audited 7136 packages in 7.598s
found 6 vulnerabilities (2 low, 3 moderate, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

sudo npm install 时,报错 permission denied 的解决方案
https://newsn.net/say/sudo-npm-install-permission.html


node_modules/.bin 模块的可执行文件

当通过 npm 安装一个包时(无论是 dependencies 还是 devDependencies),如果这个包提供了一个可以在命令行中调用的​​可执行文件​​(通常在其 package.json 中有 “bin” 字段声明),那么 npm 就会在项目的 node_modules/.bin 目录下创建指向这些可执行文件的​​符号链接(Symlinks)​​(在 Windows 上可能是 .cmd 或 .ps1 文件)。


npm cli

蕾西 npm i 安装依赖,但是严格按 package-lock.json 安装,适用于 CI/CD 或生产环境
完全依赖 package-lock.json,不修改它


npm list 查看安装包

npm list 查看本地已安装模块

npm list --depth=0 查看本地安装包
–depth 表示深度,我们使用的模块会有依赖,深度为零的时候,不会显示依赖模块

npm list --depth --global 查看全局安装包

npm list -g 查看全局已安装模块

npm list –depth=0 仅查看直接依赖

仅列出项目直接依赖


npm root -g 查看全局安装路径

npm root -g
/opt/homebrew/lib/node_modules

npm update 更新模块

npm update <Module Name>
它会先到远程仓库查询最新版本,然后查询本地版本。如果本地版本不存在,或者远程版本较新,就会安装。

npm update <package> 可以把当前目录下 node_modules 子目录里边的对应模块更新至最新版本。
npm update <package> -g 可以把全局安装的对应命令行程序更新至最新版。


npm uninstall 删除模块

删除全局模块
npm uninstall -g <package>

删除本地模块
npm uninstall 模块

删除本地模块时你应该思考的问题:是否将在 package.json 上的相应依赖信息也消除?
npm uninstall 模块:删除模块,但不删除模块留在package.json中的对应信息
npm uninstall 模块 --save 删除模块,同时删除模块留在package.json中dependencies下的对应信息
npm uninstall 模块 --save-dev 删除模块,同时删除模块留在package.json中devDependencies下的对应信息

例如

sudo npm uninstall hexo-generator-search --save

Password:
removed 1 package and audited 7132 packages in 4.202s
found 6 vulnerabilities (3 low, 2 moderate, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details

npm search 搜索模块

npm search <Module Name>

npm prune 清理无效包

手动删除 package.json 中的依赖后,执行 npm prune 可删除所有 package.json 中不存在的包


package.json

package.json 中最重要的属性是 name 和 version 两个属性,这两个属性是必须要有的,否则模块就无法被安装,这两个属性一起形成了一个 npm 模块的唯一标识符。

package.json 开发者声明的依赖蓝图​

package.json 是由开发者手动维护的,通过 npm install <package> --save / --save-dev 命令写入或更新,或者直接编辑
package.json ​声明了​​需要哪些包以及愿意接受的大致版本范围,但并不锁定确切的版本。
package.json 主要关注​​顶级依赖(直接依赖)​​。

package.json 的目的:

  • 列出项目​​直接依赖​​的包(在 dependencies、devDependencies、optionalDependencies 或 peerDependencies 中)。
  • 定义项目元数据:​​ 包含项目名称、版本、描述、入口点、脚本命令(scripts)、作者信息、仓库地址等。
  • 指定兼容版本范围:​​ 使用 语义化版本 SemVer 范围(如 ^1.2.3, ~1.2.0, >2.0.0, 2.x)来定义你的项目能接受的依赖包版本。

例如:

{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.18.0", // 声明需要 express,兼容 4.18.0 到 5.0.0(不含)之间
    "lodash": "~4.17.21"  // 声明需要 lodash,兼容 4.17.21 到 4.18.0(不含)之间
  },
  "devDependencies": {
    "eslint": "^8.0.0"
  }
}

package-lock.json 精确依赖树的权威快照​

package-lock.json 用于描述​​整个依赖树​​:精确到每一个直接依赖和所有层级的间接依赖。
package-lock.json 是由 npm 自动生成和维护的,​永远不要手动编辑 package-lock.json ​​它由 npm 在运行 npm installnpm install <package> 安装更新依赖时自动生成或更新。
package-lock.json 精确描述​​了当前 node_modules 文件夹中所有内容的确切状态,像一个时间点的详细快照。
package-lock.json 只包含确切的版本号(如 “version”: “4.18.2”),没有任何语义化范围符号(^, ~)。

package-lock.json 的目的:

  • 锁定依赖树:​​ 精确描述 node_modules 目录中​​实际安装​​的​​每一个包的确切版本​​(包括所有的​​直接依赖​​和​​嵌套的间接依赖/传递依赖​​)。
  • 确保一致性:​​ 是 npm 实现​​确定性安装​​和​​依赖一致性​​的核心。它保证在任何时候(不同的机器、不同的时间点)、任何人运行 npm install 时,只要存在有效的 package-lock.json 就会安装​​完全相同的依赖树​​。
  • 描述依赖关系结构:​​ 不仅仅记录版本,还记录包从哪里下载(resolved URL)、包的完整性校验和(integrity hash),以及包之间的依赖关系结构。

package-lock.json 对依赖安装/更新的影响

当 package-lock.json 存在时

  • npm install 会​忽略 package.json 中的语义化版本范围,完全按照 package-lock.json 中描述的精确版本和依赖结构​​去安装依赖。这是保证一致性的关键!
  • npm install <package>@<version> 手动安装指定版本依赖时,会​​自动更新 package-lock.json 来反映这个新确切的依赖树状态​​。这通常也会更新 package.json 中该依赖的版本范围。
  • npm update 会根据 package.json 中定义的语义化版本范围,查找并安装满足范围的最新版本(可能是次要版本或补丁版本),并​​自动更新 package-lock.json​​ 到新的精确状态。

当 package-lock.json ​​不存在​​时:

  • npm install 会根据 package.json 中的依赖声明,解析出最新的、符合语义化版本范围的依赖树来安装。安装完成后,npm 会自动​​生成一个新的 package-lock.json​​ 文件,记录下这次安装的精确快照。此时安装的结果可能会在不同时间或不同环境中因新版本的发布而略有差异。

dependencies 生产依赖

dependencies 描述项目​​在生产环境运行所必需​​的依赖包

核心依赖通过 dependencies 描述,例如:
框架/库:react, vue, express, lodash
UI 组件:antd, material-ui
工具库:axios, moment


devDependencies 开发依赖

devDependencies 描述仅在​​开发、测试和构建过程​​中需要的依赖包
生产环境部署时​​自动排除​​(通过 NODE_ENV=production)

常用于安装一些本地构建、调试、测试框架,例如:
构建工具:webpack, vite, babel
测试框架:jest, mocha, cypress
代码质量:eslint, prettier
类型检查:typescript, @types/* (TS 类型定义)

安装

npm install <package-name> --save-dev
# 或简写
npm i <package-name> -D

SemVer 语义化版本控制

npm 使用 语义化版本 SemVer 描述版本号
主版本号.次版本号.修订号
MAJOR.MINOR.PATCH

在 package.json 中,dependencies 和 devDependencies 都是标准的 JSON 对象,格式相同。
dependencies 是一个对象,配置模块依赖的模块列表,key是模块名称,value是版本范围,版本范围是一个字符,可以被一个或多个空格分割。

{
  "dependencies": {
    "包名": "版本描述符",
    // 更多生产依赖...
  },
  "devDependencies": {
    "包名": "版本描述符",
    // 更多开发依赖...
  }
}

语义化版本控制 SemVer
4.18.2 精确版本,拒绝任何其他版本
^4.18.2 兼容版本,最常用,默认行为,允许次版本和补丁更新​​,允许的版本范围是 大于等于 4.18.2 且 小于 5.0.0,​拒绝 5.0.0
~4.18.2 安全版本,约等于,仅允许补丁更新​,允许的版本号范围是 大于等于 4.18.2 且 小于 4.19.0,​​拒绝 4.19.0
4.18.x 通配符,匹配特定版本段的任何补丁更新,等效于 ~4.18.0
>4.17.0 <4.19.0 区间描述符​,指定版本安装范围,安装符合范围的最高版本,例如 >version >=version <version
4.18.2-beta.3 预发布版本​,安装特定预发布版本,需明确指定完整版本号
*"" ​​任意版本,安装最新版本(​​高危操作​​),可能引入破坏性更新
"latest" 安装最新正式版,等效于 *

特殊依赖
dependencies 也可以被指定为一个 git 地址或者一个压缩包地址。
1、Git 仓库依赖:

{
  "dependencies": {
    "private-pkg1": "git+https://github.com/user/repo.git",  // 指定git仓库
    "pkg-on-branch": "github:user/repo#branch-name",  // 指定特定分支
    "pkg-on-commit": "git+https://github.com/user/repo#commit-hash"  // 指定特定提交
  }
}

2、本地文件/压缩包依赖

{
  "devDependencies": {
    "local-pkg": "file:./path/to/local-module",
    "tarball": "https://registry.com/pkg-1.2.3.tgz"
  }
}

scripts 自定义脚本字段

npm run 是一个在项目中执行自定义脚本的接口,其能力来源于 package.json 文件中的 scripts 字段。​

scripts 字段是 npm run 的 『指令集』
scripts 字段是一个 JSON 对象,属性名(键)是自定义的脚本名称(如 dev, serve, build, lint),属性值(值)是该脚本实际要执行的 ​​shell 命令​​。

例如 Vue3 项目 package.json 文件中的 scripts 字段如下:

{
  "name": "my-vue3-app",
  "version": "0.1.0",
  "scripts": {
    "dev": "vite",       // 用于启动开发服务器
    "build": "vite build", // 用于构建生产包
    "preview": "vite preview" // 用于预览生产包
    "build-only": "vite build",
    "type-check": "vue-tsc --build",
    "lint": "eslint . --fix",
    "format": "prettier --write src/"
  },
  "dependencies": { ... },
  "devDependencies": { ... }
}

npm run script-name 执行过程

在项目根目录(即包含 package.json 的目录)下运行 npm run script-name 例如 npm run dev 时,内部的执行顺序是:
1、查找 package.json:​​ npm 首先在当前目录及其父目录中查找 package.json 文件。
2、定位 scripts:​​ 找到 package.json 后,npm 会查找其中的 scripts 对象。
3、匹配脚本名:​​npm 检查 scripts 对象中是否存在一个键(属性名)与你输入的 script-name(例如 dev)匹配。
4、执行命令字符串:如果找到了匹配的脚本,npm 会将其值(例如 vite )作为一个 ​​shell 命令​​ 在一个​​子进程中​​执行。
执行脚本命令时有个关键点:环境变量 PATH 的修改:​​ npm 在执行这个命令前,会做一件非常重要的事情:它会将项目本地的 node_modules/.bin 目录 ​​临时地添加到​​ shell 的 PATH 环境变量​​的最前面​​。
5、vite 可执行文件是一个 Node.js 脚本。它被执行后,读取项目的配置文件(如 vite.config.js),然后启动开发服务器(包含模块热重载 - HMR)、编译 Vue 单文件组件(.vue)等,最终让你的 Vue3 应用在浏览器中运行起来。


npm 常用软件

npm-pack-all 打离线安装包

npm-pack-all 是一个用于将 Node.js 项目的依赖项打包成 .tgz 文件的工具,其核心功能是将项目中的生产依赖(dependencies)和开发依赖(devDependencies)递归打包,便于离线分发或部署。

使用场景

  • 离线环境部署:在无网络连接的环境中,通过 .tgz 文件安装依赖(npm install artifact.tgz)。
  • 私有库/组件分发:将团队内部私有库打包后分发给成员,确保版本一致性。

npm-pack-all 与 npm pack 的区别:

  • npm pack 仅打包当前目录的模块(如项目自身代码),不处理依赖项。
  • npm-pack-all 递归打包所有依赖项,生成包含完整依赖树的 .tgz 文件。

npm-check-updates

npm-check-updates
https://www.npmjs.com/package/npm-check-updates

npm-check-updates(NCU) 更新 package.json 中的依赖到最新版本,忽略指定的版本号。

安装npm-check-updates

npm install -g npm-check-updates

ncu 检测版本更新

进入 package.json 所在目录,执行 ncu 检查 package.json 中依赖的可用版本更新
这里以 hexo 为例:

# ncu
Checking /home/centos/git/hexo/package.json
[====================] 12/12 100%

 hexo                     ^3.9.0  →  ^5.4.0
 hexo-deployer-git        ^0.1.0  →  ^3.0.0
 hexo-generator-archive   ^0.1.4  →  ^1.0.0
 hexo-generator-category  ^0.1.3  →  ^1.0.0
 hexo-generator-index     ^0.2.0  →  ^2.0.0
 hexo-generator-tag       ^0.2.0  →  ^1.0.0
 hexo-renderer-ejs        ^0.2.0  →  ^1.0.0
 hexo-renderer-marked     ^1.0.1  →  ^4.0.0
 hexo-renderer-stylus     ^0.3.1  →  ^2.0.1
 hexo-server              ^0.2.0  →  ^2.0.0
 hexo-tag-bootstrap        0.0.8  →   0.2.1
 hexo-wordcount           ^2.0.1  →  ^6.0.1

Run ncu -u to upgrade package.json

ncu -u 更新package.json

进入 package.json 所在目录,执行 ncu -u 可以更新 package.json 中的依赖版本到最新。
之后再执行 npm install 根据 package.json 中的版本号更新依赖包。

注意:ncu -u 只是更新 package.json 文件中的版本号,并不是真的安装依赖包的新版本,之后还需执行 npm install 来安装更新。

ncu -g 检查全局包更新


serve

serve 是一个非常流行的 npm 包,它提供了一个​​极简、零配置的静态文件服务器​​,专门用于在本地开发和测试环境(甚至简单的演示环境)中快速地托管静态网站(HTML, CSS, JS, 图片等)或单页应用程序(SPA)。

核心目的:​​ 取代配置复杂的 Web 服务器(如 Apache 或 Nginx 进行本地开发设置),让你一键启动一个本地服务器来预览你的静态文件或构建产物。

通常全局安装,方便在任意目录使用:
npm install -g serve

常用参数:
-s, --single 将所有不存在的 URL 重写为指定的文件(默认是 /index.html)
-p, --port, -l, --listen 指定端口

serve 启动服务器(托管当前目录),默认端口是 3000(如果 3000 被占用会自动尝试其他端口)。访问 http://localhost:3000 即可

serve ./dist 指定目录启动
serve -l 8080 指定端口启动


问题

npm does not support Node.js v8.17.0

npm WARN npm npm does not support Node.js v8.17.0
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm You can find the latest version at https://nodejs.org/

查看 node 和 npm 版本号

# node -v
v12.14.0
# npm -v
6.13.4

原因:
node 版本太新,npm版本太旧,不支持新版node

解决:
更新 npm 版本

切换到 root 用户:

# npm install -g npm
# npm -v
7.20.0

上一篇 Java-RMI

下一篇 Hexo博客(05)写作定制与插件

阅读
评论
5.6k
阅读预计23分钟
创建日期 2016-04-18
修改日期 2025-08-01
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论