Table of Contents
Overview of pnpm Workspaces
pnpm Workspaces allow developers to manage multiple packages within a single repository efficiently. This setup is beneficial for monorepos, where multiple related packages are developed together. With pnpm, you can share dependencies among packages, streamline project organization, and improve overall build times. The workspace feature simplifies dependency management and enables developers to work on multiple packages simultaneously while keeping their configurations clean and organized.
Related Article: How to use pnpm run -r for project management
Setting Up Your First Workspace
To create your first pnpm workspace, start by initializing a new project if you haven't already. Open your terminal and run:
mkdir my-workspace cd my-workspace pnpm init
This command creates a new directory and initializes a new pnpm project. After this, create a pnpm-workspace.yaml
file in the root directory to define your workspace. This file will specify which packages belong to the workspace.
packages: - 'packages/*'
This configuration indicates that all packages located inside the packages
directory will be included in the workspace. You can create this packages
folder and add your first package.
Configuring package.json for Workspaces
Each package in your workspace should have its own package.json
file. Navigate to the packages
directory and create a new package:
mkdir packages/my-package cd packages/my-package pnpm init
This command will prompt you to fill in details for your package. After completing this setup, you will have a package.json
file specific to my-package
. It should look something like this:
{ "name": "my-package", "version": "1.0.0", "main": "index.js" }
You can also include a workspaces
field in the root package.json
to specify the workspace settings, although it's not mandatory since you have already defined them in the pnpm-workspace.yaml
file.
Managing Dependencies in Workspaces
Managing dependencies becomes simpler with pnpm workspaces. When you add a dependency to a package, pnpm will hoist it to the root node_modules directory if it's a common dependency across multiple packages. You can add a dependency to my-package
by navigating to its directory and running:
pnpm add lodash
This command will install lodash and link it in your package. If another package in the workspace needs the same dependency, pnpm will not install it again; instead, it will use the hoisted version, conserving disk space and improving performance.
Related Article: How To Clear Pnpm Cache
Using the Workspace Protocol
pnpm provides a special protocol to manage dependencies between packages within the same workspace. Instead of specifying a version number for a local package, you can use the workspace protocol. For example, if my-package
depends on another package my-other-package
, you can add it like this:
pnpm add my-other-package --workspace
This command tells pnpm to link the local package directly rather than downloading it from the registry. This improves development speed and consistency, as changes in my-other-package
will be reflected immediately in my-package
.
Hoisting Mechanism Explained
Hoisting is a method where common dependencies are moved to the root node_modules directory. This mechanism reduces duplication and speeds up installations. In a workspace, when you add a dependency that multiple packages need, pnpm will hoist that dependency to the root level instead of installing it in each package's node_modules folder.
For example, if both my-package
and my-other-package
require lodash, pnpm will install it once at the root level. This approach not only saves space but also ensures that all packages are using the same version of the dependency, reducing potential conflicts.
Running Scripts Across Workspaces
Running scripts across multiple packages in a workspace can be performed easily. If you want to run a script defined in my-package
from the root directory, you can execute:
pnpm -r run build
The -r
flag indicates that you want to run the command recursively across all packages in the workspace. If you want to target a specific package, you can use:
pnpm run build --filter my-package
This command will only run the build script for my-package
.
Creating Local Packages
Creating local packages in a pnpm workspace involves simply adding a new directory under the packages
folder. For instance, to create a new package named my-local-package
, navigate to the packages
directory and run:
mkdir my-local-package cd my-local-package pnpm init
After initializing, you can add any dependencies or scripts as you would in a typical package.json
. The local package can then be used across other packages in the workspace using the workspace protocol.
Related Article: How to install pnpm on Mac
Versioning Workspaces
Versioning in pnpm workspaces can be handled through individual package.json
files. Each package can have its own version number, which allows for precise control over updates and releases. When you publish a package, you will reference its version in its package.json
.
To update the version of a package, you can use:
pnpm version patch
This command will increment the patch version of the current package. You can specify major
or minor
if you want to update those versions instead. The root package.json
can also have a version, but it is not strictly necessary unless you intend to publish the entire workspace as a single package.
Integrating with Existing npm Projects
Integrating pnpm workspaces into existing npm projects requires some adjustments. Start by installing pnpm globally if it is not already installed. You can do this with:
npm install -g pnpm
After installing pnpm, convert your existing project by creating a pnpm-workspace.yaml
file as described earlier. Then, update your package.json
files for each package to ensure they are compatible with pnpm.
Make sure to run:
pnpm install
This command will restructure your node_modules and install dependencies according to pnpm’s methodology. Check for any issues with package versions or configurations and resolve them as needed.
Comparing pnpm Workspaces and npm Workspaces
When comparing pnpm workspaces and npm workspaces, several key differences emerge. pnpm focuses on performance and disk space efficiency through its unique hoisting mechanism. It creates a single version of each dependency, avoiding duplication across packages.
npm workspaces, on the other hand, employ a more traditional approach, installing dependencies separately for each package. While npm workspaces are simpler and may be familiar to users, they do not offer the same level of optimization as pnpm workspaces.
pnpm's workspace protocol also allows for smoother local package management, making it easier to work on interdependent packages without needing to publish changes. This is particularly useful for active development cycles.
Handling Multiple Versions of Packages
Handling multiple versions of packages in pnpm workspaces is a straightforward process. If a package requires a specific version of a dependency that differs from the version used elsewhere in the workspace, pnpm will place that dependency in the node_modules of the respective package.
For example, if my-package
needs lodash@4.17.0 and my-other-package
requires lodash@3.10.1
, pnpm will install both versions separately in their respective node_modules folders. You can specify the version you need in the package.json
of each package, and pnpm will manage these installations accordingly.
Related Article: How To Check Pnpm Version
Benefits of Using Workspaces
Using workspaces provides several advantages. They simplify management by allowing developers to work on multiple packages in a unified environment. This setup encourages better organization and consistency, as shared dependencies are easily managed.
Another significant benefit is the speed of installations. The hoisting mechanism reduces redundancy, making installations faster and minimizing disk usage. The workspace protocol enhances local development by allowing direct linking between dependent packages without needing to publish updates.