名称: npm-helper 描述: NPM和Node.js包管理、项目配置和依赖故障排除。
NPM包管理助手技能
NPM和Node.js包管理、项目配置和依赖故障排除。
指令
您是Node.js和NPM生态系统专家。当被调用时:
-
包管理:
- 安装和管理npm包
- 处理package.json配置
- 管理锁文件(package-lock.json)
- 有效使用npm、yarn或pnpm
- 配置工作空间和单体仓库
-
项目设置:
- 初始化新的Node.js项目
- 配置脚本和生命周期钩子
- 设置项目结构
- 配置开发工具
- 管理多个包管理器
-
依赖管理:
- 处理版本范围和语义版本
- 解决依赖冲突
- 审计安全漏洞
- 安全更新依赖
- 管理对等依赖
-
故障排除:
- 修复模块解析错误
- 解决版本冲突
- 调试安装问题
- 清除缓存和重建
- 处理平台特定问题
-
最佳实践:提供包管理、版本控制、安全性和性能优化指导
包管理器比较
npm(默认)
# 优点:Node.js默认,广泛支持
# 缺点:比替代品慢
# 初始化项目
npm init
npm init -y # 跳过提示
# 安装依赖
npm install express
npm install --save-dev jest
# 安装所有依赖
npm install
# 更新依赖
npm update
npm update express
# 移除包
npm uninstall express
# 运行脚本
npm run build
npm test # npm run test的简写
npm start # npm run start的简写
# 列出已安装包
npm list
npm list --depth=0 # 仅顶级
# 检查过时包
npm outdated
Yarn(v1经典版)
# 优点:更快,更好的用户体验,工作空间
# 缺点:需额外安装工具
# 安装Yarn
npm install -g yarn
# 初始化项目
yarn init
yarn init -y
# 安装依赖
yarn add express
yarn add --dev jest
# 安装所有依赖
yarn install
yarn # 简写
# 更新依赖
yarn upgrade
yarn upgrade express
# 移除包
yarn remove express
# 运行脚本
yarn build
yarn test
yarn start
# 列出已安装包
yarn list
yarn list --depth=0
# 检查过时包
yarn outdated
# 交互式升级
yarn upgrade-interactive
pnpm(快速高效)
# 优点:最快,磁盘空间高效,严格
# 缺点:较少见,一些兼容性问题
# 安装pnpm
npm install -g pnpm
# 初始化项目
pnpm init
# 安装依赖
pnpm add express
pnpm add -D jest
# 安装所有依赖
pnpm install
# 更新依赖
pnpm update
pnpm update express
# 移除包
pnpm remove express
# 运行脚本
pnpm build
pnpm test
pnpm start
# 列出已安装包
pnpm list
pnpm list --depth=0
# 检查过时包
pnpm outdated
Yarn v3(Berry)
# 优点:零安装、即插即用、尺寸更小
# 缺点:与v1不同,需要迁移
# 启用Yarn Berry
yarn set version berry
# 安装依赖
yarn add express
yarn add -D jest
# 使用即插即用(v3默认)
# 无node_modules文件夹
# 或使用node_modules
echo "nodeLinker: node-modules" >> .yarnrc.yml
# 零安装(提交.yarn/cache)
echo "enableGlobalCache: false" >> .yarnrc.yml
使用示例
@npm-helper
@npm-helper --init-project
@npm-helper --fix-dependencies
@npm-helper --audit-security
@npm-helper --migrate-to-pnpm
@npm-helper --troubleshoot
项目初始化
基本项目设置
# 初始化package.json
npm init -y
# 安装常用依赖
npm install express dotenv
# 安装开发依赖
npm install --save-dev \
nodemon \
eslint \
prettier \
jest \
@types/node \
typescript
# 创建基本结构
mkdir -p src tests
touch src/index.js tests/index.test.js
# 创建.gitignore
cat > .gitignore << EOF
node_modules/
.env
.env.local
dist/
build/
coverage/
.DS_Store
*.log
EOF
# 创建.nvmrc指定Node版本
node -v > .nvmrc
TypeScript项目设置
# 初始化项目
npm init -y
# 安装TypeScript和类型
npm install --save-dev \
typescript \
@types/node \
@types/express \
ts-node \
nodemon
# 初始化TypeScript
npx tsc --init
# 配置tsconfig.json
cat > tsconfig.json << EOF
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"declaration": true,
"declarationMap": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
EOF
# 更新package.json脚本
npm pkg set scripts.build="tsc"
npm pkg set scripts.dev="nodemon src/index.ts"
npm pkg set scripts.start="node dist/index.js"
现代ESM项目设置
{
"name": "my-esm-project",
"version": "1.0.0",
"type": "module",
"main": "dist/index.js",
"scripts": {
"dev": "node --watch src/index.js",
"build": "tsc",
"start": "node dist/index.js",
"test": "node --test"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"@types/node": "^20.10.0",
"typescript": "^5.3.0"
}
}
package.json配置
基本字段
{
"name": "my-package",
"version": "1.0.0",
"description": "一个有用的包",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
},
"scripts": {
"dev": "nodemon src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"lint": "eslint src/**/*.ts",
"lint:fix": "eslint src/**/*.ts --fix",
"format": "prettier --write \"src/**/*.ts\"",
"typecheck": "tsc --noEmit",
"prepare": "husky install",
"prepublishOnly": "npm run build && npm test"
},
"keywords": ["node", "javascript", "helper"],
"author": "您的姓名 <email@example.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/user/repo.git"
},
"bugs": {
"url": "https://github.com/user/repo/issues"
},
"homepage": "https://github.com/user/repo#readme"
}
依赖类型
{
"dependencies": {
"express": "^4.18.2",
"dotenv": "^16.3.1"
},
"devDependencies": {
"typescript": "^5.3.0",
"jest": "^29.7.0",
"eslint": "^8.55.0",
"prettier": "^3.1.0"
},
"peerDependencies": {
"react": ">=16.8.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
}
},
"optionalDependencies": {
"fsevents": "^2.3.3"
},
"bundledDependencies": [
"internal-package"
]
}
脚本最佳实践
{
"scripts": {
"// 开发": "",
"dev": "nodemon src/index.ts",
"dev:debug": "nodemon --inspect src/index.ts",
"// 构建": "",
"build": "npm run clean && tsc",
"clean": "rm -rf dist",
"prebuild": "npm run lint",
"postbuild": "echo '构建完成!'",
"// 测试": "",
"test": "jest",
"test:unit": "jest --testPathPattern=unit",
"test:integration": "jest --testPathPattern=integration",
"test:e2e": "jest --testPathPattern=e2e",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"// 代码检查和格式化": "",
"lint": "eslint . --ext .ts,.js",
"lint:fix": "eslint . --ext .ts,.js --fix",
"format": "prettier --write \"src/**/*.{ts,js,json}\"",
"format:check": "prettier --check \"src/**/*.{ts,js,json}\"",
"// 类型检查": "",
"typecheck": "tsc --noEmit",
"typecheck:watch": "tsc --noEmit --watch",
"// 组合": "",
"validate": "npm run lint && npm run typecheck && npm test",
"ci": "npm run validate && npm run build",
"// 发布": "",
"prepare": "husky install",
"prepublishOnly": "npm run ci",
"version": "npm run build && git add -A dist",
"postversion": "git push && git push --tags"
}
}
依赖版本管理
语义版本控制(semver)
{
"dependencies": {
"express": "4.18.2", // 精确版本
"lodash": "^4.17.21", // 兼容版本(4.x.x,< 5.0.0)
"axios": "~1.6.0", // 近似版本(1.6.x)
"react": ">=16.8.0", // 至少版本
"vue": "<4.0.0", // 小于版本
"moment": "*", // 最新版本(不推荐)
"date-fns": "latest" // 最新版本(不推荐)
}
}
版本范围示例
# 脱字符(^)- 兼容更新
^1.2.3 # >=1.2.3 <2.0.0
^0.2.3 # >=0.2.3 <0.3.0
^0.0.3 # >=0.0.3 <0.0.4
# 波浪符(~)- 仅补丁更新
~1.2.3 # >=1.2.3 <1.3.0
~1.2 # >=1.2.0 <1.3.0
~1 # >=1.0.0 <2.0.0
# 高级范围
1.2.3 - 2.3.4 # >=1.2.3 <=2.3.4
1.2.x # 1.2.0, 1.2.1等
* # 任何版本
锁文件管理
# npm - package-lock.json
# 始终提交package-lock.json
npm ci # 从锁文件安装(CI/CD)
npm install # 如果需要,更新锁文件
# Yarn - yarn.lock
# 始终提交yarn.lock
yarn install --frozen-lockfile # 不更新锁文件
# pnpm - pnpm-lock.yaml
# 始终提交pnpm-lock.yaml
pnpm install --frozen-lockfile # 不更新锁文件
安全和审计
漏洞扫描
# npm审计
npm audit
npm audit --json # JSON输出
npm audit --audit-level=moderate # 仅中等及以上
# 修复漏洞
npm audit fix
npm audit fix --force # 可能安装破坏性更改
# Yarn审计
yarn audit
yarn audit --level moderate
# pnpm审计
pnpm audit
pnpm audit --audit-level moderate
pnpm audit --fix
安全最佳实践
# 安装特定漏洞修复
npm install package@version
# 使用npm-check-updates进行安全更新
npx npm-check-updates
npx ncu -u # 更新package.json
npm install
# 检查过时包
npm outdated
yarn outdated
pnpm outdated
# 使用Snyk进行深度扫描
npx snyk test
npx snyk wizard
# 忽略特定漏洞(谨慎使用)
# 创建.npmrc
echo "audit-level=moderate" >> .npmrc
工作空间和单体仓库管理
npm工作空间
{
"name": "my-monorepo",
"private": true,
"workspaces": [
"packages/*",
"apps/*"
],
"scripts": {
"build": "npm run build --workspaces",
"test": "npm run test --workspaces",
"clean": "npm run clean --workspaces"
}
}
# 为所有工作空间安装依赖
npm install
# 向特定工作空间添加依赖
npm install lodash --workspace=packages/utils
# 在特定工作空间运行脚本
npm run build --workspace=packages/utils
# 在所有工作空间运行脚本
npm run test --workspaces
# 列出工作空间
npm ls --workspaces
Yarn工作空间
{
"name": "my-monorepo",
"private": true,
"workspaces": {
"packages": [
"packages/*",
"apps/*"
]
}
}
# 安装所有依赖
yarn install
# 向工作空间添加依赖
yarn workspace @myorg/utils add lodash
# 在工作空间运行脚本
yarn workspace @myorg/utils build
# 在所有工作空间运行脚本
yarn workspaces run build
# 显示工作空间信息
yarn workspaces info
pnpm工作空间
# pnpm-workspace.yaml
packages:
- 'packages/*'
- 'apps/*'
# 安装所有依赖
pnpm install
# 向工作空间添加依赖
pnpm add lodash --filter @myorg/utils
# 在工作空间运行脚本
pnpm --filter @myorg/utils build
# 在所有工作空间运行脚本
pnpm -r build
# 并行运行
pnpm -r --parallel build
常见问题及解决方案
问题:模块未找到
# 检查包是否安装
npm list package-name
# 重新安装依赖
rm -rf node_modules package-lock.json
npm install
# 清除npm缓存
npm cache clean --force
npm install
# 检查NODE_PATH
echo $NODE_PATH
# 修复:确保包在依赖中
npm install package-name
问题:版本冲突
# 检查冲突
npm ls package-name
# 强制解析(package.json)
{
"overrides": {
"package-name": "1.2.3"
}
}
# Yarn解析
{
"resolutions": {
"package-name": "1.2.3"
}
}
# pnpm覆盖
{
"pnpm": {
"overrides": {
"package-name": "1.2.3"
}
}
}
问题:对等依赖警告
# npm 7+将对等依赖视为常规依赖
# 使用传统行为:
npm install --legacy-peer-deps
# 或在.npmrc中设置
echo "legacy-peer-deps=true" >> .npmrc
# 手动安装对等依赖
npm install peer-dependency-name
问题:EACCES权限错误
# 不要使用sudo!修复权限
# 选项1:更改npm目录
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# 选项2:修复所有权
sudo chown -R $(whoami) ~/.npm
sudo chown -R $(whoami) /usr/local/lib/node_modules
问题:损坏的node_modules
# 完全清理
rm -rf node_modules package-lock.json
npm cache clean --force
npm install
# 验证安装
npm list
npm doctor
# 检查磁盘空间
df -h
问题:安装慢
# 使用pnpm(最快)
npm install -g pnpm
pnpm install
# 使用离线缓存
npm install --prefer-offline
# 跳过可选依赖
npm install --no-optional
# 并行安装
npm install --legacy-peer-deps
# 使用CI模式
npm ci # 更快,使用锁文件
性能优化
.npmrc配置
# .npmrc文件
registry=https://registry.npmjs.org/
save-exact=true
progress=false
loglevel=error
engine-strict=true
legacy-peer-deps=false
fund=false
audit=true
包安装优化
# 在CI/CD中使用npm ci(快10倍)
npm ci
# 跳过安装后脚本(安全时)
npm install --ignore-scripts
# 使用生产模式
npm install --production
# 偏好离线
npm install --prefer-offline
# 使用包管理器缓存
# npm: ~/.npm
# yarn: ~/.yarn/cache
# pnpm: ~/.pnpm-store
包大小优化
# 分析包大小
npx webpack-bundle-analyzer
# 安装前检查包大小
npx package-size lodash moment date-fns
# 查找重复包
npx find-duplicate-packages
# 使用包大小工具
npm install --save-dev bundle-size
npx bundle-size
# 替代方案:使用bundlephobia
# https://bundlephobia.com
发布包
准备发布
{
"name": "@myorg/package-name",
"version": "1.0.0",
"description": "包描述",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist",
"README.md",
"LICENSE"
],
"scripts": {
"prepublishOnly": "npm run build && npm test",
"prepare": "npm run build"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
}
}
发布工作流
# 登录npm
npm login
# 检查将发布的内容
npm pack --dry-run
# 更新版本
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 publish
# 发布作用域包
npm publish --access public
# 带标签发布
npm publish --tag beta
# 查看已发布包
npm view @myorg/package-name
包管理器迁移
npm到Yarn
# 安装Yarn
npm install -g yarn
# 从package-lock.json导入
yarn import
# 或全新安装
rm package-lock.json
yarn install
npm到pnpm
# 安装pnpm
npm install -g pnpm
# 从package-lock.json导入
pnpm import
# 或全新安装
rm package-lock.json
pnpm install
Yarn到npm
# 移除Yarn文件
rm yarn.lock
# 使用npm安装
npm install
脚本和自动化
复杂脚本示例
{
"scripts": {
"// 并行执行": "",
"dev": "concurrently \"npm:dev:*\"",
"dev:server": "nodemon src/server.ts",
"dev:client": "vite",
"// 顺序执行": "",
"build": "npm run clean && npm run build:tsc && npm run build:bundle",
"build:tsc": "tsc",
"build:bundle": "webpack",
"// 跨平台命令": "",
"clean": "rimraf dist",
"copy": "copyfiles -u 1 src/**/*.json dist",
"// 环境特定": "",
"start:dev": "NODE_ENV=development node dist/index.js",
"start:prod": "NODE_ENV=production node dist/index.js",
"// 带参数": "",
"test": "jest",
"test:file": "jest --",
"// 用法: npm run test:file path/to/test.js"
}
}
自定义npm脚本
# 使用npm run运行
npm run build
# 传递参数
npm run test -- --watch
npm run test:file -- src/utils.test.js
# 运行多个脚本
npm run build && npm test
# 并行运行(使用npm-run-all)
npm install --save-dev npm-run-all
npm-run-all --parallel dev:*
最佳实践总结
包管理
- 始终提交锁文件(package-lock.json, yarn.lock, pnpm-lock.yaml)
- 在生产中使用精确版本(
npm install --save-exact) - 使用.nvmrc固定Node.js版本
- 在CI/CD中使用
npm ci进行快速可靠安装 - 保持依赖最小化(检查包大小)
- 分离开发和依赖
安全
- 定期运行
npm audit - 保持依赖更新
- 更新前审查依赖变更
- 使用锁文件实现可重复构建
- 不要提交node_modules或.env文件
- 尽可能使用
npx而非全局安装
性能
- 使用pnpm获得最快安装
- 尽可能利用离线缓存
- 在CI/CD中使用
npm ci - 考虑Yarn PnP实现零安装
- 分析和优化包大小
项目组织
- 使用清晰描述性脚本名称
- 在README中记录复杂脚本
- 单体仓库使用工作空间
- 遵循语义版本控制
- 包含engines字段指定Node版本要求
快速参考命令
# 安装
npm install # 安装所有依赖
npm install <package> # 安装包
npm install -D <package> # 作为开发依赖安装
npm install -g <package> # 全局安装
npm ci # 从锁文件清理安装
# 更新
npm update # 更新所有包
npm update <package> # 更新特定包
npm outdated # 检查过时包
# 移除
npm uninstall <package> # 移除包
npm prune # 移除未使用包
# 信息
npm list # 列出已安装包
npm view <package> # 查看包信息
npm search <package> # 搜索包
# 脚本
npm run <script> # 运行脚本
npm test # 运行测试
npm start # 启动应用
# 安全
npm audit # 检查漏洞
npm audit fix # 修复漏洞
# 缓存
npm cache clean --force # 清除缓存
npm cache verify # 验证缓存
# 发布
npm login # 登录注册表
npm publish # 发布包
npm version <type> # 提升版本
备注
- 在CI/CD中使用npm ci实现一致快速安装
- 始终提交锁文件到版本控制
- 生产依赖偏好精确版本
- 使用工作空间管理单体仓库
- 定期审计依赖安全
- 保持Node.js和包管理器更新
- 使用.nvmrc指定Node.js版本
- 考虑pnpm以获得更好性能和磁盘使用
- 包发布使用语义版本控制
- 在README中记录所有自定义脚本