-
Notifications
You must be signed in to change notification settings - Fork 5
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
post: angular elements #241
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Do you know the reason why they decided to push that?
but there is a bit of "plumbing" to do (you have to write an ES6 class with a constructor that follows some rules, | ||
then observe the attributes that can change, then implement the correct lifecycle methods defined in the specification). | ||
|
||
That why Angular 5 introduces `@angular/elements`! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is why
// listen to the custom event | ||
ponyComponent.addEventListener('selected', event => console.log('selected!', event)); | ||
|
||
You can even create new component and insert them, they will be automatically upgraded to custom element (and the inner PonyComponent will be instantiated)! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new components
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to custom elements
_posts/2017-10-24-angular-cli-1.5.md
Outdated
## Support for Angular 5 and its new compiler, AoT by default! | ||
|
||
This is probably the biggest feature of this release! | ||
As Angular 5 ships with an improved compiler (check out our article about that if you missed it), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to have a link to the article here. (link)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review :) You're right, the link to our other (unpublished) article is needed here. It's pretty much ready, we are just waiting for the official release!
Angular Elements are classic components packaged as Custom Elements. | ||
|
||
When you package an Angular Component as an Angular Element, | ||
you can the use it like a standard Custom Element. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can then use like
3851ea0
to
633df78
Compare
setTimeout(() => ponyComponent.ponyName = 'Pinkie Pie', 3000); | ||
|
||
// listen to the custom event | ||
ponyComponent.addEventListener('selected', event => console.log('selected!', event)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might not want to go into that much detail here, but event
will be a CustomEvent, which means that the emitted value will be on event.detail
. This is typical for Custom Elements.
(BTW, I've put the source code from the PR into this stackblitz project if you want to have a play.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thxs for the review @gkalpak (I hope the rest of the post is accurate enough!).
I'll update the example to include event.detail
. I have my own project (building your PR from source) but I'll add a link to your Stackblitz project in the post if you don't mind, so the readers will be able to play with it 👍 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, no problem. Hm...actually, it is better to use this link (which I will not modify further).
Or you can use that link, which looks a little prettier (using @angular/material
components as custom elements 😃).
The rest of the post looks accurate enough 👍 (given the volatile state of the @angular/elements
atm 😃). The API is definitely going to change (in subtle but breaking ways 😁). One thing you might want to mention is that you need to include custom-element-specific polyfills on all browsers (for different reasons).
(BTW, I don't think this will land for 5.0.0.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 No worries, I'm reviewing your PR regularly and I'll update the blog post.
Regarding the polyfill needed, I noticed that I had to use native-shim
. Is it the one you're talking about? I was hoping that setting the compilation target to ES2015 would be enough as I was using a class for my component, but that's because of Angular code right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm reviewing your PR regularly and I'll update the blog post
I mean even after the PR lands. There will be follow-up PRs. The plan is to merge the original PR and iterate (but probably after 5.0.0).
But you are apparently doing a great job keeping an eye on us (which is awesome btw), so I am sure you will find out the moment it happens 😁
WRT to polyfills, it depends on your browser's needs. My preliminary findings:
- IE9-10 require a
MutationObserver
polyfill and anObject.setPrototypeOf
polyfill (but one that can cope with getter/setter descriptors). - Browsers without native
customElements
support (e.g. Edge, Firefox, IE9-11, Safari) require @webcomponents/custom-elements/custom-elements.min.js.
(There are some issues on Safari 7-9 which I haven't solved yet, so they might need more polyfills.) - Browsers with native
customElements
support (e.g. Chrome, Opera) require @webcomponents/custom-elements/src/native-shim.js, which (as you said) is for allowing ES5 functions to be used as custom elements. (According to the spec, only ES2015 class can be used.)
Theoretically, you should not require that if compiling to ES2015 and using the ES2015 Angular sources (which are published as well). But I haven't tried that yet.
(I have included the polyfills I used for running the PR tests at the bottom of this file.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't happen 😕
When I build my PR locally, I can see that the es2015 sources (dist/packages-dist/elements/esm2015/elements.js
) look correct. I.e. I see the following:
class NgElementImpl extends HTMLElement {
...
constructor() {
super();
...
}
createNgElementConstructor(...) {
...
class NgElementConstructorImpl extends NgElementImpl {
constructor() {
super(...);
...
}
Based on your error, it seems that you are using the non-es2015 sources.
Do you have a repo where I can reproduce the error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simple repro here
It is using my own build snapshots, but they are based on your last commit. When running yarn package & http-server
you can see the error. It looks like my build does not use the esm2015 sources, I'm probably just missing a setting somewhere...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, your demo helped me find out that package.json#es2015
was misconfigured for @angular/elements
(it contained esm15
instead of esm2015
). I fixed that on the PR. 😄
With that fixed, you need to make sure the es2015 (not the es5) sources are used in the bundle. I didn't look into if/how you can do it with webpack, but I know @angular/cli
knows how to do it, so here is a demo that shows @angular/elements
working without native-shim
(yarn && yarn start
).
I added a small postinstall
script that fixes up @angular/elements/package.json
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you wanted to do it without the cli, you need to either load directly from @angular/elements/esm2015/elements
or configure webpack to take package.json#es2015
into account when resolving a package. Here is how the cli configures webpack, for example.
See here for more info on what the conventions are for supporting different formats.
Shout out to @filipesilva for providing all the info 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gkalpak That indeed works with the proper Webpack config and using your fixed PR. Happy that it helped to catch this bug!
I'll update the article to include a few things about the polyfills.
@jnizet @clacote I updated the Angular Elements article with the correct code from v6 (see https://github.com/cexbrayat/ng-elements/commit/ce175b4b738c40dc12b90fb4b612a634c88e2294 for the demo repo that I use). I plan to publish the article shortly after the v6 release (first the article about ng v6, then cli v6, then this one). |
94d1741
to
77e95ba
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor suggestions
_posts/2017-10-24-angular-cli-1.5.md
Outdated
@@ -0,0 +1,129 @@ | |||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This post/file needs to be removed
layout: post | ||
title: Angular Elements | ||
author: cexbrayat | ||
tags: ["Angular 2", "Angular", "Angular 4", "Angular 5", "Angular 6", "Angular CLI"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe that should be reordered (order is preserved at display time: "Angular 6", "Angular 5"...) and maybe add "Web Components" and/or "Custom Elements"
|
||
I deep dived into the [official specification](https://w3c.github.io/webcomponents/spec/custom/) | ||
to learn a bit more about the details of Custom Elements. | ||
You can of course build your own Custom Elements with vanilla JavaScript |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
your own Custom Elements -> your own Custom Element (singular)
so I would not recommend using it in production yet. | ||
But this time will come! | ||
|
||
Check out our [ebook](https://books.ninja-squad.com/angular), [online training (Pro Pack)](https://angular-exercises.ninja-squad.com/) and [training](http://ninja-squad.com/training/angular) if you want to learn more! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://ninja-squad.com -> https://ninja-squad.com (https
)
12c15ca
to
96b59c4
Compare
|
||
Sometimes you don't want a full Angular app. Sometimes you just want to build a widget. | ||
Or maybe you have several teams, some using React, Vue and others Angular. | ||
Right now it's not really easy to share just one Angular component, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to share -> to integrate
// get the ES6 class | ||
const PonyElement = createCustomElement(PonyComponent, { injector }); | ||
// use it to register the custom element | ||
customElements.define('ns-pony', PonyElement); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is customElements here? A standard function provided by the browser on window (apparently yes). So I would make that clear by using window.customElements
Fixed: ready to merge and publish tomorrow morning |
This is just in case the PR angular/angular#19469 lands in ng 5 just before the release.
(the Angular team has been working on it the whole weekend, so that may be the goal).
The plan is then to release this post at the same time as the one on ng 5 and link them.
If angular elements lands later, we'll release it separately.
Feedback is welcome if you have time to review (in case we have to release it with ng 5).
This is on top of #238 , review only the last commit