Filtering in an MPR is important because, during development, changes are mainly made inside one or two packages. It wouldn't make sense to run commands on the whole repository if only a few packages were modified.
Filtering in Lerna (as of
v3.2.1) is achieved by the following flags:
scope- Include only packages with names matching the given glob.
include-filtered-dependents- Include all transitive dependents when running a command regardless of
include-filtered-dependencies- Include all transitive dependencies when running a command regardless of
ignore- Exclude packages with names matching the given glob.
private- Include private packages. Pass --no-private to exclude private packages.
since- Only include packages that have been updated since the specified [ref]. If no ref is passed, it defaults to the most recent tag.
These flags make filtering in Lerna quiet powerful. However, they are pretty hard to type. Let's say you downloaded a repository and want to work only on
login-page component. You'd want to run installation for
login-page and any of its dependencies:
lerna bootstrap --scope login-page --include-filtered-dependencies
Or maybe you changed a component called
site-header and would like to run tests on all the dependent packages:
lerna run test --scope site-header --include-filtered-dependents
These flags are not only hard to type but also hard to remember and easy to mix up.
Unlike Lerna, pnpm uses a special package selector syntax to restrict its commands. So instead of memorizing a set of long flag names, you should only remember a very easy-to-remember selector syntax.
As of version
2.15.0, these are the selectors that pnpm supports:
<pattern>- Restricts the scope to package names matching the given pattern. E.g.:
<pattern>...- Includes all direct and indirect dependencies of the matched packages. E.g.:
...<pattern>- Includes all direct and indirect dependents of the matched packages. E.g.:
./<directory>- Includes all packages that are inside a given subdirectory. E.g.:
.- Includes all packages that are under the current working directory.
These filters may be specified either via the
--filter flag or after a
--at the end of the command.
Note: as of
v2.15.0, filters after
--are not supported by
So if you want to bootstrap
login-page and all of its dependencies, this is the way you do it with pnpm:
pnpm recursive install -- login-page...
And if you want to run tests of
site-header and all of its dependents, use the
pnpm recursive test --filter ...site-header
Of course, you can combine as many selectors as you'd like:
pnpm recursive update -- ...site-header login-page... ./utils @style/*
The command above updates dependencies in:
- dependents of
- dependencies of
- all packages that are located in the
- all packages from the
pnpm might not have yet all the features that Lerna provides but for many users it might be enough already.
If you haven't heard about pnpm yet, I recommend reading also Flat node_modules is not the only way which explains the unique node_modules structure created by pnpm.
|Lerna v3.2||pnpm v2.15|
|--scope my-component||-- my-component|
|--scope toolbar-*||-- toolbar-*|
|--scope my-component --include-filtered-dependencies||-- my-component...|
|--scope my-component --include-filtered-dependents||-- ...my-component|
originally posted in pnpm blog