manfredsteyer / ngx-build-plus

Extend the Angular CLI's default build behavior without ejecting, e. g. for Angular Elements
1.19k stars 136 forks source link

Angular elements with ngx-build-plus and Ivy compiler #198

Open sistla001 opened 4 years ago

sistla001 commented 4 years ago

We were using ngx-build-plus (v9.0.6) with angular elements to externalize libraries from main bundle. This all worked fine with Angular 7 until we upgraded to Angular 9.1.11 (Ivy). Both our angular elements and SPA are in Angular 9.1.11 (using Ivy) and we are getting the following error:

Uncaught NullInjectorError: StaticInjectorError(Platform: core)[CompilerFactory]: 
  NullInjectorError: No provider for CompilerFactory!
    at NullInjector.get (core.umd.js:1147:29)
    at resolveToken (core.umd.js:12326:28)
    at tryResolveToken (core.umd.js:12270:20)
    at StaticInjector.get (core.umd.js:12164:24)
    at compileNgModuleFactory__PRE_R3__ (core.umd.js:28612:40)
    at PlatformRef.bootstrapModule (core.umd.js:28854:20)
    at Module.zUnb (main.js:1:4220)
    at n (main.js:1:110)
    at Object.0 (main.js:1:943)
    at n (main.js:1:110)

More background that may help: I got below error when upgrading ngx-build-plus to 9.0.6 first when I ran ng update ngx-build-plus after upgrading angular element to angular 9.1.11. Though it failed, I proceeded with the build and landed with above error. Not sure if they are related.

Using package manager: 'npm' Collecting installed dependencies... Found 51 dependencies. Fetching dependency metadata from registry... Updating package.json with dependency ngx-build-plus @ "9.0.6" (was "7.8.3")... UPDATE package.json (2492 bytes) √ Packages installed successfully. Executing migrations of package 'ngx-build-plus'

Updates references to builders for ngx-build-plus × Migration failed: Cannot read property 'architect' of undefined log:

TypeError: Cannot read property 'architect' of undefined
at node_modules\ngx-build-plus\schematics\add-ngx-build-plus\index.js:8:55
at MergeMapSubscriber.project (node_modules\@angular\cli\node_modules\@angular-devkit\schematics\src\rules\call.js:74:24)
at MergeMapSubscriber._tryNext (node_modules\@angular\cli\node_modules\rxjs\internal\operators\mergeMap.js:69:27)
at MergeMapSubscriber._next node_modules\@angular\cli\node_modules\rxjs\internal\operators\mergeMap.js:59:18)
at MergeMapSubscriber.Subscriber.next (node_modules\@angular\cli\node_modules\rxjs\internal\Subscriber.js:66:18)
at Observable._subscribe (node_modules\@angular\cli\node_modules\rxjs\internal\util\subscribeToArray.js:5:20)
at Observable._trySubscribe (node_modules\@angular\cli\node_modules\rxjs\internal\Observable.js:44:25)
at Observable.subscribe (node_modules\@angular\cli\node_modules\rxjs\internal\Observable.js:30:22)
at MergeMapOperator.call (node_modules\@angular\cli\node_modules\rxjs\internal\operators\mergeMap.js:39:23)
at Observable.subscribe (node_modules\@angular\cli\node_modules\rxjs\internal\Observable.js:25:31)
at MapOperator.call (node_modules\@angular\cli\node_modules\rxjs\internal\operators\map.js:32:23)
at Observable.subscribe (node_modules\@angular\cli\node_modules\rxjs\internal\Observable.js:25:31)
at Object.subscribeToResult (node_modules\@angular\cli\node_modules\rxjs\internal\util\subscribeToResult.js:12:23)
at MergeMapSubscriber._innerSub (node_modules\@angular\cli\node_modules\rxjs\internal\operators\mergeMap.js:82:53)
at MergeMapSubscriber._tryNext (node_modules\@angular\cli\node_modules\rxjs\internal\operators\mergeMap.js:76:14)
at MergeMapSubscriber._next (node_modules\@angular\cli\node_modules\rxjs\internal\operators\mergeMap.js:59:18)

This issue was closed stating it as ngx-build-plus issue:

https://github.com/angular/angular/issues/37215

Works fine when Ivy is disabled and building angular elements.

Any help regarding this would be appreciated

manfredsteyer commented 4 years ago

Do you get the same error when creating a brand new project with a hello world Angular Element?

radhwan commented 4 years ago

Yes, with Angular 10 , I have the same issue "@angular-extensions/elements": "^10.0.2", "@angular/animations": "~10.0.9", "@angular/common": "~10.0.9", "@angular/compiler": "~10.0.9", "@angular/core": "~10.0.9", "@angular/elements": "^10.0.12", "@angular/forms": "~10.0.9", "@angular/platform-browser": "~10.0.9", "@angular/platform-browser-dynamic": "~10.0.9",

image

infacto commented 3 years ago

Same here (more or less. Not related to Ivy. Just fails on installation.):

npx ng add ngx-build-plus
Installing packages for tooling via npm.
Installed packages for tooling via npm.
Cannot read property 'architect' of undefined

Angular 10.1.1

diminutivesloop commented 3 years ago

I'm seeing this as well with Angular 9.1.12. It doesn't happen when Ivy is disabled but I need Ivy enabled for this project.

manfredsteyer commented 3 years ago

Hm, interesting.

Perhaps there no defaultProject configured in your angular.json?

You can use ng add @ngx-build-plus --project projectNameFromAngularJson

Can you try this?

ringodotnl commented 3 years ago

Having the exact same issue, did an update from ng8 to ng10.

A 'fix' (hint) is to not exclude ng.core, ng.platformBrowser and ng.compiler in webpack.externals as in:

const webpack = require('webpack');

module.exports = {
  externals: {
    rxjs: 'rxjs',
    // '@angular/core': 'ng.core',
    '@angular/common': 'ng.common',
    '@angular/common/http': 'ng.common.http',
    // '@angular/platform-browser': 'ng.platformBrowser',
    '@angular/platform-browser-dynamic': 'ng.platformBrowserDynamic',
    '@angular/compiler': 'ng.compiler',
    // '@angular/elements': 'ng.elements',
    '@angular/router': 'ng.router',
    '@angular/forms': 'ng.forms',
  },
};

These package are in the app.module.ts:

import { Injector, ModuleWithProviders, NgModule } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { BrowserModule } from '@angular/platform-browser';

Any ideas @manfredsteyer how to fix this for ng10 ?

Cheers, Ringo.

ringodotnl commented 3 years ago

Extra info: Tried a ne new clean project with Angular 10, same error.

Also tested: Removed the content in the script array at file angular.json. Did make a bundle of the files in the array, This bundle is loaded defer in the index.html. Then with ng serve added --extra-webpack-config to webpack.externals.js. Result: the 'ng serve' did give the same error as ng build.

Error message: *****.js:14138 Uncaught NullInjectorError: StaticInjectorError(Platform: core)[CompilerFactory]: NullInjectorError: No provider for CompilerFactory!

ryousfi commented 3 years ago

@manfredsteyer We ve got the same behavior using Angular 9 environment. Any feedback on that will be much appreciated.

ERROR: myscript.js:371 Uncaught NullInjectorError: StaticInjectorError(Platform: core)[hg]: NullInjectorError: No provider for hg!

NagornovAlex commented 3 years ago

I was trying to migrate mfes from angular 9 (without ivy) to v11 and ran into same error.

The error: externals.umd.js:20616 Uncaught NullInjectorError: StaticInjectorError(Platform: core)[CompilerFactory]: NullInjectorError: No provider for CompilerFactory! at NullInjector.get (http://localhost:4200/externals.umd.js:20616:29) at resolveToken (http://localhost:4200/externals.umd.js:21368:28) at tryResolveToken (http://localhost:4200/externals.umd.js:21313:20) at StaticInjector.get (http://localhost:4200/externals.umd.js:21207:24) at compileNgModuleFactoryPRE_R3 (http://localhost:4200/externals.umd.js:38654:40) at PlatformRef.bootstrapModule (http://localhost:4200/externals.umd.js:38909:20) at Module.0wko (http://localhost:4200/assets/main.js:2471:77) at webpack_require (http://localhost:4200/assets/main.js:20:30) at Object.0 (http://localhost:4200/assets/main.js:1929:18) at __webpack_require__ (http://localhost:4200/assets/main.js:20:30)

We use ngx-build-plus and webpack-externals approach as described in the @manfredsteyer 's mfe guide.

Does it mean that for ng11 the approach is not valid any more and we will have to migrate our mfes to module federation approach?

alexzuza commented 3 years ago

This error means that the application uses not compiled by ngcc compiler version of umd file.

Angular CLI by default runs ngcc for fesm2015 module format.

Simply add this command to package.json

"postinstall": "ngcc -s ./node_modules/@angular -p main",
NagornovAlex commented 3 years ago

This error means that the application uses not compiled by ngcc compiler version of umd file.

Angular CLI by default runs ngcc for fesm2015 module format.

Simply add this command to package.json

"postinstall": "ngcc -s ./node_modules/@angular -p main",

Thanks, Alexey! That fixed the issue. I had to run ngcc for each 3rd party module used in MFE module and then generated web-externals bundle (umd libs) again and everything worked out. Also its possible to run 'ngcc -s ./node_modules -p main' for all modules.

alexzuza commented 3 years ago

@NagornovAlex

Also its possible to run 'ngcc -s ./node_modules -p main' for all modules.

Yes, it's possible even with

ngcc -p main

because default value for -s(source) flag is ./node_modules

dreamerkumar commented 3 years ago

As observed here by @ringodotnl when I tried this in Angular 10, the Angular Element didnt work at first without commenting out the below two from the externals: "@angular/platform-browser": "ng.platformBrowser", "@angular/platform-browser-dynamic": "ng.platformBrowserDynamic", But looking inside the umd file for them, I saw dependencies on angular animations. So I included that in the externals and in the angular json scripts. And it worked!!

In externals:

        "@angular/animations": "ng.animations",
        "@angular/platform-browser": "ng.platformBrowser",
        "@angular/platform-browser-dynamic": "ng.platformBrowserDynamic",

In scripts section of angular json:

              "node_modules/@angular/animations/bundles/animations.umd.js",
              "node_modules/@angular/platform-browser/bundles/platform-browser.umd.js",
              "node_modules/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"
ravitejrai commented 3 years ago

The idea is to import correct umd bundles. For IVY the umd bundles need to be imported from the IVY_NGCC folder created inside of your node_modules. To generate these you need to have the postinstall defined under your script tag as ngcc --properties main create-ivy-entry-points or ngcc --properties main es2015.

"node_modules/@angular/animations/bundles/ivy_ngcc/animations.umd.js", "node_modules/@angular/platform-browser/bundles/ivy_ngcc/platform-browser.umd.js", "node_modules/@angular/platform-browser-dynamic/bundles/ivy_ngcc/platform-browser-dynamic.umd.js" In the later case you won't find any IVY_NGCC folder inside of node_modules and you will have to import umd.js files instead of umd.min.js

pvasantha commented 3 years ago

We've got the same kind of issue using the Angular 11 environment. Any feedback on that will be much appreciated.

core.11.0.5.js:1416 Uncaught NullInjectorError: StaticInjectorError(Platform: core)[Lg]: NullInjectorError: No provider for Lg!

JakobBablitschky commented 3 years ago

Hi, I'm currently creating some proof of concepts for a project and wanted to do one with this MFE approach (Using ngx-build-plus). Everything worked as expected so far, but I ran into the same issue when adding keycloak. This was my order of doing things (Only in shell application):

Deleting the node_modules folder and doing "npm install" again seemed to solve it somehow. (BTW - executing only ngcc did not help)

Don't know if this is gonna help someone, but I just thought I'll leave it here.