When using pnpm as a package manager, if you have a workspace project, you may need to build the packages, which have dependencies between them. To control the build order and ensure dependencies are built first, you can use several strategies provided by pnpm.
1. Using pnpm -r or --recursive
pnpm supports running commands recursively within a workspace, automatically detecting dependencies between packages and executing commands in the correct sequence.
shpnpm -r --filter <filter-pattern> run <command>
For example, if you want to build all packages, you can use:
shpnpm -r run build
2. Using the --sort Flag
When running pnpm -r, adding the --sort flag ensures that pnpm executes commands in topological order, processing dependencies before the packages that depend on them.
shpnpm -r --sort run build
3. Using the pnpm-workspace.yaml File
By declaring the package order in the pnpm-workspace.yaml file, pnpm considers this order when executing commands.
yamlpackages: - 'packages/utils' - 'packages/core' - 'packages/app'
pnpm will process packages/utils first, then packages/core, and finally packages/app.
4. Using Filter Flags
pnpm supports using filter flags to limit the scope of packages on which commands are run.
shpnpm -r --filter "<package-name>" run build
You can specify multiple filter conditions to control the execution order.
5. Writing Custom Scripts
If you have complex build requirements, you can write custom scripts to control the build process. For example, you can use a Node.js script to analyze package.json files for dependencies and execute build tasks according to your specific needs.
javascriptconst { execSync } = require('child_process'); const { getWorkspaces } = require('some-workspaces-tool'); const buildPackage = (packageName) => { console.log(`Building ${packageName}...`); execSync(`pnpm run build`, { stdio: 'inherit', cwd: `packages/${packageName}` }); }; const workspaces = getWorkspaces(); // Custom logic to sort and build packages workspaces.sort(customSortFunction).forEach((workspace) => { buildPackage(workspace.name); });
Example:
Suppose you have a package named @company/core that depends on @company/utils. You want to build @company/utils before @company/core.
You can specify the package order in pnpm-workspace.yaml as follows:
yamlpackages: - 'packages/utils' - 'packages/core'
Then run the following command to ensure the correct build order:
shpnpm -r --sort run build
This will build the utils package first, followed by the core package.
By using these tools and strategies from pnpm, you can effectively manage the build order of your workspace projects, ensuring correctness and efficiency.