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

Angular -> generating Web Components #20859

Closed
playerx opened this issue Dec 7, 2017 · 19 comments
Closed

Angular -> generating Web Components #20859

playerx opened this issue Dec 7, 2017 · 19 comments

Comments

@playerx
Copy link

playerx commented Dec 7, 2017

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

none

Expected behavior

Create web components using angular

What is the motivation / use case for changing the behavior?

I think it would be cool if angular will give us ability to generate web components, I was researching and found angular elements project but it's archived: https://github.com/robwormald/angular-elements.

Main goal is to generated web components, that will wrap angular component and will be hosted & accessible independently.

What's your plan about that?

@playerx playerx changed the title Angular & Web Components Angular -> generating Web Components Dec 7, 2017
@Toxicable
Copy link

Angular Elements is our plan, it's currently in progress
https://github.com/angular/angular/tree/labs/elements

@playerx
Copy link
Author

playerx commented Dec 7, 2017

Thats just awesome, I've found the video also:
https://www.youtube.com/watch?v=ljsOPm4MMEo

Do you have some sample project (source code) how to use it? I would love to try it.

@gkalpak
Copy link
Member

gkalpak commented Dec 7, 2017

Nothing official atm I'm afraid. There are still some things to work out (e.g. packaging). And docs are also coming.
(You can get an idea of how to use it from this stackblitz project, where I have put the code from the labs/elements branch into the @angular/elements directory).

The tl;dr instructions to use it are:

import {NgModule} from '@angular/core';

// Create some component as usual. (Note: `ContentChild[ren]` are not supported.)
import {MyFunkyComponent} from './my-funky.component';

// Define a list of components that you want to use as Custom Elements. (We'll use this later.)
export const ceComponents = [MyFunkyComponent];

// Create a module (almost) as usual.
@NgModule({
  ...
  providers: [...],
  declarations: [
    ...,  // Other non-CE components can go here
    ...ceComponents,
  ],

  // Differences from what you usually do:
  // - No `bootstrap` components.
  // - Define as `entryComponents` all components that you want to use as Custom Elements.
  entryComponents: ceComponents,  
})
export class MyFunkyModule {}
// Then somewhere in your non-Angular app:
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {registerAsCustomElements} from '@angular/elements';
import {ceComponents, MyFunkyModule} from './my-funky.module';

const bootstrapFn = () => platformBrowserDynamic().bootstrapModule(MyFunkyModule);
registerAsCustomElements(ceComponents, bootstrapFn).
  then(moduleRef => /* Custom Elements are ready. Do your thing... */);

Note, that depending on the browser you will need a different set of polyfills for Custom Elements.
Chrome (/Opera) have the best support atm, and for them you need @webcomponents/custom-elements/src/native-shim if you want to be able to transpile ES2015 classes to ES5 functons (because this is not compatible with Custom Elements according to the spec).
(If you re willing to use ES2015 sources and configure your build process to do so, then you don't need an extra polyfill on Chrome/Opera.)

@gkalpak
Copy link
Member

gkalpak commented Dec 7, 2017

If you are interested in using ES2015 sources, there is some info in this discussion (including some working projects you can checkout).

@playerx
Copy link
Author

playerx commented Dec 7, 2017

Thanks a lot!

@gkalpak
Copy link
Member

gkalpak commented Dec 7, 2017

I am going to close this issue now, since it is not actionable in its current state. Feel free to fiddle around with labs/elements and make sure you send any feedback or issues our way ❤️

@gkalpak gkalpak closed this as completed Dec 7, 2017
@playerx
Copy link
Author

playerx commented Dec 8, 2017

I've created demo project using latest angular cli:
https://github.com/playerx/angular-elements-sample

I think more people will be interested in this topic and hope it will be useful for them.

P.S. It's really simple :)

@playerx
Copy link
Author

playerx commented Dec 10, 2017

I've created little bit more complex scenarios and results are really impressive:

creating web components (source code)
using web components (source code)

@gkalpak
I've found one issue, if I'm hosting angular element in another angular element, in the same project, it's rendered two times:
screen shot 2017-12-10 at 13 24 34
screen shot 2017-12-10 at 13 25 28
but when I'm using those components in another project it renders correctly once.
I think angular renders it as angular component and after that it's rendered as web component also.

@gkalpak
Copy link
Member

gkalpak commented Dec 11, 2017

Thx for the feedback, @playerx! That really helps us 👍
The double-compilation is a known issue. We are still investigating the best solution (one that does not impose any extra overhead on pure-Angular apps and has minimal overhead for ngElements apps.

@studioTeaTwo
Copy link

I feel @angular/elements is so cool!

I want to create a custom tag which is extends HTMLElement and publish to use in <script src="fancy-button.js"></script>.

Just like Rob's demo

How do I develop it by @angular/elements?

@gkalpak
Copy link
Member

gkalpak commented Dec 12, 2017

As mentioned above, there are still some rough edges and packaging is an open issue. In a nutshell, you would need to bundle your Angular app (including Angular itself and any 3rd-party libs) and run registerAsCustomElements(...) in your main.ts file. See @playerx's demo for an example.

@studioTeaTwo
Copy link

@gkalpak Thank you for quick reply ! And I see.

I have one more question.

registerAsCustomElements(...) has two functions.

export function registerAsCustomElements<T>(
    customElementComponents: Type<any>[], platformRef: PlatformRef,
    moduleFactory: NgModuleFactory<T>): Promise<NgModuleRef<T>>;
export function registerAsCustomElements<T>(
    customElementComponents: Type<any>[],
    bootstrapFn: () => Promise<NgModuleRef<T>>): Promise<NgModuleRef<T>>;

How should we use each two funcitons differently?

@gogakoreli
Copy link

gogakoreli commented Dec 13, 2017

@gkalpak
What about performance? If every component has Angular inside, is it too much overhead? I am asking, because if every web component comes with its own Angular runtime I think it will hit the performance and make app very slow as the number of components increase.

@playerx
Copy link
Author

playerx commented Dec 13, 2017

@gogakoreli not every component has angular inside, angular runtime will be per project you create and in project you can have multiple web components. If you will create projects for each component it will have overhead I think.

It will be interesting to make some experiments with https://nrwl.io/nx, here you will have same versions of packages and you will not need to download angular runtime per project, but I don't know how it will work in real life, yet

@gogakoreli
Copy link

Lets take we have different angular web components and they have dependency on the same versions of packages, which are angular or any third party packages. Can these components share same dependencies between them in the same app environment? I am talking about angular web components which are developed independently, located inside different projects.

@gkalpak
Copy link
Member

gkalpak commented Dec 13, 2017

@gogakoreli, we still need to figure this stuff out (and work is in progress for being able to make the components as slim as possible). As @playerx mentioned, you can have multiple components (or even NgModules with components) per project without any overhead. Things get more complicated when you want to mix different projects depending on different Angular versions 😃

Theoretically, in the simple case where you have multiple projects using the same version, you should be able to load Angular once, create a PlatformRef and share that across all components (even if they come from different projects). But (a) I haven't actually tried that and (b) there are no guidelines to achieve that (e.g. how you should package your projects, how to load Angular etc).

It is pretty much uncharted territory, but we are very eager to explore it 😃
I would just play it simple for now, until the API is ready for more complex (more real-world) usecases.

@playerx
Copy link
Author

playerx commented Jan 7, 2018

I've created a blog post about angular elements and my researches:

Angular & Web Components

Hope it will help new users to get started with Angular Elements :)

@playerx
Copy link
Author

playerx commented May 2, 2018

Interesting example, how to use Angular Elements:
https://twitter.com/beeman_nl/status/991251676224016384
👍

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants