ngx-build-plus:externals not working for Angular 14

1k Views Asked by At

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.tsfile:

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": {

   }
 }
0

There are 0 best solutions below