angular / angular-cli

CLI tool for Angular
https://cli.angular.io
MIT License
26.74k stars 11.98k forks source link

Bootstrap Module cannot be from library #18286

Closed M4R1KU closed 4 years ago

M4R1KU commented 4 years ago

šŸž Bug report

I guess this is a bug but it could also be a feature request, since I am not exactly sure what the design decisions were.

Command (mark with an x)

Is this a regression?

No it is not.

Description

We are implementing a lot of Microservices where each Service also contains their own frontend. We then have a shell application which collects information about all microservices and loads the frontends of those services into the shell so that they are usable for the user.

Each service also comes with a standalone mode, which currently is just a really small angular app that wraps the module which is normally lazy-loaded into the shell.

With time the requirement came, that the standalone shells of the services should contain some basic functionalities, which the main shell also provides, like for example a logout button or a forbidden page.

My intention was to create a npm library which contains a StandaloneShellModule, which acts as the AppModule for those standalone shells and provides those basic functionalities i mentioned above.

The original problem i faced, was that angular complained that my StandaloneShellModule is not part of the typescript compilation.

ERROR in ./node_modules/@company/shell/lib/standalone-shell.module.d.ts
Module build failed (from ./node_modules/@ngtools/webpack/src/index.js):
Error: D:\project\frontend\node_modules\@company\shell\lib\standalone-shell.module.d.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.
The missing file seems to be part of a third party library. TS files in published libraries are often a sign of a badly packaged library. Please open an issue in the library repository to alert its author and ask them to package the library using the Angular Package Format (https://goo.gl/jB3GVv).

I then found out that the cli for some reason rewrites the imports for platformBrowserDynamic and the module given to bootstrapModule. The compiled main.js looked something like this.

import * as __NgCli_bootstrap_1 from "./../node_modules/@company/shell/lib/standalone-shell.module.d";
import * as __NgCli_bootstrap_2 from "@angular/platform-browser";
if (environment.production) {
    enableProdMode();
}
__NgCli_bootstrap_2.platformBrowser().bootstrapModule(__NgCli_bootstrap_1.StandaloneShellModule)

I searched for the place where this happened in the cli and found this file. https://github.com/angular/angular-cli/blob/master/packages/ngtools/webpack/src/transformers/replace_bootstrap.ts

šŸ”¬ Minimal Reproduction

I do not provide a reproduction, because the issue is more of a question why the CLI is designed this way and why it does not support third party modules to be bootstrapped.

šŸ”„ Exception or Error

-

šŸŒ Your Environment

Angular CLI: 9.1.1 Node: 14.4.0 OS: win32 x64

Angular: 9.1.1 ... 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.901.1 @angular-devkit/build-angular 0.901.1 @angular-devkit/build-optimizer 0.901.1 @angular-devkit/build-webpack 0.901.1 @angular-devkit/core 9.1.1 @angular-devkit/schematics 9.1.1 @angular/cdk 9.2.1 @angular/material 9.2.1 @ngtools/webpack 9.1.1 @schematics/angular 9.1.1 @schematics/update 0.901.1 rxjs 6.5.5 typescript 3.8.3 webpack 4.42.0

alan-agius4 commented 4 years ago

Hi @M4R1KU,

The reason for that transformer is to replace the bootstrapping mechanising from JIT to AOT. This is needed to avoid the need for users to do code changes to for their application to work in both JIT and AOT mode. In case of when using the old rendering engine (VE) we need to amend the import to point to an ngfactory file, however if this happens to be part of an external library we'll be unable to resolve the file correctly at a compiler level.

Typically the bootstrapping module is part of the application and not an external library. It's important to point out that the compilation of a library is different from that of the application and certain application features are not meant to be used in a library. The most common one being lazy-loading modules and routing are designed and meant to be used in an application. More context: https://github.com/angular/angular-cli/issues/6373.

If you are using AOT for your dev builds you can try to change the application bootstrapping code to use @angular/platform-browser directly instead if @angular/platform-browser-dynamic.

M4R1KU commented 4 years ago

Hi @alan-agius4

Thanks for your answer. I tried your suggestions and it seems to work fine. We've been using Ivy and AOT already and if i take it correctly, there was no need to call platformBrowserDynamic over platformBrowser even before my special requirement, right?

Another question just out of curiosity. Will there be some point when Angular wont have a JIT mode anymore? My understanding of Ivy was that there is no need for JIT, since Ivy is always compiled ahead-of-time. I assume VE will be deprecated in one of the next releases (12? 13?).

alan-agius4 commented 4 years ago

if i take it correctly, there was no need to call platformBrowserDynamic over platformBrowser even before my special requirement, right?

platformBrowserDynamic is only needed when the application is in JIT mode.

Another question just out of curiosity. Will there be some point when Angular wont have a JIT mode anymore? My understanding of Ivy was that there is no need for JIT, since Ivy is always compiled ahead-of-time. I assume VE will be deprecated in one of the next releases (12? 13?).

VE has been deprecated since version 9. Ivy does work and support JIT mode and there are a number use cases where you'd need to use the JIT compiler such as dynamic components. In many cases you don't need JIT during development because Ivy AOT incremental compilations times are similar to JIT. If support for JIT will ever go away is a bigger discussion which we didn't have yet.

angular-automatic-lock-bot[bot] commented 4 years ago

This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.