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

Discussion: Pre-ES6 Support #430

Closed
Hesulan opened this issue Nov 14, 2016 · 4 comments
Closed

Discussion: Pre-ES6 Support #430

Hesulan opened this issue Nov 14, 2016 · 4 comments

Comments

@Hesulan
Copy link
Contributor

Hesulan commented Nov 14, 2016

Pre-ES6 Support

How should Marko deal with ES6+ features in pre-ES6 environments?

Definitions

"ES6+" refers to features and keywords introduced in ES2015 or later, and the environments which support them.

"pre-ES6" refers to environments which do not support features introduced in ES2015 or later, in which those features must either be transpiled or polyfilled before execution, or not used at all.

Context

It is of course possible to use ES6+ features within user-written code, which simply gets copied into the compiled output in the case of a template or executed as-is in the case of a component or taglib. The burden then falls on the developer to know which features may or may not be used in their environment.

However, as discovered while working on #428, Marko's compiler is perfectly capable of generating ES6+ code, though it doesn't currently do so. The purpose of this issue is open a discussion on the possible ways of dealing with situations where a new enhancement or taglib wishes to make use of such features while rendering, which may not yet be supported in all environments, especially client-side.

Possible Solutions

  1. Automatically compile certain features and keywords differently based on a configuration option. This would require the most effort to implement and maintain.

  2. Don't allow ES6+ to be generated by the Marko core. Any enhancement or taglib that wants to use newer language features must be a separate module.

  3. Clearly mark all features and tags which require ES6+ support. The burden then falls once again on the end developer to know what they can or cannot use, or to run it through a transpiler before rendering.

  4. Create an optional transpiler plugin. If a valid transpiler (like Babel) is passed to the compiler, then whenever an ES6+ feature is encountered it will be automatically fed through the transpiler's API. It could possibly even accept other transpilers like coffeescript or typescript. I would be willing to work on this when I find the time if others are interested.

Those are just the ideas I could think of, this is intended to start an open-ended discussion. Suggestions and constructive criticism are welcome!

@patrick-steele-idem
Copy link
Contributor

Here are my thoughts:

Marko should not be in the business of transpiling JavaScript. If a developer wants to use ES6 functionality, then the code should pass through unmodified. On the server, you wouldn't want to transpile the code since later versions of Node.js have great ES6 support.

There is one exception and that is ES6-style imports:

//html syntax:
<import foo from "./foo"/>

// concise syntax:
import foo from "./foo"

ES6-style imports are not currently enabled by default in any browser and are not supported in Node.js. However, we like the syntax and semantics of ES6-style imports so we want to support it.

Specifically related to the let and const tags, I want those to pass through as-is as there ES6 keywords. No transpiling is required on the server and no transpiling is required for modern browsers. If the user wants to support older browsers then they would need to enable babel to run on .marko.js files to produce ES5-compatible code.

Could integrate babel? Maybe, but I don't think we should since the JS module bundler will typically be doing transpiling anyway.

@Hesulan
Copy link
Contributor Author

Hesulan commented Nov 14, 2016

@patrick-steele-idem I was thinking more about long-term compatibility. I feel like import/export is just the tip of the iceburg. Aside from big things like that and async/await, the little things also start to look really tempting, like rest/spread operators, destructuring, argument defaults...

I guess a variation of my question might be something like "Where will the line be drawn on legacy support in the (near-ish) future, and what will be the recommended solutions"? The compiler already requires Node.js 4+ to run, though I believe none of the core components or tags currently produce anything higher than ES5.

The idea of built-in support for running in ES3-only is ridiculous, but for the compiler to assume native ES7 async/await support would be equally laughable. Aside from the note about the compiler requiring Node 4+ I couldn't find anything that explicitly stated the lowest supported version, or detailed information on what is needed to make it work in legacy environments, but I feel that's something that needs to be addressed.

@Hesulan
Copy link
Contributor Author

Hesulan commented Nov 14, 2016

At the moment I agree that it's pretty safe to stick with ES6 or lower for the compiler code, and the renderer doesn't use anything newer than ES5, or maybe even ES3 (unless of course the user writes ES6+ code). But things like that have a way of getting fuzzy fast, especially with constantly evolving standards like ECMAScript, Node, and the major browsers.

@Hesulan
Copy link
Contributor Author

Hesulan commented Nov 21, 2016

I think what was really bothering me is that none of the documentation - at least that I can find - describes which features and ES versions are required by the various pieces of Marko, other than a side-note somewhere about the compiler using ES6 classes and a vague statement about the renderer being "supported in all web browsers" in the FAQ.

For example, a list like the following could be added to the documentation:

It would also be helpful to include information on how to transpile with Babel, and when that would be necessary, for new users who may not already know those things.

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

2 participants