Since upgrading my Angular project from Angular12 to Angular 14, I receive following error:
ng serve --extra-webpack-config webpack.partial.js -o
or ng serve
or ng build
all result in:
****************************************************************************************
This is a simple server for use in testing or debugging Angular applications locally.
It hasn't been reviewed for security issues.
DON'T USE IT FOR PRODUCTION!
****************************************************************************************
- Generating browser application bundles (phase: setup)...An unhandled exception occurred: Script file node_modules/rxjs/bundles/rxjs.umd.js does not exist.
See "C:\Users\ME\AppData\Local\Temp\ng-LBMvnR\angular-errors.log" for further details.
/ Generating browser application bundles (phase: setup)...
It then keeps stuck in the Generating browser application bundles (phase: setup)...
phase forever. I'm sure that the problem comes from the ngx-build-plus tool, as these errors are quite similar:
https://github.com/manfredsteyer/ngx-build-plus/issues/314#issuecomment-1089107900 ngx-build-plus:externals not working for Angular 13
The suggested solution from the ngx-build-tool team seems to be to add:
window.ng.core = require('@angular/core');
window.ng.common = require('@angular/common');
But I don't understand where or how to add this.
My app.module.ts
file:
import {
CUSTOM_ELEMENTS_SCHEMA,
DoBootstrap,
Injector,
NgModule
} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { MyComponent } from './my/my.component';
import { createCustomElement } from '@angular/elements';
import { FormsModule } from '@angular/forms';
import { NoSanitizePipe } from './shared/nosanitize.pipe';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
FormsModule
],
declarations: [
AppComponent,
MyComponent,
NoSanitizePipe
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
bootstrap: [],
entryComponents: [MyComponent]
})
export class AppModule implements DoBootstrap {
constructor(private injector: Injector) {}
ngDoBootstrap(): void {
if (!customElements.get('my-element')) {
const webComponent = createCustomElement(MyComponent, {
injector: this.injector
});
customElements.define('my-element', webComponent);
console.log('registered my component');
} else {
console.warn('the my component was already registered');
}
}
}
angular.json
:
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"my-dashboard": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"options": {
"outputPath": "../app/src/main/resources/static/my-widget",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": [
{
"bundleName": "polyfill-webcomp-es5",
"input": "node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"
},
{
"bundleName": "polyfill-webcomp",
"input": "node_modules/@webcomponents/webcomponentsjs/bundles/webcomponents-sd-ce-pf.js"
},
"node_modules/@webcomponents/custom-elements/src/native-shim.js",
"node_modules/rxjs/bundles/rxjs.umd.js",
"node_modules/@angular/core/bundles/core.umd.js",
"node_modules/@angular/common/bundles/common.umd.js",
"node_modules/@angular/common/bundles/common-http.umd.js",
"node_modules/@angular/compiler/bundles/compiler.umd.js",
"node_modules/@angular/elements/bundles/elements.umd.js",
"node_modules/@angular/platform-browser/bundles/platform-browser.umd.js",
"node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"
]
},
"configurations": {
"dev": {
"fileReplacements": [
{
"replace": "src/environments/environment.local.ts",
"with": "src/environments/environment.dev.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
},
"staging": {
"fileReplacements": [
{
"replace": "src/environments/environment.local.ts",
"with": "src/environments/environment.staging.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
},
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.local.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
}
}
},
"serve": {
"builder": "ngx-build-plus:dev-server",
"options": {
"browserTarget": "my-dashboard:build"
},
"configurations": {
"production": {
"browserTarget": "my-dashboard:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "my-dashboard:build"
}
},
"test": {
"builder": "ngx-build-plus:karma",
"options": {
"main": "src/test.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "my-dashboard:serve"
},
"configurations": {
"production": {
"devServerTarget": "my-dashboard:serve:production"
}
}
}
}
}
},
"defaultProject": "my-dashboard",
"cli": {
"defaultCollection": "@angular-eslint/schematics"
}
}
package.json
:
{
"name": "my-dashboard",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"build-dev": "ng build -c=dev --single-bundle --output-hashing none && node concat",
"build-staging": "ng build -c=staging --single-bundle --output-hashing none && node concat",
"build-prod": "ng build -c=production --single-bundle --output-hashing none && node concat",
"test": "ng test",
"lint": "npx eslint src/**/*.{js,ts,jsx,tsx,vue,scss,json,css,html} --quiet",
"format": "npx prettier --write src/**/*.{js,ts,jsx,tsx,scss,json,scss,css,html}",
"e2e": "ng e2e",
"build:externals": "ng build --extra-webpack-config /webpack.externals.js --prod --single-bundle",
"postinstall:bak": "",
"postinstall": "ngcc"
},
"private": true,
"dependencies": {
"@angular-builders/custom-webpack": "^14.0.0",
"@angular/animations": "~14.0.0",
"@angular/common": "~14.0.0",
"@angular/compiler": "~14.0.0",
"@angular/core": "~14.0.0",
"@angular/elements": "^14.0.0",
"@angular/forms": "~14.0.0",
"@angular/platform-browser": "~14.0.0",
"@angular/platform-browser-dynamic": "~14.0.0",
"@angular/router": "~14.0.0",
"@contentful/rich-text-html-renderer": "^15.13.1",
"@webcomponents/custom-elements": "^1.5.0",
"@webcomponents/webcomponentsjs": "^2.6.0",
"contentful": "^9.2.4",
"ngx-build-plus": "^14.0.0",
"rxjs": "~7.5.6",
"tslib": "^2.4.0",
"zone.js": "~0.11.8"
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.0.0",
"@angular-eslint/builder": "14.0.4",
"@angular-eslint/eslint-plugin": "14.0.4",
"@angular-eslint/eslint-plugin-template": "14.0.4",
"@angular-eslint/schematics": "14.0.4",
"@angular-eslint/template-parser": "14.0.4",
"@angular/cli": "^14.2.2",
"@angular/compiler-cli": "~14.0.0",
"@types/jasmine": "~4.3.0",
"@types/node": "^18.7.17",
"@typescript-eslint/eslint-plugin": "5.37.0",
"@typescript-eslint/parser": "5.37.0",
"concat-files": "^0.1.1",
"eslint": "^8.23.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"istanbul": "^0.4.5",
"jasmine-core": "~4.4.0",
"jasmine-spec-reporter": "~7.0.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.1.1",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "^2.0.0",
"prettier": "^2.7.1",
"protractor": "~7.0.0",
"schematics-scss-migrate": "^1.3.15",
"ts-node": "~10.9.1",
"typescript": "~4.7.0"
},
"browser": {
"[module-name]": false
}
}
webpack.partial.js
:
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
"VERSION": JSON.stringify("4711")
})
]
}
webpack.externals.js
:
const webpack = require('webpack');
window.ng.core = require('@angular/core');
window.ng.common = require('@angular/common');
module.exports = {
"externals": {
}
}