npm包管理

npm(Node Package Manager)是 JavaScript 世界的包管理器,拥有世界上最大的软件注册表。掌握 npm 是现代 JavaScript 开发的必备技能。

npm 基础

初始化项目

# 交互式初始化
npm init

# 快速初始化(使用默认值)
npm init -y

# 使用预设配置
npm init -y --scope=@dongba

# package.json 示例
{
  "name": "dongba-project",
  "version": "1.0.0",
  "description": "东巴文项目",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "东巴文",
  "license": "ISC"
}

安装依赖

# 安装包(保存到 dependencies)
npm install lodash
npm i lodash

# 安装指定版本
npm i lodash@4.17.21
npm i lodash@^4.17.0    # 兼容版本
npm i lodash@~4.17.0    # 近似版本
npm i lodash@>=4.0.0    # 最低版本

# 安装开发依赖
npm i -D typescript
npm i --save-dev eslint

# 安装全局包
npm i -g nodemon
npm i -g --force nodemon  # 强制安装

# 安装所有依赖
npm install

# 只安装生产依赖
npm install --production

# 安装特定范围的依赖
npm install --only=dev
npm install --only=prod

版本号规则

npm 使用语义化版本(SemVer):主版本.次版本.修订版本

符号 含义 示例
无符号 精确版本 1.2.3
^ 兼容版本(主版本不变) ^1.2.3>=1.2.3 <2.0.0
~ 近似版本(次版本不变) ~1.2.3>=1.2.3 <1.3.0
> 大于 >1.2.3
>= 大于等于 >=1.2.3
< 小于 <1.2.3
<= 小于等于 <=1.2.3
` `
- 范围 1.2.3 - 2.0.0
x 通配符 1.2.x>=1.2.0 <1.3.0

更新与卸载

# 查看可更新的包
npm outdated

# 更新包
npm update lodash
npm update          # 更新所有包

# 更新到最新版本(可能跨主版本)
npm install lodash@latest

# 卸载包
npm uninstall lodash
npm un lodash
npm r lodash

# 卸载全局包
npm uninstall -g nodemon

# 清理缓存
npm cache clean --force

package.json 详解

{
  "name": "@dongba/utils",
  "version": "1.0.0",
  "description": "东巴文工具库",
  "keywords": ["utils", "javascript", "dongba"],
  "homepage": "https://db-w.cn",
  "bugs": {
    "url": "https://github.com/dongba/utils/issues"
  },
  "license": "MIT",
  "author": {
    "name": "东巴文",
    "email": "dongba@example.com",
    "url": "https://db-w.cn"
  },
  "contributors": [],
  "files": ["lib", "dist"],
  "main": "lib/index.js",
  "module": "es/index.js",
  "browser": "dist/umd/index.js",
  "types": "lib/index.d.ts",
  "bin": {
    "dongba-cli": "./bin/cli.js"
  },
  "man": "./man/dongba.1",
  "directories": {
    "lib": "lib",
    "test": "test"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/dongba/utils.git"
  },
  "scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js",
    "build": "webpack --mode production",
    "test": "jest",
    "lint": "eslint src/",
    "prepublishOnly": "npm run build"
  },
  "config": {
    "port": "3000"
  },
  "dependencies": {
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "typescript": "^5.0.0",
    "jest": "^29.0.0"
  },
  "peerDependencies": {
    "react": ">=17.0.0"
  },
  "peerDependenciesMeta": {
    "react": {
      "optional": true
    }
  },
  "bundledDependencies": ["lodash"],
  "optionalDependencies": {
    "fsevents": "^2.3.0"
  },
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=9.0.0"
  },
  "os": ["darwin", "linux", "win32"],
  "cpu": ["x64", "arm64"],
  "private": false,
  "publishConfig": {
    "registry": "https://registry.npmjs.org/",
    "access": "public"
  },
  "type": "module",
  "exports": {
    ".": {
      "import": "./es/index.js",
      "require": "./lib/index.js",
      "types": "./lib/index.d.ts"
    },
    "./utils": {
      "import": "./es/utils.js",
      "require": "./lib/utils.js"
    }
  },
  "sideEffects": false
}

npm scripts

基本用法

{
  "scripts": {
    "start": "node src/index.js",
    "dev": "nodemon src/index.js",
    "build": "webpack",
    "test": "jest",
    "lint": "eslint src/"
  }
}
npm run start
npm start           # start 可省略 run
npm run dev
npm run build
npm test            # test 可省略 run

生命周期钩子

{
  "scripts": {
    "prebuild": "echo '构建前'",
    "build": "webpack",
    "postbuild": "echo '构建后'",
    "pretest": "npm run lint",
    "test": "jest",
    "posttest": "echo '测试完成'"
  }
}

执行 npm run build 时:

  1. 先执行 prebuild
  2. 再执行 build
  3. 最后执行 postbuild

脚本变量

{
  "scripts": {
    "info": "echo $npm_package_name",
    "version": "echo $npm_package_version",
    "config": "echo $npm_package_config_port",
    "env": "echo $npm_config_env"
  },
  "config": {
    "port": "3000"
  }
}
npm run info        # 输出包名
npm run version     # 输出版本
npm run config      # 输出配置端口
npm run env --env=production  # 传递参数

跨平台脚本

# 安装 cross-env
npm install -D cross-env
{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack",
    "dev": "cross-env NODE_ENV=development webpack serve"
  }
}

并行与串行

npm install -D npm-run-all
{
  "scripts": {
    "lint:js": "eslint src/**/*.js",
    "lint:css": "stylelint src/**/*.css",
    "lint": "npm-run-all lint:*",
    "build:js": "webpack",
    "build:css": "postcss",
    "build": "npm-run-all --parallel build:*",
    "test:unit": "jest",
    "test:e2e": "cypress run",
    "test": "npm-run-all --serial test:*"
  }
}

npm 配置

.npmrc 文件

# 项目级配置(项目根目录)
registry=https://registry.npmmirror.com
@dongba:registry=https://npm.dongba.cn

# 认证信息
//npm.dongba.cn/:_authToken=${NPM_TOKEN}

# 代理配置
proxy=http://proxy.example.com:8080
https-proxy=http://proxy.example.com:8080

# 缓存配置
cache=/path/to/cache

# 其他配置
save-exact=true
package-lock=false

配置命令

# 查看配置
npm config list
npm config list -l    # 查看所有配置

# 设置配置
npm config set registry https://registry.npmmirror.com
npm config set @dongba:registry https://npm.dongba.cn

# 获取配置
npm config get registry

# 删除配置
npm config delete registry

# 编辑配置文件
npm config edit

常用镜像源

# 淘宝镜像
npm config set registry https://registry.npmmirror.com

# 官方镜像
npm config set registry https://registry.npmjs.org

# 使用 nrm 管理镜像源
npm install -g nrm
nrm ls              # 列出所有镜像源
nrm use taobao      # 切换到淘宝镜像
nrm test            # 测试镜像源速度
nrm add dongba https://npm.dongba.cn  # 添加自定义镜像源

发布包

准备发布

# 登录 npm
npm login

# 查看当前用户
npm whoami

# 检查包名是否可用
npm search dongba-utils
npm view @dongba/utils

发布流程

# 发布前检查
npm pack            # 打包,查看包含的文件

# 发布
npm publish

# 发布作用域包(公开)
npm publish --access public

# 发布到私有仓库
npm publish --registry https://npm.dongba.cn

# 发布测试版本
npm version 1.0.0-beta.1
npm publish --tag beta

# 发布下一个版本
npm version 2.0.0
npm publish --tag next

版本管理

# 更新版本号
npm version patch   # 1.0.0 -> 1.0.1
npm version minor   # 1.0.0 -> 1.1.0
npm version major   # 1.0.0 -> 2.0.0

# 预发布版本
npm version prerelease  # 1.0.0 -> 1.0.1-0
npm version prepatch    # 1.0.0 -> 1.0.1-0
npm version preminor    # 1.0.0 -> 1.1.0-0
npm version premajor    # 1.0.0 -> 2.0.0-0

# 自定义版本
npm version 1.2.3

# 带 Git 标签
npm version minor -m "升级到 %s"

废弃与删除

# 废弃某个版本
npm deprecate @dongba/utils@1.0.0 "此版本有安全问题"

# 废弃整个包
npm deprecate @dongba/utils "包已废弃,请使用新包"

# 删除版本(发布 24 小时内)
npm unpublish @dongba/utils@1.0.0

# 删除整个包(发布 24 小时内)
npm unpublish @dongba/utils --force

package-lock.json

锁文件的作用

{
  "name": "dongba-project",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "dongba-project",
      "version": "1.0.0",
      "dependencies": {
        "lodash": "^4.17.21"
      }
    },
    "node_modules/lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    }
  }
}

锁文件最佳实践

# 提交锁文件到版本控制
git add package-lock.json
git commit -m "添加锁文件"

# 不同环境安装
npm ci              # CI 环境,严格按照锁文件安装
npm install         # 开发环境,可能更新锁文件

# ci 命令特点
# - 必须存在 package-lock.json
# - 严格按照锁文件版本安装
# - 比 install 更快
# - 安装前删除 node_modules
# - 不会修改 package-lock.json

npx 命令

npx 用于执行 npm 包中的命令。

# 执行本地安装的包
npx webpack
npx jest

# 执行未安装的包(临时安装)
npx create-react-app my-app
npx vite

# 使用特定版本
npx webpack@5.0.0

# 使用 GitHub 仓库
npx github:user/repo

# 使用本地文件
npx ./local-script.js

# 交互式创建项目
npx create-vite
npx @nestjs/cli new project

# 执行 Node 脚本
npx node -e "console.log('东巴文')"

私有仓库

使用私有包

{
  "dependencies": {
    "@dongba/utils": "^1.0.0"
  }
}
# .npmrc
@dongba:registry=https://npm.dongba.cn
//npm.dongba.cn/:_authToken=${NPM_TOKEN}

搭建私有仓库

# 使用 Verdaccio
npm install -g verdaccio
verdaccio

# 添加用户
npm adduser --registry http://localhost:4873

# 发布包
npm publish --registry http://localhost:4873

常用命令速查

命令 说明
npm init 初始化项目
npm install 安装依赖
npm install <pkg> 安装包
npm install -D <pkg> 安装开发依赖
npm install -g <pkg> 全局安装
npm uninstall <pkg> 卸载包
npm update 更新依赖
npm outdated 查看过期依赖
npm run <script> 运行脚本
npm test 运行测试
npm publish 发布包
npm version <type> 更新版本
npm ci CI 安装
npm cache clean 清理缓存
npm ls 查看依赖树
npm dedupe 依赖去重
npm prune 清理多余依赖
npm link 本地链接包
npm unlink 取消链接
npm pack 打包
npm view <pkg> 查看包信息
npm search <pkg> 搜索包
npm audit 安全审计
npm audit fix 修复漏洞

下一步

掌握 npm 后,你可以继续学习:


东巴文(db-w.cn)—— 让包管理更简单