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

Suggestion: remove bare import statements #724

Closed
magic-akari opened this issue Jul 4, 2019 · 6 comments
Closed

Suggestion: remove bare import statements #724

magic-akari opened this issue Jul 4, 2019 · 6 comments

Comments

@magic-akari
Copy link

magic-akari commented Jul 4, 2019

The only one dependence in lit-element is lit-html. (Thanks for removing @polymer/polymer.)

There are three methods to use lit-element

  • use bundlers(such as webpack)
  • use unpkg query parameters(?module)
  • use import-maps

But it is painful to use lit-element as es modules without any extra specific effort.

  • I cannot import lit-element form ./node_modules as my demo project.
  • I cannot import lit-element from other CDN. They don't support to rewrite bare import statements as unpkg doing.
  • CDN rewriting will cause SRI verification to fail.
  • import-maps is perfect in the future, not now.

Maybe it is better to remove bare import statement from lit-element.

There are only two functions/classes used in lit-element which is imported from lit-html.
render function:
https://github.com/Polymer/lit-element/blob/46c8f404937672ed10587124ec3ddee82fd005fe/src/lit-element.ts#L76
TemplateResult:
https://github.com/Polymer/lit-element/blob/46c8f404937672ed10587124ec3ddee82fd005fe/src/lit-element.ts#L213

I did some try, here is my idea.

- static render = render;
+ static render: typeof render;

or

- static render = render;
+ static render: typeof render = () => {
+     throw new Error("not implemented");
+ };

When the users are going to use LitElement, they have to inject the render function themselves first.

import { render, html } from "https://some.cdn/lit-html.js";
import { LitElement } from "https://some.cdn/lit-element.js";

LitElement.render = render;

class MyElement extends LitElement {
  // some other details...
}
customElements.define("my-element", MyElement);

It's ok to create a wrapper file which imports lit-html and injects render function automatically. It will keep compatibility.

import { render } from "lit-html";
import { LitElement } from "./lit-element";

LitElement.render = render;

export { LitElement };
export { html, svg, TemplateResult, SVGTemplateResult } from "lit-html/lit-html.js";
// ...

As for TemplateResult, we may need a flag in lit-html.

- if (templateResult instanceof TemplateResult) {
+ if (templateResult.flagOrAnotherName === Symbol.for("TemplateResult")) {

It is my rough idea. There will, of course, be a lot more details when we get started for real.

Do you have any ideas?

Related issue: #140

@magic-akari
Copy link
Author

It seems that the TemplateResult will be deleted in #712 .

@chase-moskal
Copy link

@magic-akari — bare specifiers is the best practice moving forward

here are some compelling options you can use today

  • use an instant bundle from the amazing new pika cdn: https://cdn.pika.dev/lit-element
    this contains lit-html
    it's like unpkg, but for bundles!
    you can link to the bundle directly, or download it locally.
    this can be bad for peer dependency scenarios if you use more than one pika bundle (easy to load the same package redundantly multiple times)

  • use your own bundle build step
    resolves peer dependencies properly.
    highly optimal

  • use import maps today with guy bedford's fantastic es-module-shims
    i absolutely love this import maps polyfill!
    resolves peer dependencies via your import map rules 🕶️

cheers!

👋 Chase

@magic-akari
Copy link
Author

magic-akari commented Jul 5, 2019

@chase-moskal Thanks for your recommendation. Pika is awesome.
There is another problem with lit-element. lit-element import and export part of lit-html.
It will be ok to use pika if lit-element exports everything from lit-html. see https://github.com/Polymer/lit-element/issues/603#issuecomment-501528498

If you need the lit-html directives which not exported from lit-elements, you have to import lit-html and bear the burden of loading duplicate resources.
Pika bundle lit-html into lit-element and you cannot use any directives from lit-html.

@web-padawan
Copy link
Contributor

@magic-akari you can try using https://github.com/pikapkg/web if you want to avoid bundlers.

@chase-moskal
Copy link

@magic-akari

Pika bundle lit-html into lit-element and you cannot use any directives from lit-html.

ah, yes, i understand — lit-element isn't exposing everything you want from lit-html

i think the best solution for your use-case, to give you more control, would be to use es-module-shims, and configure an import map

then you can use es modules with bare specifiers, and you can configure (via import map) the browser where to fetch lit-element and lit-html (like for example, locally, or from unpkg), and so then you can import your directives from "lit-html", and lit-element will be internally using the same copy of lit-html (so you win by avoiding any duplication) — by the way, i've made this funny little tool called importly to help me generate my import maps

using your own bundler is another option, but requires a build step

also @pika/web is a really compelling option for package management as well!

@justinfagnani
Copy link
Contributor

We very consciously chose to use bare specifiers, and we could not change this at this point even if we wanted to.

We're following npm ecosystem standards by using bare specifiers. Nearly all tooling supports them, and the platform will soon too with import maps. Relative imports are not reliable in npm. In fact, many tools break with relative imports that reach out of the package.

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

No branches or pull requests

5 participants