Nodejs Monorepo
Tools
Use Changesets as monorepo manager
Init a monorepo
mkdir monorepo && cd monorepogit init# Add .gitignore file for nodejs <https://github.com/github/gitignore/blob/master/Node.gitignore>npm init --yes
Add "private":"true"
to the root package.json
npm init -w packages/anpm init -w packages/bnpm init -w packages/c
Let c
depends a
and b
,
Add
"dependencies": {"a":"^1.0.0","b":"^1.0.0"}
to packages/c/package.json
Install changesets
Also see here
npm install -D @changesets/cli && npx changeset init
This action will add a .changeset
folder, and a couple of files to help you out:
You should change the .changeset/config.json
-> baseBranch
to yourself main branch, also change access
to public
Commit current files.
git add .git commit -m "feat: init"
That's done.
Usage
First publish
First publish you should just use the follow command to publish your module
npx changeset publish
Future changes
You should see changesets philosophy
You should first create an intent to change
, that said, before what ever changes you want to make, you should create a intent change
npx changeset
...Make some changes
Now, generate new version, changeset will take care your dependences,
Note, by default, if
a
upgrade from1.0.1
to1.0.2
,c
depends ona@^1.0.1
, thenc
package.json
will not change, cause npm will auto updatea@^1.0.1
to the last version1.0.2
if you want change to the exact version every time, you can set the config to"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {"updateInternalDependents": "always"}
npx changeset version
Then, you can publish it.
npx changeset publish
git add .git commit -m "chore: version"git push --follow-tags
With CI
I'll use Github Actions as example.
The CI workflow assume that you use Git workflows as your git workflow.
Note, you can use
@changesets/changelog-github
as your changelog format log. with this, you can generate a log like this , without this, then the log will only include commit link >npm i -D @changesets/changelog-github
{"changelog": ["@changesets/changelog-github",{ "repo": "theowenyoung/monorepo-example" }]}
- Create a script in root
package.json
{"scripts": {"version-packages": "changeset version","release": "changeset publish"}}
- Create github actions workflows
mkdir -p .github/workflows
touch .github/workflows/release.yml
With the following content:
name: Releaseon:workflow_dispatch:push:branches:- mainjobs:release:name: Releaseruns-on: ubuntu-lateststeps:- name: Checkout Repouses: actions/checkout@masterwith:# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commitsfetch-depth: 0- name: Setup Node.js 12.xuses: actions/setup-node@masterwith:node-version: 12.x- name: Setup NPM Latestrun: npm i -g npm- name: Install Dependenciesrun: npm i- name: Create Release Pull Request or Publish to npmuses: changesets/action@masterwith:# this expects you to have a script called release which does a build for your packages and calls changeset publishpublish: npm run releaseversion: npm run version-packagesenv:GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- Add
NPM_TOKEN
to your github repo secret settings
By Nodejs Tips:
npm token create
Done.
Every time you use npx changeset
to generate a new changeset intent, and the change is pulled to the main
branch, then CI will create a pull request to generate a new version, and after the pull request was merged, CI will publish npm packages, and create a new release.