Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve bundling experience for supporting multiple Angular Elements on a page #19164

Open
dsozzi opened this issue Mar 11, 2020 · 16 comments
Open

Improve bundling experience for supporting multiple Angular Elements on a page #19164

dsozzi opened this issue Mar 11, 2020 · 16 comments

Comments

@dsozzi
Copy link

@dsozzi dsozzi commented Mar 11, 2020

Hi,

I’d like to bring some attention back to this original post

angular/angular#23732

Where it’s stating that in previous Angular version it was not possible to run multiple Angular Elements on a single page and we had to wait for Ivy release.

Now that we are at version 9 and Ivy is enabled by default, I was wondering if there are any progress regarding this issue.

Thanks

UPDATE by @gkalpak (for visibility):

List of related issues (with useful context, info, explanations):

@predorock
Copy link

@predorock predorock commented Mar 13, 2020

+1

@dsozzi
Copy link
Author

@dsozzi dsozzi commented Mar 17, 2020

is there any news? thanks :)

@crisz
Copy link

@crisz crisz commented Mar 17, 2020

In the linked issue and in many other related issues, the advised solution was to use ngx-build-plus and many threads were flagged as "won't fix".

I think this cannot be the solution, for four reasons:

  1. This is a base feature. The concept of modularity through elements is meaningless if you can't use multiple angular applications on the same page
  2. ngx-build-plus works by disabling some optimizations in the webpack build configuration. If the Angular team would embrace the feature I think that a smarter solution may be found
  3. Despite the effort put in ngx-build-plus, it still has some limits: the bundles are still too large since, after concatenations, you end up including in each file a lot of duplicated code. Furthermore, you need to perform some operations in your HTML document in order to externalize the polyfills and include all the (and only the) required dependencies. Do I need to import the @angular/router package? And the @angular/forms? I don't know! I need to check it component by component
  4. ngx-build-plus is an independent project ran by volunteers. There's no warranty that the development will be taken forward in the future and that's safe to be used in production. As now, the latest commit has been 1 month ago and the issues that I remember open months ago, are still open now
@flash-me
Copy link

@flash-me flash-me commented Mar 18, 2020

Take a look at this issue: angular/angular#35429

I also posted a solution with pure angular toolchain which is working.

cheers
flash

@dsozzi
Copy link
Author

@dsozzi dsozzi commented Mar 18, 2020

thanks @flash-me. I'll read through all your replies and see how it goes. My intention was to ask if there was an official way to have multiple angular elements living togheter and not using some special/custom hacks. In my case I have implemented a simple script which renames the webpackJsonp variable during the building process.

@flash-me
Copy link

@flash-me flash-me commented Mar 18, 2020

Hi @dsozzi

the only "hack" is that you need to compile your angular element as a library (ng-packagr with that builder that comes with the angular-cli) instead of an application.

Instruction and implementation can be found in the repo I posted

cheers
flash

@sod
Copy link

@sod sod commented Mar 20, 2020

It's already longer possible to bootstrap multiple applications. The tricky part was, to run them all with one dependency injection container and one change detection umbrella. But wasn't that fixed with the new @Injectable({providedIn: 'platform'})? https://angular.io/api/core/Injectable

@flash-me
Copy link

@flash-me flash-me commented Mar 22, 2020

@sod I don't know how "platform" Provision is related to change detection and even the mentioned issue of this topic.

How should I profit from providing Injectables (e. g. A token or Service) at platform level when I want to bootstrap angular elements (which are wrapped angular Components)?

I don't see any relation between Change Detection, "platform" Provisioning & Components. Can you describe your intent?

cheers
flash

@flash-me
Copy link

@flash-me flash-me commented Mar 22, 2020

@sod If you want to reuse any existing Angular Platform, you get it and use it to bootstrap further applications. Like I already did it here.

But again, how is @Injectable related to this?

cheers
flash

@qkhanhpro
Copy link

@qkhanhpro qkhanhpro commented Oct 2, 2020

Should I make a comment to bring more attention to this matter?
We are trying to export all our stateless components as angular elements and seems like Angular has not really been optimized for that? Can we be confident to use this feature in production?

@flash-me
Copy link

@flash-me flash-me commented Oct 2, 2020

What kind of optimization do you expect? What do you think is missing?

cheers
flash

@qkhanhpro
Copy link

@qkhanhpro qkhanhpro commented Oct 3, 2020

What kind of optimization do you expect? What do you think is missing?

cheers
flash

Thanks for answering, flash

In our company, we have been developing multiple angular project in the recent years. 10s of them, each with some components that follow company UX UI guideline, resulting in duplicated work
Now with emerging Angular Elements, we would like to export all the components that we created in the 10 projects into reusable element for the Jquery/React world also.

I would like to know if
1/ Is It now possible to include angular elements generated from different projects?
2/ Each project would generate an Angular mini-app with its own change detector and app/module lifecycle independent of each other ( Am I right? ) - would that come with a performance penalty if heavily used?
3/ I believe that due to each element being so independent of each other, there will not likely a chance to optimize dependency. Ex:
Project 1 generate Element A that depend on module/package P1 P2 P3 P4
Project 2 generate Element B that depend on module/package P2 P3 P4 P5

Whoever use both Element A and B would suffer the bundle size of duplicated P2 P3 P4 right

// Did my question spiraled out of context considering the current issue?

@mlc-mlapis
Copy link

@mlc-mlapis mlc-mlapis commented Oct 3, 2020

@qkhanhpro The key point is to place all of such components into one placeholder application that allows you to generate only the same runtime bundle for them. So the ideal strategy is to use probably some monorepo, as Nx, for example, and if it has a sense (depends on the type of those components), use lazy loading. Their code will be loaded lazily and individually then, in a moment of their real use.

@flash-me
Copy link

@flash-me flash-me commented Oct 3, 2020

What kind of optimization do you expect? What do you think is missing?
cheers
flash

Thanks for answering, flash

In our company, we have been developing multiple angular project in the recent years. 10s of them, each with some components that follow company UX UI guideline, resulting in duplicated work
Now with emerging Angular Elements, we would like to export all the components that we created in the 10 projects into reusable element for the Jquery/React world also.

I would like to know if
1/ Is It now possible to include angular elements generated from different projects?
2/ Each project would generate an Angular mini-app with its own change detector and app/module lifecycle independent of each other ( Am I right? ) - would that come with a performance penalty if heavily used?
3/ I believe that due to each element being so independent of each other, there will not likely a chance to optimize dependency. Ex:
Project 1 generate Element A that depend on module/package P1 P2 P3 P4
Project 2 generate Element B that depend on module/package P2 P3 P4 P5

Whoever use both Element A and B would suffer the bundle size of duplicated P2 P3 P4 right

// Did my question spiraled out of context considering the current issue?

You may have a Look at this: https://github.com/flash-me/angular-micro-frontends
There I'm showing one solution on how to adapt an approach such you're looking for with angular only tools.

But in that repo I'm aiming for minimal usage of dependencies. So I even removed the cli and ng-packagr and directly use ngc + rollup. Depending on the skillset of the developers, this might be an issue regarding developer experience. If you prefer the angular cli toolchain, you can have a look on this previous commit: https://github.com/flash-me/angular-micro-frontends/tree/d2cdf8975ff29b7b9e7d9ff127a88104d09c006e

back to the questions:

  1. yes, it is. Even on runtime without reloading the page. (described in the readme)
  2. with my approach, the elements share the angular runtime and so the change detection, since they are bootstrapping using the same platform
  3. They are "optimized", as each project comes only with its own code. Thx to ng-packagr (+rollup), no external dependencies is included in the bundled. Given that, you need to provide these dependencies yourself once.

But to be honest. Such solution is not handy for the average angular developer, since a lot more knowledge is required.

Hope I could help you a little bit

cheers
flash

@flash-me
Copy link

@flash-me flash-me commented Oct 3, 2020

@qkhanhpro The key point is to place all of such components into one placeholder application that allows you to generate only the same runtime bundle for them. So the ideal strategy is to use probably some monorepo, as Nx, for example, and if it has a sense (depends on the type of those components), use lazy loading. Their code will be loaded lazily and individually then, in a moment of their real use.

This way, your projects are hard coupled to one application and everything needs to be bundled on every change. If this fits the requirements, I'd strongly recommend this way, since it's officially intended and supported.
If you need more flexibility on your projects, e. g. the final composition happens on runtime + you want to reuse them in a framework agnostic way (custom elements) you may have a look on my answer above, which allows you to develop completely independently without a big messy monorepo with hundreds of dependencies

cheers
flash

@jelbourn jelbourn changed the title Multiple angular elements on a single page Improve bundling experience for supporting multiple Angular Elements on a page Oct 21, 2020
@jelbourn jelbourn transferred this issue from angular/angular Oct 21, 2020
@jelbourn
Copy link
Member

@jelbourn jelbourn commented Oct 21, 2020

Moving this to the CLI repo since it relates to bundling. I believe this would fall under the feature request umbrella for CLI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
9 participants
You can’t perform that action at this time.