Description
🐞 Bug report
Command (mark with an x
)
- new
- build
- serve
- test
- e2e
- generate
- add
- update
- lint
- extract-i18n
- run
- config
- help
- version
- doc
Is this a regression?
Yes, this didn't cause issues when using angular 11.
Description
Any builder that ends up using multiple instances of @angular-devkit/architect
results in an error.
Example scenario: package 1 exposes a builder that executes a builder in package 2, both packages have their own copy of @angular-devkit/architect
in node_modules, e.g. because of deviating versions or because the package manager doesn't hoist the dependency.
🔬 Minimal Reproduction
Clone https://github.com/bgotink/ngx-playwright/tree/repro-angular-schema-error and try to build
$ cd $(mktemp -d)
$ git clone --depth 1 https://github.com/bgotink/ngx-playwright --single-branch -b repro-angular-schema-error .
$ yarn
$ yarn ng build all
The last command uses a builder from one package to run multiple builders from another package. Both of these packages have an identical copy of @angular-devkit/architect
version 0.1200.0-rc.2
while the node_modules
folder itself contains @angular-devkit/architect
version 0.1200.0
.
Building works fine if the situation is identical but using angular 11 packages.
Building also works fine if I add a resolution to force only a single (hoisted) version of @angular-devkit/architect
to be installed.
🔥 Exception or Error
/.../node_modules/rxjs/internal/util/hostReportError.js:4
setTimeout(function () { throw err; }, 0);
^
Error: schema with key or id "BuilderProgressSchema" already exists
at Ajv._checkUnique (/.../node_modules/@angular-devkit/core/node_modules/ajv/dist/core.js:448:19)
at Ajv._addSchema (/.../node_modules/@angular-devkit/core/node_modules/ajv/dist/core.js:439:22)
at Ajv.runCompileAsync (/.../node_modules/@angular-devkit/core/node_modules/ajv/dist/core.js:156:30)
at async CoreSchemaRegistry._compile (/.../node_modules/@angular-devkit/core/src/json/schema/registry.js:215:25)
I've logged the ids of compiled schemas before and after compilation and noticed that two copies of the BuilderProgressSchema
schema are being compiled at the same time.
This didn't give rise to issues in angular 11 because the CoreSchemaRegistry
first tried to compile the schemas synchronously, which works for these schemas. In angular 12, the compilation is always asynchronous, which means multiple schemas can end up being compiled at the same time. This breaks as ajv only supports compiling one schema any given id. The relevant part of CoreSchemaRegistry#_compile
function boils down to
ajv.remove(schema);
// actual compilation happens no earlier than the next microtick thanks to an await in the ajv functions
await ajv.compileAsync(schema);
which ends up removing the schema twice and then compiling it twice, causing the error above.
🌍 Your Environment
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 12.0.0
Node: 14.15.3
Package Manager: yarn 2.4.1
OS: darwin x64
Angular: undefined
...
Package Version
------------------------------------------------------
@angular-devkit/architect 0.1200.0
@angular-devkit/core 12.0.0
@angular-devkit/schematics 12.0.0-rc.2
@angular/cli 12.0.0
@schematics/angular 12.0.0
typescript 4.2.4
Anything else relevant?