angular: ngcc fails in monorepo setup with libraries built with view engine and consumed with tsconfig paths

🐞 bug report

Affected Package

Probably @angular-devkit/build-angular or @angular/compiler.

Is this a regression?

Works with v8.

Description

We are using a monorepo setup with 1 application and two libraries. One library gets published and one is private. In short:

  • lib1 component library published to internal nexus
  • lib2 private to the monorepo consuming lib1
  • documentation app for lib1 consuming both lib1 and lib2, in the reproduction sample it only consumes lib2 for simplicity
  • for the application build we point to the build artifacts in the dist folder via tsconfig paths

I created a simple reproduction repository: https://github.com/Phil147/ngcc-monorepo/tree/rc6 https://github.com/Phil147/ngcc-monorepo/tree/master with RC8

Lib1 has a secondary entry point for a button component. Lib2 uses the button in a component. Both libraries build correctly but then ngcc fails during the application build.

Run npm run build:all which will build the libraries and then the application, all in production mode meaning the libraries with view engine.

In the rc6 branch the error is

ERROR in Failed to compile entry-point lib2 due to compilation errors:
dist/lib1/button/button.module.d.ts:1:22 - error NG6002: Appears in the NgModule.imports of Lib2Module, but could not be resolved to an NgModule class

1 export declare class ButtonModule {

On the master branch with rc8: ERROR in Cannot read property 'injectorImports' of undefined

🔬 Minimal Reproduction

https://github.com/Phil147/ngcc-monorepo/tree/rc6 https://github.com/Phil147/ngcc-monorepo/tree/master

Run npm ci and npm run build:all on both branches to see the errors.

🔥 Exception or Error


ERROR in Failed to compile entry-point lib2 due to compilation errors:
dist/lib1/button/button.module.d.ts:1:22 - error NG6002: Appears in the NgModule.imports of Lib2Module, but could not be resolved to an NgModule class

1 export declare class ButtonModule {

ERROR in Cannot read property 'injectorImports' of undefined

🌍 Your Environment

Angular Version:


Angular CLI: 9.0.0-rc.8
Node: 12.13.0
OS: darwin x64

Angular: 9.0.0-rc.8
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.900.0-rc.8
@angular-devkit/build-angular      0.900.0-rc.8
@angular-devkit/build-ng-packagr   0.900.0-rc.8
@angular-devkit/build-optimizer    0.900.0-rc.8
@angular-devkit/build-webpack      0.900.0-rc.8
@angular-devkit/core               9.0.0-rc.8
@angular-devkit/schematics         9.0.0-rc.8
@ngtools/webpack                   9.0.0-rc.8
@schematics/angular                9.0.0-rc.8
@schematics/update                 0.900.0-rc.8
ng-packagr                         9.0.0-rc.3
rxjs                               6.5.3
typescript                         3.6.4
webpack                            4.41.2

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 3
  • Comments: 15 (8 by maintainers)

Most upvoted comments

For others who might find this in regards to install a snapshot build: I only got it running with npm i git://github.com/angular/compiler-cli-builds.git#be5a9df8d5759975533849e268b4191c5465efec just using the URL in the package.json gave me some errors like

npm ERR! code ENOPACKAGEJSON
npm ERR! package.json Non-registry package missing package.json: https://github.com/angular/compiler-cli-builds/tree/be5a9df8d5759975533849e268b4191c5465efec.
npm ERR! package.json npm can't find a package.json file in your current directory.

@petebacondarwin Thanks for your awesome work our monorepo built successfully with ivy for the first time 🎉 💪 this is awesome. The documentation app for our library went down from 3,4 to 2,3 MB in bundle size. You guys are really awesome! 🙏

Guys, i have some solution but im not sure how currect it is.

1. "buildOptimizer": false,
2. "enableIvy": true
3. "aot": false,

Before do this refactoring, application size is: 18 440KB; After: 17 887KB

I can confirm that #35227 also fixes this locally for me.

@Phil147 oh, sorry! I meant #34500, not #34508.

So glad to here it!

Yes you can! Try using this URL as the npm source in your package.json: https://github.com/angular/compiler-cli-builds#be5a9df8d5759975533849e268b4191c5465efec

@petebacondarwin cool thanks for that quick fix 🎉 Is there any way to use the build artifacts of the PR to test it against our production repository?

Hi @alxhub thanks for your answer! Happy to hear that a fix is on the way. 🎉 The PR you linked is about zonejs is this really related to this issue? I would love to track the original issue 👍

This is an instance (duplicate) of #34500. A fix is in the works!

we have the same issue in our app. we have set of libraries packaged (ng-packagr with --prod and enableIvy false) and published to internal npm registry. then consumed by our app. we migrated our app and library projects to v9 but when consumed through the npm packages it fails with above errors.

i also noticed that output esm2015 and fesm2015 scripts have differences compared to v8 output. v8 esm2015 module file. not sure if this causing the error (need to check later)

/**
 * @fileoverview added by tsickle
 * Generated from: http2Module.ts
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import { HttpClientJsonpModule, HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { CoreModule } from '@anthem/mbrportal/core';
import { HttpClient2 } from './services/httpClient2';
import { UrlHelper } from './services/urlHelper';
export class Http2Module {
    /**
     * @return {?}
     */
    static forRoot() {
        return {
            ngModule: Http2Module,
            providers: [UrlHelper, HttpClient2]
        };
    }
}
Http2Module.decorators = [
    { type: NgModule, args: [{
                imports: [HttpClientModule, CoreModule, HttpClientJsonpModule],
                declarations: [],
                entryComponents: [],
                exports: []
            },] }
];

v9 esm2015 module file

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var Http2Module_1;
import { HttpClientJsonpModule, HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { CoreModule } from '@anthem/mbrportal/core';
import { HttpClient2 } from './services/httpClient2';
import { UrlHelper } from './services/urlHelper';
let Http2Module = Http2Module_1 = class Http2Module {
    static forRoot() {
        return {
            ngModule: Http2Module_1,
            providers: [UrlHelper, HttpClient2]
        };
    }
};
Http2Module = Http2Module_1 = __decorate([
    NgModule({
        imports: [HttpClientModule, CoreModule, HttpClientJsonpModule],
        declarations: [],
        exports: []
    })
], Http2Module);
export { Http2Module };