Skip to content
On this page

npm 脚本

npm脚本是npm生态系统的核心功能之一,允许您在package.json文件中定义和运行命令。本章将详细介绍npm脚本的使用方法和最佳实践。

脚本基础

定义脚本

在package.json文件中定义脚本:

json
{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "test": "jest",
    "build": "webpack --mode production",
    "lint": "eslint src/",
    "format": "prettier --write src/"
  }
}

运行脚本

bash
# 运行脚本
npm run script-name

# 对于预定义脚本可以省略run
npm start    # 等同于 npm run start
npm test     # 等同于 npm run test
npm stop     # 等同于 npm run stop
npm restart  # 等同于 npm run restart

# 运行自定义脚本
npm run dev
npm run build
npm run lint

常用脚本模式

开发脚本

json
{
  "scripts": {
    "dev": "webpack serve --mode development",
    "dev:api": "nodemon --exec 'node src/api/server.js'",
    "dev:ui": "vite",
    "dev:watch": "chokidar 'src/**/*.js' -c 'npm run build'"
  }
}

测试脚本

json
{
  "scripts": {
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "test:unit": "jest --testPathPattern=unit",
    "test:e2e": "cypress run",
    "test:watchAll": "jest --watchAll"
  }
}

构建脚本

json
{
  "scripts": {
    "build": "webpack --mode production",
    "build:dev": "webpack --mode development",
    "build:prod": "webpack --mode production",
    "build:analyze": "webpack-bundle-analyzer --mode production",
    "prebuild": "npm run clean",
    "postbuild": "npm run copy-files"
  }
}

代码质量脚本

json
{
  "scripts": {
    "lint": "eslint src/",
    "lint:fix": "eslint src/ --fix",
    "format": "prettier --write src/",
    "format:check": "prettier --check src/",
    "type-check": "tsc --noEmit",
    "validate": "npm run lint && npm run type-check && npm run test"
  }
}

脚本钩子

npm提供预定义的钩子来执行特定生命周期事件:

安装钩子

json
{
  "scripts": {
    "preinstall": "echo 'Before install'",
    "install": "echo 'During install'",
    "postinstall": "echo 'After install'",
    "prepublish": "echo 'Before publish'",
    "prepare": "npm run build",  // 发布前或安装后执行
    "prepack": "npm run build",
    "postpack": "echo 'After packing'",
    "preuninstall": "echo 'Before uninstall'",
    "postuninstall": "echo 'After uninstall'"
  }
}

自定义脚本钩子

json
{
  "scripts": {
    "prebuild": "npm run clean",
    "build": "webpack --mode production",
    "postbuild": "npm run copy-files",
    
    "pretest": "npm run lint",
    "test": "jest",
    "posttest": "npm run report-coverage",
    
    "prestart": "npm run validate",
    "start": "node dist/index.js",
    "poststart": "echo 'Application started successfully'"
  }
}

高级脚本技巧

跨平台脚本

json
{
  "scripts": {
    "clean": "rimraf dist coverage",
    "copy-files": "cpx 'src/assets/**/*' dist/assets",
    "build:win": "set NODE_ENV=production && webpack",
    "build:unix": "NODE_ENV=production webpack",
    "build:cross": "cross-env NODE_ENV=production webpack"
  }
}

并行和串行执行

json
{
  "scripts": {
    "build:client": "webpack --config webpack.client.js",
    "build:server": "webpack --config webpack.server.js",
    "build:all": "npm run build:client && npm run build:server",
    "build:parallel": "npm run build:client & npm run build:server",
    "dev:all": "concurrently \"npm run dev:client\" \"npm run dev:server\""
  }
}

条件执行

json
{
  "scripts": {
    "build": "npm run build:check-env && webpack",
    "build:check-env": "node -e \"if(process.env.NODE_ENV !== 'production') throw new Error('Build requires production environment')\"",
    "build:prod": "cross-env NODE_ENV=production npm run build:webpack",
    "build:dev": "cross-env NODE_ENV=development npm run build:webpack",
    "build:webpack": "webpack"
  }
}

环境变量

设置环境变量

json
{
  "scripts": {
    "dev": "cross-env NODE_ENV=development nodemon index.js",
    "start": "cross-env NODE_ENV=production node index.js",
    "build:prod": "cross-env NODE_ENV=production API_URL=https://api.prod.com webpack",
    "build:staging": "cross-env NODE_ENV=staging API_URL=https://api.staging.com webpack"
  }
}

使用环境变量

bash
# 在脚本中使用环境变量
echo "Environment: $NODE_ENV"
echo "API URL: $API_URL"

# Windows兼容方式
echo "Environment: %NODE_ENV%"

实用脚本示例

完整的开发工作流

json
{
  "name": "my-awesome-project",
  "version": "1.0.0",
  "scripts": {
    "prebuild": "npm run clean",
    "build": "npm run build:client && npm run build:server",
    "build:client": "webpack --config webpack.client.js",
    "build:server": "webpack --config webpack.server.js",
    "build:analyze": "webpack-bundle-analyzer --mode production",
    
    "dev": "concurrently \"npm run dev:client\" \"npm run dev:server\"",
    "dev:client": "webpack serve --config webpack.client.js",
    "dev:server": "nodemon --exec 'node src/server.js'",
    
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage --collectCoverageFrom=src/**/*.{js,jsx}",
    "test:e2e": "cypress run",
    
    "lint": "eslint src/ --ext .js,.jsx,.ts,.tsx",
    "lint:fix": "eslint src/ --ext .js,.jsx,.ts,.tsx --fix",
    "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"",
    "format:check": "prettier --check \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"",
    
    "type-check": "tsc --noEmit",
    "validate": "npm run type-check && npm run lint && npm run test",
    
    "clean": "rimraf dist coverage node_modules/.cache",
    "clean:deps": "rimraf node_modules package-lock.json",
    "clean:install": "npm run clean:deps && npm install",
    
    "start": "node dist/server.js",
    "start:prod": "cross-env NODE_ENV=production node dist/server.js",
    
    "postinstall": "npm run build",
    "prepublishOnly": "npm run validate",
    "prepare": "husky install"
  }
}

CI/CD相关脚本

json
{
  "scripts": {
    "ci:test": "npm run test -- --ci --coverage --maxWorkers=2",
    "ci:build": "npm run build && npm run build:docker",
    "ci:deploy": "npm run build && npm run deploy:staging",
    "ci:security": "npm audit && snyk test",
    "ci:validate": "npm run validate && npm run ci:security"
  }
}

脚本工具和实用程序

concurrently - 并行执行脚本

json
{
  "scripts": {
    "dev": "concurrently \"npm run dev:client\" \"npm run dev:server\" \"npm run dev:db\"",
    "dev:client": "vite",
    "dev:server": "nodemon src/server.js",
    "dev:db": "mongod --dbpath ./data/db"
  }
}

nodemon - 监视文件变化

json
{
  "scripts": {
    "dev": "nodemon --exec \"npm run build && node dist/index.js\"",
    "dev:api": "nodemon --watch src/api --exec \"node src/api/server.js\""
  },
  "nodemonConfig": {
    "watch": ["src/"],
    "ext": "js,json",
    "ignore": ["src/**/*.test.js", "node_modules/"],
    "delay": "2000"
  }
}

cross-env - 跨平台环境变量

json
{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack",
    "dev": "cross-env NODE_ENV=development nodemon server.js"
  }
}

脚本最佳实践

脚本命名约定

json
{
  "scripts": {
    // 构建相关
    "build": "构建生产版本",
    "build:dev": "构建开发版本",
    "build:prod": "构建生产版本",
    "build:analyze": "构建并分析包大小",
    
    // 开发相关
    "dev": "开发服务器",
    "dev:api": "API开发服务器",
    "dev:ui": "UI开发服务器",
    
    // 测试相关
    "test": "运行测试",
    "test:unit": "单元测试",
    "test:e2e": "端到端测试",
    "test:watch": "监听模式运行测试",
    
    // 质量相关
    "lint": "代码检查",
    "lint:fix": "自动修复代码问题",
    "format": "格式化代码",
    "type-check": "类型检查",
    
    // 部署相关
    "deploy": "部署应用",
    "deploy:staging": "部署到预发布环境",
    "deploy:prod": "部署到生产环境",
    
    // 工具相关
    "clean": "清理构建文件",
    "validate": "验证代码质量"
  }
}

脚本文档化

json
{
  "name": "my-project",
  "scripts": {
    "dev": "启动开发服务器",
    "build": "构建生产版本",
    "test": "运行所有测试",
    "lint": "检查代码质量",
    "start": "启动生产服务器"
  },
  "description": "项目描述",
  "keywords": ["javascript", "nodejs", "npm"],
  "repository": {
    "type": "git",
    "url": "https://github.com/user/repo.git"
  }
}

调试脚本

调试技巧

bash
# 以调试模式运行npm脚本
npm run build --inspect

# 显示详细输出
npm run build --verbose

# 显示执行的命令
npm run build --dry-run  # 模拟运行,不实际执行

# 获取帮助信息
npm run --help

脚本调试示例

json
{
  "scripts": {
    "debug": "node --inspect-brk index.js",
    "debug:test": "node --inspect-brk ./node_modules/.bin/jest --runInBand",
    "debug:build": "node --inspect-brk ./node_modules/.bin/webpack"
  }
}

npm脚本是自动化开发工作流的关键工具,通过合理配置和使用脚本,可以大大提高开发效率和代码质量。