This is a monorepo sample using pnpm while a bit overloaded with packages it shows you how easy is to create a monorepo setup with pnpm
Each of the packages (packages/**) has it's own readme to explain
how to work inside that specific package
first install pnpm
npm i -g pnpm
then run
pnpm recursive installpnpm run build:lib
after that you should be able to lift any of the applications you can check package.json on the root to see available commands
pnpm run dev:api2:website1pnpm run dev:api2:website2pnpm run dev:api2:website3
these run the nestjs backend with Aurelia, Vue or Angular (respectively).
To run a command from a specific package.json, use pnpm's filter commands
pnpm run dev --filter @monosample/api1
that will run the dev command in the @monosample/api1 package which resides in packages/api1/package.json, another example would be
pnpm run serve --filter @monosample/website2
that will run the serve command in the @monosample/website2 package which resides in packages/website2/package.json
The following structure is used in this sample
|- package.json
|- .npmrc
|- pnpm-workspace.yaml
|- packages
|- api1
|- api2
|- lib
|- website1
|- website2
|- website3
Important Notes:
- inside
.npmrcplease useshared-workspace-lockfile=false, this allows us to take advantage of pnpm 4.0.0+ package hoisting- inside
pnpm-workspace.yamlwe setup the actual structure that will be followed by pnpm please refer to pnpm docs- If you are using webpack in one of your packages please set
{ resolve: { symlinks: false } }this will prevent issues with webpack trying to locate the shared library packages (likepackages/lib)- Not required, but recommended to use scoped package names in your projects to prevent name collisions example.
packages/lib/package.json{ "name": "@monosample/lib", "version": "1.0.0", "private": true, } // packages/api1/package.json { //... "dependencies" : { //... "winston": "3.2.1", "@monosample/lib": "1.0.0" //... }, //... }- try to use npm scripts on your packages to simplify development | deployment | builds
that way it's easier to keep on your root ({ "scripts": { "build:lib": "pnpm run build --filter @monosample/lib", "build:lib:watch": "pnpm run build:watch --filter @monosample/lib", } }pnpm run build:lib) terminal instead having a terminal open for each package. If it ever becomes too messy, remember you can always put javascript files on your root and use any utility library inside your scripts- Messy dependencies, if you are using a dependency that for some reason does not mark a dependency of itself in it's package.json but requires it because it's available on
node_modulesyou might have trouble with tools like webpack trying to locate that package and it somehow "doesn't exist", you can always require that package manually but if you are starting to have a lot of issues with dependencies create an.npmrcfile on your project and add the following lineshamefully-hoist=truelike inpackages/website1/.npmrcorpackages/website2/.npmrcthis will make pnpm recreate a similar structure asnpm's/yarn's normal flat structure, you can find more information here: