npm scripts are commands defined in the scripts field of package.json, used to automate common project tasks.
Basic Syntax
json{ "scripts": { "start": "node index.js", "dev": "nodemon index.js", "build": "webpack --mode production", "test": "jest", "lint": "eslint src/" } }
Running Scripts
Use npm run <script-name> or npm <script-name> (for special commands like start, stop, test):
bashnpm run dev npm start npm test
Lifecycle Scripts
npm provides special lifecycle scripts that automatically execute on specific events:
Installation Related Lifecycle
json{ "scripts": { "preinstall": "echo 'Installing dependencies...'", "install": "node setup.js", "postinstall": "echo 'Dependencies installed!'", "preuninstall": "echo 'Uninstalling...'", "postuninstall": "echo 'Uninstalled!'" } }
Execution order:
preinstallinstallpostinstall
Publishing Related Lifecycle
json{ "scripts": { "prepublishOnly": "npm run build && npm run test", "prepack": "npm run build", "postpack": "echo 'Package packed!'", "publish": "node publish.js", "postpublish": "echo 'Published!'" } }
Execution order:
prepublishOnlyprepackpreparepostpackpublishpostpublish
Other Lifecycle
json{ "scripts": { "prestart": "npm run build", "start": "node index.js", "poststart": "echo 'Server started!'", "pretest": "npm run lint", "test": "jest", "posttest": "npm run coverage" } }
Passing Arguments to Scripts
You can pass arguments to scripts:
json{ "scripts": { "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage" } }
Pass additional arguments when running:
bashnpm run test -- --verbose
Arguments after -- are passed to the script command.
Environment Variables
npm scripts can access environment variables provided by npm:
json{ "scripts": { "build": "webpack --env.NODE_ENV=$npm_package_config_env", "start": "node $npm_package_main" } }
Common environment variables:
npm_package_name: Package namenpm_package_version: Package versionnpm_package_main: Main entry filenpm_package_scripts_*: Other scriptsnpm_config_*: npm configurationnpm_lifecycle_event: Current lifecycle event name
Cross-Platform Compatibility
Handling cross-platform compatibility of npm scripts:
Using cross-env
json{ "scripts": { "build": "cross-env NODE_ENV=production webpack" } }
Using rimraf (cross-platform delete)
json{ "scripts": { "clean": "rimraf dist" } }
Common Script Patterns
Development Environment Scripts
json{ "scripts": { "dev": "nodemon index.js", "dev:debug": "nodemon --inspect index.js", "dev:hot": "webpack serve --hot" } }
Build Scripts
json{ "scripts": { "build": "webpack --mode production", "build:dev": "webpack --mode development", "build:analyze": "webpack --mode production --analyze" } }
Test Scripts
json{ "scripts": { "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage", "test:ci": "jest --ci --coverage --maxWorkers=2" } }
Code Quality Scripts
json{ "scripts": { "lint": "eslint src/", "lint:fix": "eslint src/ --fix", "format": "prettier --write \"src/**/*.js\"", "typecheck": "tsc --noEmit" } }
Git Hook Scripts (using husky)
json{ "scripts": { "prepare": "husky install", "precommit": "lint-staged" } }
Parallel and Sequential Execution
Use & for parallel execution, && for sequential execution:
json{ "scripts": { "parallel": "npm run lint & npm run test", "sequential": "npm run lint && npm run test", "all": "npm run lint && npm run test && npm run build" } }
Use npm-run-all tool for more flexibility:
json{ "scripts": { "dev": "npm-run-all --parallel dev:*", "dev:server": "nodemon index.js", "dev:client": "webpack serve" } }
Best Practices
- Naming Convention: Use colons to separate related scripts (e.g.,
test:watch) - Documentation: Document custom scripts in README
- Error Handling: Ensure scripts return non-zero exit codes on failure
- Performance Optimization: Avoid unnecessary repetitive operations
- Environment Isolation: Use environment variables to manage different environment configurations
- Dependency Management: Install development tools as devDependencies
Debugging Tips
View Script Execution Details
bashnpm run <script> -- --verbose
View Actual Command Being Executed
bashnpm run <script> -n
Debug Local Packages Using npm link
bashnpm link ../my-local-package
npm scripts are the core of project automation, and using them properly can significantly improve development efficiency and project maintainability.