Lesson 05-Customizing npm Behavior

npm Scripts Hooks

Introduction to npm Scripts

  • npm scripts are defined in the scripts field of package.json, allowing you to specify commands executable in a command-line environment.
  • They provide a standardized way to perform common project tasks like building, testing, and deployment.

Hook Mechanism: pre and post

  • npm offers preprocessing and postprocessing hooks (pre and post) that run custom scripts before or after specific npm events.
  • These hooks are useful for ensuring prerequisites are met before main scripts or performing cleanup afterward.

Example: Using pre and post Hooks

"scripts": {
    "test": "echo 'Running tests...' && jest",
    "pretest": "npm run lint",
    "posttest": "echo 'Tests completed.'"
}
  • In this example:
  • pretest runs the lint task before test, ensuring code style consistency.
  • posttest runs after test, outputting a completion message.

Understanding Hook Execution Order

  • When running npm run test, npm executes scripts in this order:
  1. pretest
  2. test
  3. posttest

General Hook Format

  • Hooks follow the naming pattern pre<command> and post<command>.
  • <command> corresponds to a command name in the scripts field.

Complex Scenarios

  • Combine multiple hooks to create sophisticated automation workflows, such as building, testing, and generating documentation before deployment.

Error Handling and Dependencies

  • If a pre hook fails, npm halts execution of subsequent scripts, preventing critical operations in an invalid state.
  • This ensures the project is in the expected state before executing main tasks.

Best Practices

  • Use clear naming conventions to make script purposes obvious.
  • Keep scripts concise, avoiding overly complex logic in package.json.
  • Leverage environment variables and parameters for flexible, configurable scripts.

Summary

  • npm scripts and their pre and post hooks offer significant flexibility and automation for project management.
  • Well-designed use of these features can greatly enhance development efficiency and project quality.

Further Reading

  • npm link is a powerful tool for local development and testing of npm packages.
  • It creates a global symbolic link to your local module, allowing other projects to use its latest version without republishing to the npm registry.
  1. Link the Module:
  • Run npm link in your module’s directory.
  • This creates a symbolic link in the global node_modules directory pointing to the module.
  1. Link to a Project:
  • In the project where you want to use the module, run npm link <module-name>.
  • This creates a symbolic link to the module directory instead of installing a copy.
  • Running npm link:
  • Creates a .npmignore file in the module’s root if none exists.
  • Establishes a global symbolic link to the module directory.
  • Running npm link <module-name> in another project creates a symbolic link in that project’s node_modules directory.
  • Suppose you’re developing a module called my-module and want to test it in my-project.
  • Run npm link in the my-module directory.
  • Then, run npm link my-module in the my-project directory.
  • Changes saved in my-module are instantly reflected in my-project without reinstalling or publishing.
  • Changes made to a linked module are not automatically committed to version control.
  • Manually commit changes and rerun npm link as needed to update the link.

Best Practices

  • Ensure each project using npm link has its own node_modules directory to avoid dependency conflicts.
  • Periodically run npm install or yarn to keep project dependencies up-to-date, even if unmodified.
  • After completing development, unlink (npm unlink) and publish the module to the npm registry.

Issues and Solutions

  • Issue: Cross-platform issues, as Windows may not support symbolic links.
  • Solution: On Windows, npm uses Junctions or hard links to simulate symbolic links.
  • Issue: Ensuring multiple projects use the latest module code when linked.
  • Solution: Rerun npm link and npm link <module-name> after changes to update all projects.

Summary

  • npm link is an invaluable tool for rapid iteration and testing of npm packages locally.
  • Understanding and mastering npm link enhances efficiency in module development and integration testing.

Further Reading

npm Workspaces

Overview of npm Workspaces

  • npm workspaces is a feature for managing multiple related but independent npm packages within a single repository.
  • It’s particularly useful for large organizations or projects with interdependent sub-projects.

Benefits of Workspaces

  • Simplified Dependency Management: Share dependencies to reduce duplicate installations.
  • Unified Building and Testing: Run build and test scripts across all sub-projects at once.
  • Streamlined Development: Easily share code and develop locally across sub-projects.

Setting Up npm Workspaces

  • Add a workspaces field to the root package.json, listing directories of sub-projects.
{
  "name": "my-monorepo",
  "version": "1.0.0",
  "workspaces": [
    "packages/*"
  ]
}

Workspace Structure

  • Sub-projects reside in the specified workspace directories, each with its own package.json.

Installing Dependencies in Workspaces

  • Run npm install in the root directory to recursively install dependencies for all workspaces.
  • Use the --workspace or -W option to target specific workspaces for installation.

Running Scripts

  • Define scripts in the root package.json to run across all workspaces.
  • Without specifying a workspace, npm run executes scripts in all workspaces.
  • Use --workspace or -W to run scripts in specific workspaces.

Linking Packages Within Workspaces

  • Workspace packages can be linked using npm link, allowing development with unpublished package code.

Code Analysis: How npm Workspaces Work

  • npm parses the workspaces field in package.json, treating each sub-project as an independent npm package.
  • During dependency installation, npm recursively processes each sub-project’s dependencies.
  • When running scripts, npm looks for scripts in the root and sub-project package.json files, executing them as needed.

Example: Using npm Workspaces

  • Imagine a repository named my-monorepo with two sub-projects: my-package-a and my-package-b.
  • Set the workspaces field in the root package.json.
  • Run npm install to install all sub-project dependencies.
  • Define a script like npm run build to iterate over sub-projects and run their build scripts.

Best Practices

  • Ensure all sub-project package.json files are correctly configured with name and version fields.
  • Use --workspace to selectively run scripts or install dependencies, avoiding unnecessary resource use.
  • Regularly run npm outdated to check for outdated dependencies across workspaces.

Common Issues and Solutions

  • Issue: Handling circular dependencies in workspaces.
  • Solution: Avoid circular dependencies; if unavoidable, refactor code or use external dependencies.
  • Issue: Sharing code between workspaces.
  • Solution: Use npm link or install workspace packages as dependencies with npm install.

Summary

  • npm workspaces is a powerful tool for managing multi-package projects, simplifying dependency management and development workflows.
  • Proper configuration and usage of npm workspaces enable efficient building and maintenance of large projects.

Further Reading

Share your love