This is just a quick example of how you can setup VS Code to work with a Lerna monorepo, along with working examples of:
Effectively, this is what I wish I had when I first got started and it is my hope to save anyone else some frustration.
A semi-functional, contrived TypeScript application based on two Lerna dependencies:
- packages/url-fetch
- packages/eslint-config-typescript
An example TypeScript dependency that's purpose is to fetch webpage with a redirect and return the new url.
An example dependency that's contain a common set of TypeScript ESlint configuration that extends and overrides the package eslint-config-airbnb-typescript so that each Lerna package does not have to have its .eslint.yaml be separately maintained.
Install Lerna globally.
npm install --global lerna
Install Yarn globally.
npm install --global yarn
git clone https://github.com/abd1tus/typescript-monorepo-example.git
cd typescript-monorepo-example
lerna bootstrap
cd typescript-monorepo-example
yarn test
cd typescript-monorepo-example
yarn lint
cd typescript-monorepo-example
yarn build
The beauty behind Lerna is its ability make editing interdependent packages together much easier by automatically updating package versions for you as needed, as well as committing those changes to git, and publishing to npm (or other, if configured).
cd typescript-monorepo-example
lerna publish
or to force updates of all Lerna tracked packages.
cd typescript-monorepo-example
lerna publish --force-publish
If you are not publishing packages to npm:
cd typescript-monorepo-example
lerna publish -skip-npm
Note, packages in the project are marked as private in package.json so that they cannot be accidentally published to npmjs.com (or any others). In your own project you may want to choose to leave some packages public, and others marked as private that do not need to be packaged - such as AWS lambda functions that don't get re-used anywhere.
The lerna bootstrap
command sets up symbolic links between packages so that updates to one package (after a build) can be seen by other packages without the need to push to git or re-deploy custom npm packages.
Important: If libraries fall out of sync and you need to refresh VS Code, open the command palette (Ctrl + Shift + P, if you are on Windows; Cmd + Shift + P, if you are on a Mac) and run Developer: Reload Window
.
In VS Code, using File -> Open Workspace... open the file typescript-monorepo-example/workspace.code-workspace
found in the project root. This will create separate directories within the VS Code workspace window. If the entire typescript-monorepo-example repo was loaded as a single folder within VS Code then problems occur with parsing and working with the ESlint files. (If anyone knows a workaround for this, please contact me so I can update this example.)
One of the problems I've run into with VS Code is it won't show you errors in files that aren't open, especially in monorepos. A way around this is to run tsc watch tasks, which will compile code automatically when changes occur, even across packages, and highlight errors. tsc watch tasks are included in tin .vscode/tasks.json
in the package folders.
Note: these watch tasks have to be started manually once the workspace is loaded. However, they are configured with "runOn": "folderOpen"
, so running Tasks: Allow Automatic Tasks in Folder
from the command palette will allow them to launch anytime the project is opened without needing to manually start them.
Make sure the ESLint plugin is installed in VS Code.
Material Icon Theme makes looking at workspaces nicer.
Debugger configurations are setup for packages/app
and packages/url-fetch
so that debugging can be run from VS Code during tests. Unfortunately a limitation of having packages/app
and packages/url-fetch
be open across separate VS Code folders within a workspace is that you cannot debug from one package to another, so focused tests should be written in each package as needed. These debugger configurations can be found in .vscode/launch.json
in the package folders.
The entire use of Lerna is beyond the scope of this project, but here are some cool highlights:
lerna exec --parallel -- rm bad-file.txt
lerna exec --parallel -- rm bad-file.txt
lerna exec -- yarn outdated
(Note this won't work on this repo since its packages are not published in npm.)
lerna exec -- yarn audit