|
|
||
|---|---|---|
| .forgejo/workflows | ||
| .vscode | ||
| src | ||
| tests | ||
| .gitignore | ||
| .npmrc | ||
| .releaserc.json | ||
| biome.json | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
Workspace Tools CLI
Tired of JavaScript dev tooling bloat ?
Workspace Tools CLI will help you managing your NPM workspaces.
The philosophy :
- no dependency
- zero config
- fast
This tool is NOT for you if :
- maintaining ever changing NX and Lerna configurations is your purpose in life
- you love patching your 915092 transitive dependencies (or leaking your credentials in supply chain attacks)
- you have to convince your boss with jargon like ai-powered-self-healing-ci-cloud-cache-task-splitting-distribution
Why
The difficulty in monorepos is building/testing only what's changed.
The problems with NPM CLI :
- only allow us to target all workspaces with the
--workspacesflag - does not fail fast despite this old request
This means that the execution time of continuous integration increases linearly as the monorepo grows. The main objective of this tool is to address these issues.
Installation
npm add --save-dev @workspace-tools/cli
Simple, right? No npx init scripts, no boilerplate starter CLI, just drop it at the root of your monorepo.
Usage
npx workspace-tools affected:<npm-script-name>
This command will calculate your dependency graph based on what you have declared in the dependencies key of your package.json files, then execute the provided npm script in a fail fast way with the command npm run <npm-script-name> --workspace /path/to/workspace --if-present.
After each successful command, it will record the state of all workspaces in a .workspaces-state file at the root of the monorepo in order to calculate only what's changed on the next execution.
Keep in mind that as a generated file, the .workspaces-state should not be committed in your git repository and should be added to your .gitignore.
Usage in CI
The ./.workspaces-state file must be cached to improve your workflow execution time in CI.
Github Actions/Forgejo Actions usage
In .github/workflows/ci.yml file:
name: Affected Continuous Integration
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v5
with:
node-version: 23
- name: Restore workspaces state
id: workspaces-state
uses: actions/cache/restore@v4
with:
path: |
./.workspaces-state
key: workspaces-state
- name: Install dependencies
run: npm ci
- name: Lint affected workspaces
run: npx workspace-tools affected:lint
- name: Save workspaces state
uses: actions/cache/save@v4
with:
path: |
./.workspaces-state
key: ${{ steps.workspaces-state.outputs.cache-primary-key }}
Example
Consider this files structure :
package.json
applications/
├─ billing/
├─ test-billing/
libs/
├─ invoices/
│ ├─ package.json
First, the root package.json must contain a workspaces field listing all items inside the monorepo.
./package.json:
{
"workspaces": [
"./applications/billing",
"./applications/test-billing",
"./libs/invoices"
]
}
The billing workspace declares a dependency to the invoices workspace.
./applications/billing/package.json:
{
"name": "billing",
"dependencies": {
"invoices": "*"
}
}
The test-billing workspace declares a dependency to the application workspace.
./applications/test-billing/package.json:
{
"name": "test-billing",
"scripts": {
"test": "echo \"Running billing tests!\""
},
"dependencies": {
"billing": "*"
}
}
And the invoices workspace has no dependency.
./libs/invoices/package.json:
{
"name": "invoices",
}
Note that the name field is the only required field.
License
The code and documentation in this project are released under the GNU General Public License v3.0.