Setting up pure Angular 21 Workspace as a Monorepo
This document outlines the steps required to setup a pure Angular CLI (that is, without nx or other higher level tools) monorepo project. These instructions are for Angular 21, the current version at the time of writing this. The document is divided into two halves -- the first half covers setting up the workspace for multiple projects which are a mix of applications and libraries. The second half lists the steps required to configure vitest, the default test framework that Angular now uses.
Workspace configuration
-
Install
@angular/cliglobally. -
Create an empty Angular workspace.
$ ng new
--no-create-application This will create the folder
<workspace_name>. All future commands are to be run from this folder. 3. 3. -
Generate the required app projects.
$ ng g application
--project-root apps/ . Our monorepo has a folder structure where all applications are stored in separate subfolders under the parent folder
apps. -
Generate the required library projects.
$ ng g library
--project-root libs/ -
Update
<workspaceRoot>/tsconfig.jsonadding the paths to the libraries created. This will allow you to refer to the libraries you generated using a friendly name rather its entire path. For example, if one of the libraries you generated was named shared, you can updatetsconfig.jsonas:{ compilerOptions: { "baseUrl": ".", "paths": { "shared": ["libs/shared/src/public-api.ts"] } } }If you generated other libraries, add them to the
pathsas above. This will allow you to import a component from the library as:import { SharedComponent } from 'shared';
Also note that we added baseUrl. This directs tsc to refer to the paths relative to the value of this setting (It would assume paths are absolute otherwise).
Vitest Configuration
Angular 21 uses the quicker vitest for running its unit tests. However it's not set up when the workspace is created perhaps because we created an empty workspace to begin with. You're expected to do this explicitly.
Vitest is setup primarily by creating two files in each project in the workspace -- vitest.config.ts & test-setup.ts. The latter filename is just a convention, you can give it any name you want as long as you refer to the correct file in vitest.config.ts.
Also, if you would like to run and debug specific tests from your IDE (such as VSCode), you need to install a few additional packages. Let's assume that that's the environment that we're aiming for here. Adding these packages and tweaking the configuration to use these, would not in anyway degrade ng test command line. So we might as well do this.
$ npm install @analogjs/platform @analogjs/vite-plugin-angular @analogjs/vitest-angular -D
AnalogJS has published a few packages that makes the process of configuring the Angular's TestBed testing workhorse for invocation from the ng command line and the IDE's testing plugin seamless. Once you install this do the following (You need to repeat this for every project in the workspace):
- Update
angular.jsonsuch that the builder fortestarchitect's point to@analogjs/vitest-angular:testrather than the angular native unit test builder.
"test": {
"builder": "@analogjs/vitest-angular:test",
}
Now when you issue ng test, it will use the @analogjs package as the default builder. But for @analogjs/vitest-angular:test to work we need to go through a couple of more steps listed below.
-
Create
vitest.config.tsin each project's root folder. It's content should look like this:import { defineConfig } from 'vite'; import angular from '@analogjs/vite-plugin-angular';export default defineConfig(({ mode }) => ({ plugins: [angular()], test: { globals: true, setupFiles: ['src/test-setup.ts'], environment: 'jsdom', include: ['src/*/.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], reporters: ['default'], }, }));
Note how
test-setup.tsis referred to insetupFiles. We'll create this file in the next step. -
Create the file
test-setup.tsin project's src/ folder. It's content shou;d look like this:import '@analogjs/vitest-angular/setup-snapshots'; import { setupTestBed } from '@analogjs/vitest-angular/setup-testbed'; import '@angular/compiler';setupTestBed();
setupTestBed()will callTestBed.initTestEnvironment(), which readies theTestBedfor running the individual suite of tests. -
Create
tsconfig.spec.jsonin the project's root folder.{ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/spec", "types": ["vitest/globals"] }, "files": ["src/test-setup.ts"], "include": ["src//*.d.ts", "src//*.spec.ts"] }Pay attention to the
fileskey. It's value explicitly addstest-setup.tsto the list of files to be transpiled. -
If you're using VSCode, install the Vitest official plugin. This will allow you to run the tests from within the IDE by clicking on the green play button on the left margin.