In my react projects I have been using ES6 modules for some time. In my react component I would use import:
import {f1,f2} from "./myLib";
In my polymer component I use a script tag:
<script src="./myLib.js"></script>
If I'm not mistaken, these are doing two totally different things. The script tag is polluting my global namespace for the whole app. The import isn't.
Question #1: Am I correct in my understanding of this?
Question #2: Is there a way to get something similar in polymer?
I have dozens of different polymer components. Some import conflicting libraries. Then, if I have a page that uses multiple components it seems like a crap shoot as to which version of the JS script I will get.
It is certainly possible to use ES6 modules with Polymer. First thing you will have to do is split the template and script. You can then go both ways
Add a script tag containing transpiled ES6 code to the element's html:
<dom-module id="my-elem"></dom-module>
<script src="my-elem.js"></script>
Use some kind of plugin to import HTML from ES6 code. This is, for example, possible with this plugin for SystemJS
import './my-elem.html!';
class MyElem extends HTMLElement {}
document.registerElement('my-elem', MyElem);
Then the difficult part is then transpiling. I'm not sure about other module loaders, but with JSPM+SystemJS it is easy to bundle as an Universal module. This way your element will be usable both by <link rel="import" href="bower_components/my-elem/my-elem.html"> and for importing from other ES6 code. In the former case any dependencies not bundled will have to live in the global scope. You could, however, place any such dependencies in your main html file. Just like many other elements are published.
If you're willing to give JSPM+SystemJS a try, please have a look at a blog post on my blog. I'm using TypeScript but for ES6 the general solution should be roughly the same.
Related
Is there a way I can make Polymer WebComponents and LitElements coexist?
It should be doable in theory, but afaik you cannot import html in LitElements, so it is actually infeasible.
This issue try to address the problem https://github.com/Polymer/lit-element/issues/48
Is there a way to use importHref in LitElement?
You cannot import HTML into anything but another Polymer 2/HTML element. If you are dealing with Polymer 2 elements from Google--paper-input, iron-dropdown, etc.--use npm to install their Polymer 3.0 version. If your HTML elements are from another source, you will have to rewrite them. I was able to use polymer-modulizer to convert some simple elements to JavaScript, but it was not up to a more complex element (15 components and 5 mix-ins). (Even those that did convert I ended up rewriting to LitElement.)
What exactly is HTML Modules? I understand that it might allow a developer to create HTML as a module like how ES6 Modules are to JavaScript.
But, are these modules basically templates like Mustache, Handlebars and Pug? Or is it like a wrapper around a similar templating system that will allow us to import an HTML file easily into another HTML file?
Will it pave a way to avoid using templating libraries utilizing the Web Components?
[Update]
Here is the link to where I found this - https://github.com/w3c/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md
HTML Modules are the new proposal for importing HTML files into a document.
HTML import supported a similar feature and permitted to import an HTML file (eventually containing itself JS and CSS) but it has been deprecated and JS module import has partially substituted that feature.
The point of HTML imports are to complete that part and make possible to import HTML files again instead of JavaScript files only.
Today you just can't import files that contain HTML (again, you could do that when meta rel=import href=myfile.html> which is not supported anymore).
If you want to do that, you have to write HTML in JavaScript string prior to process it.
The proposal also introduces notions such as import.meta.document that refer to the internal document to be imported.
Note that is it a proposal, even though it could be inserted into the spec, it should then be implemented by browsers, and finally adopted by the community in order to remain and become a stable feature.
Currently the closest you can use is the Lego Web-Component library that allows to include HTML as a module and extends native HTML functionality:
<template>
<p>Hello World!</p>
</template>
Used as:
<script src="./dist/index.js" type="module"></script>
<hello-world />
Example taken from https://github.com/polight/lego#hello-world
Let's see how the spec is going to evolve for HTML Modules in the futureā¦
Is there a way to define Polymer web components directly in the HTML file for the page where they're used instead of importing them through link tags?
This seems like it would be faster vs having to request a page and then send requests for the web component html files as well. So far all the guides I've seen only reference importing via <link rel="import" href="/my_component.html" />.
You can use Polymer Bundler to reduce the number of network requests concatenating web components and dependencies in one file. You can find more info here.
As suggested in the other answer, it seems like a better approach to worry more about having a clear structure of your files/elements while you're developing, and to let a build script worry about stuff like that.
But since a bundler would basically do the same thing, define all the elements in a file, it's obviously possible. So only to answer the initial question, you can see a sample here.
So you just have to use multiple dom-module tags like:
<dom-module id="my-element">
...
</dom-module>
<dom-module id="my-inner-element">
...
</dom-module>
And multiple calls to customElements.define:
customElements.define(MyElement.is, MyElement);
customElements.define(MyInnerElement.is, MyInnerElement);
But I would most certainly recommend against writing your entire application in a single file.
I'm using Polymer components with ClojureScript + Reframe (actually, at the moment, I have just one Polymer component working). My component is mostly stateless (a drawing tool for Dicom images), so it plays nicely with Reframe. I use HTML + callbacks to communicate with it. It works nicely, but I'm not using ClojureScript advanced compilation. I haven't used advanced compilation before and have some questions about its use:
As I understand, Polymer isn't compatible with Google Closure. Is that still the case?
If I'm using just HTML/callbacks to talk to the component, do I still have problems with name mangling? I suppose that I am safe with the HTML part, but am I going to have problems with the callbacks? Such as [component-x {... :on-mouse-down (dispatch-canvas-event editor-id)}]
What happens to the javascript portion of the WebComponent during compilation? Does it get changed, even if I don't call any function directly (just HTML/callbacks)?
If I do have to call a function in a component, any examples of how to write an Extern file for a Polymer component?
I'm getting into Polymer and i like the deps resolution approach using imports.
And i like the extending capability through the behaviors config.
However, there's something that doesn't feel comfortable to me, about behaviors in particular.
Looking at the PolymerElements code i see that behaviors, are defined inside their own html in the global object Polymer and then referenced directly when imported by another component..
For example:
paper-button imports paper-button-behavior
https://github.com/PolymerElements/paper-button/blob/master/paper-button.html#L14
it then defines paper-button-behavior as behavior referencing from global Polymer.PaperButtonBehavior
https://github.com/PolymerElements/paper-button/blob/master/paper-button.html#L144
wich is defined here (the imported html)
https://github.com/PolymerElements/paper-behaviors/blob/master/paper-button-behavior.html#L49
Ain't it an anti-pattern, especially as typically an app will not use Polymer's world exclusively?