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

why lit-html is not transpiled to es5 in npm? #516

Closed
maciejw opened this issue Sep 20, 2018 · 32 comments
Closed

why lit-html is not transpiled to es5 in npm? #516

maciejw opened this issue Sep 20, 2018 · 32 comments

Comments

@maciejw
Copy link

maciejw commented Sep 20, 2018

Can you clarify something?

when someone publishes package to npm with module and main properties, the only difference should be es6 module format, packages should be both es5 compliant.

webpack/webpack#1979 (comment)

in your case, you publish modules not transpiled to es5, you are es2017 compatible.

can you clarify, whet is proper way of consuming this package, to use it with webpack, when webpack and babel for that matter will not transpile node_module files from es* to es5.

you can program your library in whatever you like, some exotic babel plugins with experimental syntax, when you publish it to npm, you force consumer of this library to know what those plugins are and configure transpilation locally, this is quite ridicules assumption on your part if true, I think :) so I'm asking :)

@web-padawan
Copy link
Contributor

Short answer is: this is needed to use native ES modules in browser (with the small transform which consists of resolving package names to paths).

Same applies to lit-element and most of web components around Polymer community (as they use native ES2015 classes and transpiling affects them by imposing the need for additional shim).

Example babel-loader config to work with lit-html can be found here: https://github.com/web-padawan/lit-components/blob/f4f17f6267cf440dd8abdb7f4794a66cdc51330b/utils/webpack.common.js#L6

@justinfagnani I do think this should be clearly documented and explained with code examples. Not everyone will use Polymer CLI, most of people will prefer Webpack etc.

@aadamsx
Copy link

aadamsx commented Sep 20, 2018

Not everyone will use Polymer CLI, most of people will prefer Webpack etc

I don't use Polymer CLI or Webpack. I ran into this went trying to use lit-html/lit-element with Meteor. Luckly MDG was able to come up with a solution using symlinks.

@Lodin
Copy link

Lodin commented Sep 20, 2018

@maciejw Actually, you can set up your webpack to compile several packages from node_modules, just add another babel-loader instance with include option pointing to the desired directory inside the node_modules.

Regarding the need of compilation to ES5-compatible source. I would strongly disagree with the comment you provided. We've entered the era when all evergreen browsers supports ES2015 standard, so it becomes unecessary for the users of Chrome, Firefox or Edge receive unnecessary bytes of code that was transpiled just because some old browsers don't support some features. And this situation is completely hopeless for someone who don't want to support IE11 and its older versions. There is no compiler to get ES5 compiled back to ES2015 and almost all libraries in npm goes compiled. Why should my users use Babel FSM while their browsers supports async await and generators natively?

I think npm libraries should be written and distributed with ES2015 code. If any site has a need to support old browsers it can compile them by itself. Just small changes in webpack configuration. It can even create a special build for old browsers and distribute it identifying by User Agent.

It becomes more important for a library like lit-html that aims ES2015+ compliant browsers and uses standards that old browsers lacks (I mean, <template> tag). Futhermore, it is considered to be used along with WebComponents that work on top of ES2015 standard. I see lit-html as a library of a new type that is written and distributed in the same state, and only I can decide in what way I compile it for my application.

There is a great post from Henry Zhu, Babel maintainer, about moving to "post-ES5" ecosystem. I completely agree with his opinion.

@maciejw
Copy link
Author

maciejw commented Sep 21, 2018

thanks for followup on this, I know that our ecosystem is in constant flux, its is even more important to be explicit about stuff you said, so documenting it is good idea, I hope this thread will help someone.

Henry Zhu expresses same concerns that I had in mind... but also shines new light on few things, good post.

I know that its possible to setup webpack to transpile node_modules but keep in mind, that previously, when I wanted to use some library, I had to run npm i some-lib and then import it, now I have to know how to override this in my babel config. what if I cannot use babel? when I'm using typescript, some TS features are not supported by babel, babel guys say "use typescript to transpile to js" and then use babel (maybe?) and ... and ... and then things start to get hairy, when I want to setup everything, because in tsconfig I have settings regarding my project, should I then process JS files with my tsc, but some tools ignore tsconfig :) and when I have couple of files in my project, its not a big deal, but when I have large project then it compiles foreeeever because I have to transpile tens of hundreds of my files and half of my node_modules. now I have more than 60000 files in node_modules and counting, its easy to configure it when I have to configure few first level dependencies, like lit-html, you have "dependencies": {}. what If I have to configure transpilation of dependencies of my dependencies of my dependencies... this is our future if we are not careful.

I've heard cool thing that Scott Hanselman once said about consuming dotnet, when MS was working on http://dot.net core. He said something along those lines, it should be easy to consume, I want to have nice domain, users will download run-time from with easy setup and I want to type dotnet new and then dotnet run and then it should work, even kids should be able to do it easily.

JS environment has opposite approach I think :) its not a complain its and observation :)

@justinfagnani
Copy link
Collaborator

We distribute standard JS modules because we need to:

  1. Have modules load natively in current browsers
  2. Only have one canonical distribution of the library in an application (since we use instanceof)
  3. Allow compilation to whatever non-standard module format the application might choose.

Standard modules are the only format that allows all three. The only requirement on applications is that if they're using a non-standard module format, that they compile the lit-html modules to that format.

With regard to other ES5 features, we distribute ES2017 because we can't know anything about the target environment, including class, arrow function, or const/let support. Only the application developers know those constraints, so only they can configure the compiler correctly.

We only use standard ES2017, so you don't need to configure your compiler with any exotic plugins. While we do write lit-html in TypeScript, that's compiled to standard ES2017 before publishing. To go from ES2017 to whatever your target is you can use Babel, TypeScript, Closure, Bublé, or any other standards-compliant JS compiler.

@charnould
Copy link

Hi,

First, thanks for your work!
I'm looking forward 1.0 (#333) because it should featured Server-Side Rendering.

At this time (I'm a newbie, sorry if this comment doesn't make any sense), I try to consume lit-html server side running Node 10.x.x and Express. I'd like to drop Handlebars (or whatever templating engine-you-want) by Lit-html: I think it might be super powerful...

However, I'm not able to consume Lit-html because Node doesn't support yet Import/export but only CommonJS...

Am I missing something?
I'd like to not use Babel/Webpack to keep things truly simple (aka no build).
Thanks.

@web-padawan
Copy link
Contributor

web-padawan commented Nov 11, 2018

@charnould you don't really need Webpack for Node. Adding @babel/register into your code should do the job, and it's just 1 line of code. It can be also used with tools like mocha etc.

@charnould
Copy link

Thanks.
I've decided to use esm. Seems that @babel/register must not be used in production.

I can now use import/export, but still fail to use Lit server-side...
Below the error I got (running Node 10.x.x...)
Do you have any idea what's going on?

file://..../node_modules/lit-html/lib/dom.js:1
ReferenceError: window is not defined
    at Object.<anonymous> (file:///..../node_modules/lit-html/lib/dom.js:14:29)
    at Generator.next (<anonymous>)

@justinfagnani
Copy link
Collaborator

@charnould lit-html uses browser APIs that aren't available in Node. It's not going to work unless you load it in a browser emulator like jsdom.

@rbosneag
Copy link

We only use standard ES2017, so you don't need to configure your compiler with any exotic plugins. While we do write lit-html in TypeScript, that's compiled to standard ES2017 before publishing. To go from ES2017 to whatever your target is you can use Babel, TypeScript, Closure, Bublé, or any other standards-compliant JS compiler.

@justinfagnani after babelization of the ES2017 result of lit-html to ES5 in order to target older browsers/platforms, will the performance benefit of lit-html (performance that comes from diffing the data against the sparse DOM template string) be affected? Will it still be beneficial to use lit in such case?

Moreover, is it going to work as expected? Since awaits are transpiled to infinite loops but there are problems with corner cases of nested async calls, do you expect lit converted to ES5 to work as expected? Have you tested such cases?

@LarsDenBakker
Copy link
Contributor

LarsDenBakker commented Nov 19, 2018

We use lit html compiled to es5. Performance impact is the same as any other library, you end up shipping more code. Dom rendering itself is the same though. Async compiles just fine, otherwise it wouldnt be a babel option. :)

@emilio-martinez
Copy link

@rbosneag we recently shipped a set of global navigation elements built on lit-html (& lit-element) with browser support down to IE11—no problem at all re:the transpiration down to es5.

@charnould
Copy link

@charnould lit-html uses browser APIs that aren't available in Node. It's not going to work unless you load it in a browser emulator like jsdom.

Understood!
However, is Server-side rendering still on track for 1.0 (as stated 1.0 Roadmap)?
By the way, do you have any hint about 1.0?

@tiberiucorbu
Copy link

tiberiucorbu commented Mar 18, 2019

@rbosneag we recently shipped a set of global navigation elements built on lit-html (& lit-element) with browser support down to IE11—no problem at all re:the transpiration down to es5.

@emilio-martinez can you share your setup, I've spent hours poking ideas into webpack, typescript and babel configs but I have no solution yet. Here is my fork of typescript babel webpack where I try to adopt lit-element:

https://gist.github.com/tiberiucorbu/2c3cdc60b1941939e288ae11ffeaed0e

@emilio-martinez
Copy link

@tiberiucorbu I believe it mostly came down to adding an entry in the Webpack rules array to let Webpack know to handle these packages. In our case we passed them to ts-loader, but I'm sure the same could be done with babel.

The entry we added looks like the below.

{
  test: /\.js$/,
  include: [
    path.resolve(__dirname, 'node_modules/lit-element'),
    path.resolve(__dirname, 'node_modules/lit-html')
  ],
  use: [
    {
      loader: 'ts-loader',
      options: {
        configFile: path.resolve(__dirname, 'tsconfig.json')
      }
    }
  ]
}

@tiberiucorbu
Copy link

Thanks @emilio-martinez, I managed to nail it down with two steps : in webpack I bundle ts to esnext that produces a bundle that contains all the goodies : "async, class extends..." and then in a post step, using babel I'm recompiling the esnext bundle to an IE11 compatible bundle. Seems to work : https://github.com/tiberiucorbu/es5-esnext-webcomponent-project-starter

@wesleytodd
Copy link

wesleytodd commented May 12, 2019

Using browserify and no babel or other compile tooling in my project I ended up wanting this, so I published a precompiled version as es5-lit-html. It uses the base configuration of @babel/preset-env, so it should work in any context people might need, specifically for me commonjs exporting.

https://github.com/wesleytodd/es5-lit-html

I would be happy to hand this over to the polymer team if they want it. If not, I will try to keep track of when releases are made here and publish the corresponding versions asap.

Edit: should have added, other than this part it is working great! Got up and running today with hardly any issues. Great work team!

@logicalphase
Copy link

logicalphase commented May 12, 2019 via email

@justinfagnani
Copy link
Collaborator

justinfagnani commented May 12, 2019

I don't think this is a good idea. Interop between the built and unbuilt versions will not work correctly.

Edit to add: And I want to point out again that shipping unnecessarily compiled code to modern browsers negatively impacts perf and code size. You'll be disadvantaging most of your users. We've seen a 25% difference in app size between ES5 and ES2017. Differential serving or using <script nomodule> for legacy browsers is a much better option. Either way, we need to ship only one canonical implementation of the library to avoid bloat and iterop issues.

@wesleytodd
Copy link

I understand your reasoning for not shipping it. That said, I am sure many users don't want to have to make changes to their build for one lib in their app. Since my build tool chain is commonjs, and productivity is my primary concern (not perf), it made sense for me. I am sure it makes sense for others, and I will leave it up to them to make the same decision.

Your comment alludes to specific compat issues. Are there specific things you know of that will break? It seems to work for me in my basic usage so far.

@majo44
Copy link

majo44 commented May 24, 2019

Hello,
I understand the reasons, I even prefer the clean es6, I even able to establish clean pure es6 development workflow. But the reality is that most of current existing tools and dev workflows expect es5 code (even with es6 modules).

Currently I'm working on Angular project where I want to use lit custom elements, that project is using angular-cli and I will need to add special additional step to translate lit, hack lib mapping, what is not simple especially with monorepo/lerna project :( Delivered es5 code will solve all my problems :)

@Lodin
Copy link

Lodin commented May 24, 2019

@majo44, I believe it is an issue of the Angular CLI, not the lit-html library. They should compile the es6 code automatically or provide a way to enable the compilation. If we rely on tools too much, our users will continue suffering from non-optimal code and reduced performance. Our intent to rely on tools already led us to the current situation where we live in a world of browsers supporting ES6, but 99% of the code we have is still ES5.

@majo44
Copy link

majo44 commented May 24, 2019

As I said, I understand, I'm sad too about %, but revolution will not happens from day to day, but slowly step by step, tool by tool, lib by lib, and to speed up this process we can't say "hey we have to replace everything today".

I'm not working with Ng because I want, but because my managers and colleagues do not know and do not trust in alternatives, convince them to web components took for me a months. If I will told them "I have super power lib, but we have to change all code to es6" no one will allow me to even look at that lib, also even If I will say "but your dev process have to be changed" it will not simplify.

But if in some time, my all libs, my whole workflow will be ready for simple switch to es6, I will do that, and there will be not any defiance.

@ruphin
Copy link
Contributor

ruphin commented May 24, 2019

Remember that you do not need to move your entire project to es6 to use es6-based dependencies.

You can add one file that imports all your es6 dependencies, run that file through Rollup, and then you have a single es5 file with all your dependencies that you can use in your project.

@justinfagnani
Copy link
Collaborator

@ruphin is exactly right. The only require is that if your app needs to compile to ES5 that you compile your ES6 dependencies to ES5. This can be done in Webpack and Rollup configs relatively easily. For

Angular CLI users there's an article on using custom Webpack configs here: https://alligator.io/angular/custom-webpack-config/

@majo44
Copy link

majo44 commented May 24, 2019

I love our community, and consistency in our ecosystem. @justinfagnani even in your company (God bless Google) you are not consistent (APF?WTF?). So what I can expect :(

I know that I'm able, I know how to do that, but I do not think that this is good to do that in this way.

If you do not want to do that for me (or other people), please do that for mother earth:

  • downloades per week: ~11500
  • compilation time: ~10s
  • percentage of people which need es5 75%

~23h of compilation time required weekly, just because you do not do that once per release :)
Is ~4,5 kWh per month :) ,

Best regards. Please forget my request.

@justinfagnani
Copy link
Collaborator

@majo44 we have pretty much nothing to do with the Angular project. They've chose to make their own packaging format, but that's not something we would do. I consider it too complex for our team and goals.

I've stated in this thread why it's a technical problem if we publish more than one version of our libraries. We don't want to enable the bugs that will result from that.

@wesleytodd
Copy link

wesleytodd commented May 24, 2019

I am sorry if I triggered this conversation to go further. I think it sounds like a good decision for the Polymer team to not publish a transpiled version. Their responsibility should be focused on what is best for the library. If they think supporting two formats is counter to that, fine. This is why OSS is great, for those of you who (like me) want a transpiled version, it is as simple as publishing it. I did it for you. Let's let them get back to all the other more worthy things they can be doing :)

@tiberiucorbu
Copy link

The problem with a transpiled es5 version is that it requires on the runtime the adapter and is about ~30% bigger that the es6 bundle, so just because of IE11 our clients that use a modern browser have to download and process more JS than required. I think we need both bundles and the tooling that enables that.

@web-padawan
Copy link
Contributor

I think we need both bundles and the tooling that enables that.

You can reach that by using webpack-babel-multi-target-plugin. It does exactly what you ask for: ES module and ES5 bundles. Check the polymer3-webpack-starter as an example of using that plugin.

AFAIK, in the upcoming Angular 8.0 there will be a similar tool baked into CLI.

@tiberiucorbu
Copy link

Thanks for sharing @web-padawan

@lake2
Copy link

lake2 commented Jul 6, 2019

Short answer is: this is needed to use native ES modules in browser (with the small transform which consists of resolving package names to paths).

Same applies to lit-element and most of web components around Polymer community (as they use native ES2015 classes and transpiling affects them by imposing the need for additional shim).

Example babel-loader config to work with lit-html can be found here: https://github.com/web-padawan/lit-components/blob/f4f17f6267cf440dd8abdb7f4794a66cdc51330b/utils/webpack.common.js#L6

@justinfagnani I do think this should be clearly documented and explained with code examples. Not everyone will use Polymer CLI, most of people will prefer Webpack etc.

This babel config not work for me , and I google a lot but didn't find a solution.
It's a very bad idea not to transpile to es5, it will waste a developer a lot of time to find a solution.
The boss ask us to make website compatible with old browsers, though we dont't love to.

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

No branches or pull requests