We published quite a few open-source packages on NPM.
Developing multiple NPM packages that rely on each other is not easy task. There are a lot of ways that things can go wrong: keeping stuff in sync, publishing etc.
We tried a couple of other tools to solve this problem: git repo npm modules, npm link
and yalc
so far but no of them was as good as pnpm
.
Our go-to method now is a pnpm workspace monorepo with git submodules. Very convenient solution for projects with multiple separate git repositories.
pnpm
makes it convenient to manage and develop multiple separate packages without using any other tools like npm link
or yalc
changeset
node_modules
, dist
, or build your projectsFollow this step-by-step guide on to create a pnpm
monorepo with git submodules. All you need is a terminal.
1# create a new directory and cd into it 2mkdir mono-repo 3cd mono-repo 4 5# creates a package.json file 6pnpm init 7 8# creates an empty git repository 9git init
.gitignore
file etc.)in this example there will be 2 folders apps
and packages
apps
for a create-react-app
, which will consume packagespackages
for several git submodules, each of them is a separate git repo, which are reusable packagespnpm-workspace.yaml
1# pnpm-workspace.yaml 2packages: 3 # executable/launchable applications 4 - 'apps/*' 5 # all packages in subdirs of packages/ and components/ 6 - 'packages/*'
add your submodules
1# add your submodules in the packages folder 2cd packages 3git submodule add https://github.com/<user>/rock rock 4 5# this will tell git to download the contents of the submodules, if the folders are empty 6git submodule update --init --recursive
the following cra will live in the apps
folder and will be part of the root, not a separate git repository
1cd apps 2npx create-react-app example
example
react app can use the submodules as dependenciespackages
folder, otherwise pnpm will fetch it from remote npm registry (if it is published), workspace protocolpnpm import
generates a pnpm-lock.yaml
from another package manager's lockfile
1# cd into a submodule 2rm -rf node_modules 3pnpm import 4# now remove the other package managers lockfile 5 6# go back to the root and install dependencies 7pnpm install
Long story short, pnpm does not version packages so when the time comes to publish a submodule to npm, some other tool needs to be used for that
1# add changeset in the root as devDependencpnpm add -Dw @changesets/cli 2 3# run the init command 4pnpm changeset init 5 6# generate a new changeset 7# the following command will ask which packages should get a new version 8pnpm changeset 9 10# this will bump the versions previously specified with pnpm changeset 11pnpm changeset version 12 13# update lockfile and rebuild dependencies 14pnpm install
example
React app, and if any of its dependencies has a new version, it will update the package.json
version of that package--filter
command--recursive
command1# build only one project 2pnpm --filter <package> run build 3 4# run all of them at once 5pnpm -r run build
pnpm
workspace in suggestcat-repo, suggestcat
is a set of ProseMirror
plugins, which gives AI suggestionspnpm
workspace we can develop suggestcat
easily, because we have 4 different submodules which depend on each other, and our React app with the ProseMirror editor consumes all of those packages, without a monorepo we would have to publish to npm registry all the time we change something in any of the repos, or use npm link
locally, which is quite cumbersome, or some other tools like yalc
which seemed to be working just fine for the first time, but with 4 packages it needed to be restarted all the time