-
Notifications
You must be signed in to change notification settings - Fork 923
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
[lit] Static build for CDN distribution #2272
Comments
The idea we discussed was to build a fairly reasonable set of bundles for LitElement and lit-html, and publish them to npm under |
thoughts on using https://github.com/pikapkg/web instead of a CDN? |
To clarify, this isn't for local installations via the npm registry, and we won't be changing the This is simply a way for us to distribute fairly well optimized bundles to CDNs that host npm files so that people can use them easily. We're a bit unusual in that we only publish plain ES2017 modules. Most packages right now still publish minified bundles in a variety of module formats. Our current approach is more optimal for local development, but gives a bad impression for people directly loading files from a npm CDN.
|
Is this in progress now? |
Regarding pikapkg, the CDN launched today which serves a minified bundle at |
Ugh... that looks like it bundles lit-html, so if you import lit-html separately to use directives, it won't work. |
that pika cdn bundling feature looks super cool!
i think i'm missing something here — i thought the pika bundle is exactly what people have been asking for? please bear with me as i think aloud here, i'll try to express why this is confusing to me what's the point in providing a lit-element bundle when it doesn't include lit-html in the bundle?
also, as soon as there is talk about importing lit-html separately, like in a peer dependency situation — i think that invalidates the convenience bundle use-case — because the user is now responsible to mediate how lit-html is shared in the application amongst multiple libraries, the user should be controlling bare specifier resolution with their own bundler, or with import maps; they have now outgrown the capabilities of a convenience bundle maybe my assumptions are wrong here — maybe avoidance of the bare specifier step is not considered important for lit-element's ease-of-use in this case? so users are still expected to implement bare specifier resolution themselves via bundling or es-module-shims in order to get started using these lit-element bundles? perhaps then it's really about the minification and consolidation of http-requests.. however if they're forced to using a bundler to use these bundles, isn't that minification and consolidation redundant, and already in the user's wheelhouse? do the bundles reference each other with bare specifiers that need to be resolved? are the bundles intended to be imported directly (grab-and-go, no bare specifiers), or with a resolution step? i was expecting the goal would have been a bundle that looks just like the one that pika provides — however i understand there's a peer dependency problem with the way pika bundles those sub dependencies — but isn't the correct solution for that, to move on from the convenience bundle and use the es modules and bare specifier resolution by configuring import maps or your own bundler? perhaps pika cdn covers the "avoiding bare specifier resolution" use-case? and maybe the lit-element bundles proposed in this thread are for a different use-case? i'd like to understand what this use-case is all about ultimately, in an ideal world, it makes sense to me that packages like lit-element would continue to only expose es modules, and all of these bundling, minification, and optimization concerns, would be left to dedicated tools like bundlers and cdn's like this new pika thing please inform me! cheers friends! 👋 |
Came back to LitElement hoping this was possible now. Darn.
If I really need to I can also go all the way and set up and configure a build pipeline to use an installed/imported version of Hyper, but it's not required. I love this "old-school" way...other modern libs like Moment, Vue, Riot, and more offer this option so anybody can start trying the lib in like less than 60 seconds. It's awesome! |
@jfbrennan <body>
<my-foo></my-foo>
<script type="module">
import {LitElement, html} from 'https://unpkg.com/lit-element?module';
class MyFoo extends LitElement {
render() {
return html`<div>You're doing it Peter!!!!</div>`;
}
}
customElements.define('my-foo', MyFoo);
</script>
</body> |
Hi, can I know the reason behind the choice of imposing a transformation step (with Polymer CLI) just to import LitElement? I'm genuinely curious. |
@antonioaltamura -- you don't need a transformation step for lit-element -- that's what's great about tagged-template literals instead of jsx justin's post above demonstrates usage of lit-element in plain html without any build step 👍 |
Nop, a remote request is not an option for me. Can I do the same with the local LitElement package? |
Pretty bummed this isn't sorted yet. Full-rollup packages for lit-html and lit-element seem like they'd be pretty straightforward from the build perspective. Yes, larger, but is that so problematic? |
you certainly can serve from your local node_modules -- maybe use 👋 chase |
yes, distributing bundles in modern esm packages is problematic -- here's why
one last thought: yeah, some people think that they want a bundle, and some people think they want common-js; i'll even bet somebody thinks they want window globals too -- so let's just leave those people behind! -- after all, they've got pika and other solutions to handle their confusion and/or legacy needs 👋 chase |
pika/unpkg and es-module-shims are definitely workable workarounds. But that's all they are when you don't/can't use a bundle for whatever reason. You'd think a framework should at the very least support a simple use case where folks can use it out of the box without a bundler or extra workarounds! For me in a corporate environment, we cannot even hit the external URLs for pika and unpkg. I can experiment find with it in our POC environment where we have access. I absolutely do not want to use a bundle just for this because we don't use it today for other web apps we build internally - yes we've managed to avoid an extra level of complexity - K.I.S.S. But this framework... just to even get started I have to bite the bundler bullet or do the workaround dance, pretty silly. |
@stevenpeh please note that you can now use Snowpack: https://www.snowpack.dev/#litelement It's solving the problem of need for a bundler by processing files on install via Rollup. |
Glad to see that Snowpack provides a solution, but unfortunately, it doesn't seem to solve the use case of the initial issue as it still requires you to set up an npm / yarn environment and install. This is a weird problem as it will have to require the CDN to know what packages are being used and resolve the dep tree as there can only be one version of We did something similar back in the day for webcomponents.org where you essentially provide it with a package.json (or bower) and it'll create a static link for the bundles. Though I don't believe it had the niceties of minification etc. Edit: I'm dumb and missed the comment above Serhii's |
Thanks, I'll give it a try. The previous pika example was a bit confusing, it seem more like a CDN reference similar to unpkg rather than providing a localized, remote dependency free and bundler free option. I'll test out snowpack. That said. The official docs should provide a recommended way to do this, even if it means using external tools like snowpack. A good framework should always provide a means of it with as little dependency as possible. In this case the minimal dependency would be a one off initial setup time dependency, better than runtime dependency (CDNs) or per build dependency (bundlers). Ultimately, the roadmap should aim at "none". None as in no extra tooling setup - the framework is self-contained with whatever dependency it needs in a localized manner. |
Ok I can get this working using snowpack to do a one off processing of my project folder to convert node_modules to web_modules. However as mentioned ideally the framework should provide a way to consume without all these workaround where a bundler like Webpack isn't use. In fact I looked around and found the another WC framework, Slim.js, allows just that. In fact they provide 2 ways to do it without external tools like snowpack if I don't want to use bundlers. They provide an explicit "no_modules" version I can import as plain script imports or if I want to use es6 modules can I also import they regular js as script modules explicitly in my index.html |
How do you see this working for components which are published and reusable? How should they declare dependency on lit-element or lit-html? Should they also ship a build that can be loaded with a script tag, duplicating lit-html + lit-element for each component? You could somewhat solve this for just lit-html or lit-element, but as an ecosystem of cross-dependent packages this isn't possible. Es modules are implemented in all browsers, they are the best way to share and ship code. Because the node_modules folder is in a different directory in your repository and when installed in another project, you can't set explicit paths to the module folder for importing dependencies. So you need to use something like bare imports for now. |
Yeah, we have a scenario where one of our packages has a peer dependency on lit-html. This is fine for when people are using a modern build toolchain with our package. But we also provide a UMD bundle for the package, and because lit-html provides no UMD, bundle option, this provides no end of troubles. Is the only solution to ingest lit-html into the umd bundle?? Publish an alternate lit-html that does provide a UMD bundle? |
@gmurray81 If you provide a non-module bundle, you should probably include everything needed in the bundle. lit-html doesn't seem right for a peer dependency either. |
Wouldn't issues arise if there were multiple nested distinct versions of lit-html? |
Hello, chiming in with my use case. Hope it helps. I am not using npm or node locally, so I can't use webpack or any other js bundling system. I am actually developing a (bunch of) Go website, and wanted to serve some web components to be used on the pages, without having a full SPA. Using Using None of them seems ideal. Having a single 70 Kb bundle to download would probably take less than 200 ms. |
Related: See: microsoft/TypeScript#29854 Edit:
|
i made this simple <demo-counter> codepen demo featuring import maps via es-module-shims (~50 lines) and yes, a bundle would load faster than using import maps, however, keep in mind: bundles are properly optimized at the application-level, not at the level of libraries like lit-element. if you want refined performance, your application should run a bundler like rollup, webpack, or snowpack as a part of the build routine |
I built lit-element bundled with lit-html. It doesn't require node and supports both iife and ES module. It's suitable for non-node js environment usage. |
@webfolderio Those are pretty large bundles (100KB plus)... Not very practical for production. Gonna chip in with my use case: I'm building a blog with Hugo and I'm using lit-element to embed dynamic content in my markdown. Right now I'm using Rollup to bundle everything but it honestly feels very overkill for what is essentially a static website. It adds another build step and I have to run the Rollup watcher in another terminal tab, set up different bundles for each page, etc... What I'd like to see is a small, minified ESM distribution I can download myself (could be a zip file for all I care) and use without any special tooling. Not a single 50KB+ file, nor a thousand little 100B files, but something in between, where files can be loaded as needed. Keep up the good work! |
following up to my previous comment I've been working through a solution to provide own static modules, including Lit, without using npm directly; transforming modules to use as static resources and provide for installation using git in mixed projects where the module provided is expected to work with npm; this is specific to how I consume Lit related dependencies, this issue and the user story mentioned here; the script to import, as part of an evolving idea to solve for the given user-story, essentially copies the modules from unpkg and saves locally: the transformed dependencies dumped into a repo for checkout (including Lit): an npm based sample project for testing this scenario and solution: an npm managed dependency which installs the above wildtype modules: I was expecting consuming projects to have their own process which would optimize for their development and release scenarios. |
Hi all, I've been working on generating bundled versions of Lit recently. Our last release (v2.2.0) started uploading these bundles and lit/lit.dev#673 adds a short section to the getting started docs about how to get and use them - the current preview of the new docs section is here. It would be great to get your feedback! |
The bundles are up and a short docs section about using them is now available at https://lit.dev/docs/getting-started/#use-bundles. |
Hi @bicknellr, are there any plans for a static build of |
Unfortunately..the documentation there was little help as I included those bundles as modules and still received the error this thread discusses. after going through this thread, someone posted this, that worked for me. import {LitElement, html} from "https://cdn.pika.dev/lit-element/^2.2.1" it is still unclear to me what the right approach for directly linking the bundles is...but atleast i can put the last 2 hours searching for a solution behind me and go on to learning lit. I can say this..it seems the vue folks have figured this out by using importmap. not sure why its so hard here. |
@MSingh00, could you describe the error you're seeing in more detail and/or provide a repro? |
I was having this issue: lit/lit-element#76. |
You should use the bundle URL instead of So this: <script type="module" src="https://cdn.jsdelivr.net/gh/lit/dist@2/all/lit-all.min.js"></script>
<script type="module">
import {LitElement, html} from 'lit';
</script> Becomes this: <script type="module">
import {LitElement, html} from 'https://cdn.jsdelivr.net/gh/lit/dist@2/all/lit-all.min.js';
</script> |
Thanks. i will use that bundle instead of the one i found earlier in this thread. thanks again |
I think the docs are open source, so maybe a quick PR to add that snippet? As I agree, I think that would be a really helpful addition since I wouldn't be surprised if others didn't get that nuance. 👌 |
Very helpful! FYI this is now 'https://unpkg.com/lit?module' |
Agreed. |
@thescientist13 thanks for the nudge. Submitted a PR here, which just got approved. |
Since you mentioned import maps earlier... Other than the bare module specifiers (i.e. what import maps intend to enable), Lit's npm packages are completely standard JS, so you can actually use import maps to run them directly from from those so long as you know enough about the dependency graph and where to get those things to be able to write it, or use a tool to write it for you. (It looks like Of course, this only works in browsers that support import maps1, so shipping this isn't viable yet. (Hopefully not for long!) I haven't indicated any versions in the unpkg URLs here, so this particular import map relies on all of the latest versions of these packages being a valid combination, which just happens to work because we typically release everything simultaneously (not a guarantee). <!DOCTYPE html>
<script type="importmap">
{
"imports": {
"lit": "https://unpkg.com/lit/index.js",
"lit/": "https://unpkg.com/lit/",
"@lit/reactive-element": "https://unpkg.com/@lit/reactive-element/reactive-element.js",
"@lit/reactive-element/": "https://unpkg.com/@lit/reactive-element/",
"lit-element": "https://unpkg.com/lit-element/index.js",
"lit-element/": "https://unpkg.com/lit-element/",
"lit-html": "https://unpkg.com/lit-html/lit-html.js",
"lit-html/": "https://unpkg.com/lit-html/"
}
}
</script>
<script type="module">
import {LitElement, html} from 'lit';
class CounterElement extends LitElement {
static properties = {
clickCount: {
type: Number,
state: true,
},
};
constructor() {
super();
this.clickCount = 0;
}
render() {
return html`
<button @click="${() => this.clickCount++}">
This button has been clicked ${this.clickCount} times.
</button>
`;
};
}
customElements.define('counter-element', CounterElement);
</script>
<counter-element></counter-element> Footnotes
|
re: import maps, can definitely recommend https://github.com/guybedford/es-module-shims. Have been using it in my project Greenwood to facilitate unbundled local development and it has been working quite well; with Lit too. 🌟 |
you might like to check out importly, my import map generator for npm projects. you can find a list of similar tools here in the wicg import maps readme. as others have mentioned, es-module-shims is top-tier ❤️ |
what about this? No matter what I try, I cannot seem to import the decorators. Are they not part of the bundle? is there another bundle? why? |
The documentation for decorators calls out that they only work with TypeScript or when using a bundler, and to use the alternatives for pure JS solutions where a bundler isn't involved. I'm sure that'll change now that decorators are Stage 3 in TC39 and once browsers ship an implementation. So yes the out-of-the-box bundle, to be used client-side without any build tooling, is only supporting JavaScript. And as vanilla JS as possible so they don't fork standards, I'd imagine. |
I am using Typescript, and the decorators are working, without a bundler, loading the Lit modules from I suppose mine is an edge case unforeseen by the bundle distributors, but it is nonetheless a valid case, which as I said has been working using a different CDN. There is more than one way to use Typescript, and not all involve using |
If you had this working with unpkg and want to use a different CDN, any CDN that acts as a sort of proxy to npm would work. jsdelivr can do that, too: https://cdn.jsdelivr.net/npm/lit/index.js You just can't use their kitchen sink bundle. I'd expect the importmap to look very similar to what you had for unpkg. |
In fact it worked first try with simply substituting the server and path you provided.
The somewhat confusing @("@") syntax is to escape the @ signs as this lives in an ASP Razor template. I have only one Lit Component so far and this is how its imports read using the sourcemap
Thank you @p-ob for your help in steering me in the right direction as well as understanding more about how this all works. |
I have been scratching my head for so long on this. I really think I stumbled on this project again seeing someone mention that this doesn't require any bundling but it just feels so complicated to use. A simple example would have solved this. Would be happy to help get it done, if someone can guide me on how to get |
crude example: |
Thanks, but roughly during the week that I wrote that comment I discovered Petite Vue and I have to say I fell in love! Don't think any other web framework will make me turn away from this one. Have been looking for this DX for over 2 decades. Its super elegant to build components and reuse them without any bundling whatsoever. Hate that I don't have a proper page setup to demo this but I promise I will come back once its ready. Have been tied with work for some months now. |
Per a F2F conversation with @justinfagnani, wanted to capture agreement to add a single, modern-browser-exclusive build of LitElement and the most frequently used lit-html directives to the distributed NPM module. The goal is to enable easy inclusion of LitElement from a single source file.
Rationale
LitElement, when built, is tiny! That isn't apparent when using it from, e.g., unpkg. The need for the Polymer CLI tools also increases the friction to getting started with the edit/compile cycle that historically makes web development so much fun.
Instead of trying to boil the whole ocean by providing every build variant, or having to compromise on size to accomodate legacy, the idea here is to get developers started quickly while providing an easier path to "real" LitElement usage via local builds.
Part of this approach might need to add guards to the build to give up when loaded in the presence of existing LitElement (to prevent over-inclusion) and console logging to flag that this isn't the most efficient approach.
The text was updated successfully, but these errors were encountered: