nodeca / js-yaml

JavaScript YAML parser and dumper. Very fast.
http://nodeca.github.io/js-yaml/
MIT License
6.29k stars 770 forks source link

Support ES Modules, and by extension, Deno and web browsers #541

Closed KSXGitHub closed 3 years ago

KSXGitHub commented 4 years ago

Node.js has ES Modules feature turned on by default, albeit still experimental. Once Node.js can use ES module syntax to load js-yaml, https://pika.dev can convert js-yaml to something web browsers and Deno can consume (alternatively, snowpack can be use to create web modules).

This change would require rewriting almost all code to modern import syntax, I am willing to work on a pull request.

puzrin commented 4 years ago

Hi! JS syntax change is not a big deal, and i have no principal objections about es6. The most boring thing is to change development process. If anyone can help, that would be very useful. After change to es6, this topics should be covered:

If you know "best practices" about topics above (and anything else i could miss) - let me know.

KSXGitHub commented 4 years ago
  • Backward compatibility. Still should support commonjs & old node.js.

Babel can compile them

  • Drop ./dist. Need better way to automate commonjs browser builds. May be some CDN can do that?

You may not need to commit ./dist to git, but you should still publish it to npm, there're countless npm-based cdn (unpkg, pika.dev, jspm.io to name a few). Babel can take care of this too.

  • How to publish both versions with minimal efforts?

    • Should we provide consistent cjs version on github or in npm only?

Write code in ES Module syntax, use Babel to transpile source code to CommonJS, publish both of them. In package.json, set "main" to CommonJS file and "module" to ES Module file.

  • Simple development. Preferably, without additional monitoring tools and compilers.

We would need at least Babel.

puzrin commented 4 years ago

Concept "babel will help" is too generic. I mean a more concrete recipes - content of package.json and additional scripts if required. Ideally - examples of well-known project, useable as template.

KSXGitHub commented 4 years ago

I mean a more concrete recipes - content of package.json and additional scripts if required

I can create a simple repo for you.

Ideally - examples of well-known project

Take a look at Preact, it supports CommonJS, ES Modules, and UMD.

There's also iter-tools, it's simpler, it supports CommonJS, ES Modules, and TypeScript.

useable as template.

I can convert this very repo for you (after I have converted the code to using ES Module syntax).

KSXGitHub commented 4 years ago

Update: I have created a simple repo with full explanation. I have also published a package from that repo. It is supported by Pika's CDN so you can try import it from the browser using ES module syntax.

puzrin commented 4 years ago

May be i'm too old, i don't understand idea to transpile everything.

aniketbiprojit commented 4 years ago
  • Why should we transpile es6 code instead of use native one?

Because, ES6 is the standard and will probably be succeded by ES7. Having code in newer standards enables newer contributors to add more value to project. Not many who have learnt JavaScript after classes came to be can work with prototypes.

  • Who cares es5 build will be in sync on npm publish?

If we are testing new code, might as well keep the old one in sync with any added features.

puzrin commented 4 years ago

Because, ES6 is the standard and will probably be succeded by ES7. Having code in newer standards enables newer contributors to add more value to project. Not many who have learnt JavaScript after classes came to be can work with prototypes.

I prefer KISS principle. This project is stable and has nothing to extend with. I don't like to overcomplicate things for uncertain features in future (that will never happens in real world).

If es6 code can't be used native, it's more simple to stay on es5 and organize simple wrapper.

If we are testing new code, might as well keep the old one in sync with any added features.

Please, understand me right. Changing syntax to es6 is trivial. The real problem is change of process. And all questions like this need to have concrete answers before start.

KSXGitHub commented 4 years ago

I prefer KISS principle.

KISS principle was never possible in JS world, it's not possible then, it's not possible now.

Before ESM, people have to use various inconsistent ways to bundle dependencies (CommonJS, UMD, etc), you may think that just adding a <script> tag is simple, but Node.js has no <script> tag, so you would have to create a CommonJS version.

Now with ESM, things can be simpler, you can drop legacy support entirely (seriously, semver allows you to do that without fear of breaking things for other people) and people that care can still support old browser if they want to (by using Babel). But if you don't want to increase major semver, then you would have to transpile yourself, making development more complex. As for me, I am fine either way.

I don't like to overcomplicate things for uncertain features in future (that will never happens in real world).

ES Module is a very certain and stable past for at least 2 years now. It has a standard. All major browsers support it (except IE). It will not stop working.

If es6 code can't be used native, it's more simple to stay on es5 and organize simple wrapper.

I can run ECMAScript 2020 (and by extension, es6, which can be considered old at this point) in the Chrome browser, right now, without wrapper.

Not to mention, ESM allows developer to use tree-shaking to reduce bundle size.

puzrin commented 4 years ago

You tell well known things, but i still don't understand why es6 should not be used natively in this project (with only es5 fallback transpiled by babel).

KSXGitHub commented 4 years ago

but i still don't understand why es6 should not be used natively in this project

You mean for the tests? The tests are already in old syntax, I don't want to touch it if it for now. But if you want to change it to es6 too, it's fine.

puzrin commented 4 years ago

You mean for the tests?

I mean for everywhere where import directive needed.

The tests are already in old syntax, I don't want to touch it if it for now.

Attempt to change dev process with small steps will be guaranteed ass pain. IMO it's more rationale to plan new approach and to do all at once.

KSXGitHub commented 4 years ago

You mean for the tests?

I mean for everywhere where import directive needed.

Node.js support ES Modules now. But I'm not sure if dependencies and test framework this repo uses support ES Modules out-of-the-box.

Attempt to change dev process with small steps will be guaranteed ass pain. IMO it's more rationale to plan new approach and to do all at once.

So you don't want to minimize code change? Fine, but we may need to add transpilation plugins for reason above.

puzrin commented 4 years ago

But I'm not sure if dependencies and test framework this repo uses support ES Modules out-of-the-box.

I'm 100% sure, after node.js officially enabled modules all popular dev tools will support those very soon. If there is lack of support now, the most obvious solution is wait for 1-2 months, doing nothing :)

So you don't want to minimize code change? Fine, but we may need to add transpilation plugins for reason above.

No, i have no goal to minimize code change. I have goal to get new comfortable development process (with import support and fallback to old way). And IMO using es6 native (with transpilers for es5 only) will be more comfortable than transpiling everything.

Under es6 i mean version with import support, and anything supported before. For example i don't mean classes must be used, but those can be used if needed - because if js engine supports import, it supports classes too.

chase-moskal commented 4 years ago

hello. i can't use this library in my modern es-module-only browser apps. as it stands i'm considering a build step that converts all yaml to json, which the browser can consume

does anybody know of an alternative which distributes es modules?

authors, would you be willing to accept a pull request which

:wave: thanks

chase-moskal commented 4 years ago

hacky es module build now available!

greetings! for my own purposes, i've created a quick esm fork

here are the changes and my explanation

if you clone the fork, you can run the build with npm i -s && ./esm/build

i do not think this should be merged into js-yaml! it's too silly and hacky. instead, my recommendation would be a typescript rewrite. perhaps an ambitious junior-level developer looking to contribute on open source projects would be up for the task

    :wave: chase

puzrin commented 3 years ago

Fixed by https://github.com/nodeca/js-yaml/commit/1b5fea8526fea734041334db3687ae5a919a0dfc