jashkenas / coffeescript

Unfancy JavaScript
https://coffeescript.org/
MIT License
16.52k stars 1.98k forks source link

Add support for ES6 module syntax #3162

Closed simonexmachina closed 8 years ago

simonexmachina commented 11 years ago

Maybe I'm missing something, but I can't see how to use ES6 modules from CoffeeScript. We should have this.

jashkenas commented 11 years ago

It looks like there isn't yet a single JS runtime that supports ES6 modules yet: http://kangax.github.io/es5-compat-table/es6/

We should not have this until it's ready.

simonexmachina commented 11 years ago

Its preventing me from using an es6 module transpiler. Is there any way I can prevent this from being a syntax error?

davidchambers commented 11 years ago

Is there any way I can prevent this from being a syntax error?

Could you include the code as JavaScript between backticks?

`import { Point, pow, sqrt } from 'math'`

# actual CoffeeScript code...

`export Segment`
simonexmachina commented 11 years ago

Yes, but it's pretty ugly! Thanks for the tip though, that works.

alexgorbatchev commented 11 years ago

:+1:

mbixby commented 11 years ago

+1

`export` Controller.extend # not working
   content: ...

vs.

# in 'controllers/configuration/items'
ConfigurationItemsController = Controller.extend
  content: ...
`export ConfigurationItemsController`
abhayathapa commented 11 years ago

+1. Great

kimroen commented 10 years ago

Is this something we should reconsider? With things like Ember App Kit and similar projects evolving, I think there's at least grounds to brainstorm a potential solution.

mbixby commented 10 years ago

Is the solution I posted (inline javascript) too invasive to be implemented?

kimroen commented 10 years ago

It's absolutely more of a nuisance than an actual issue.

Things like this: (export default)

export default Ember.TextField.extend({
  didInsertElement: function() {
    this.$().focus();
    this.$().addClass('focus'); // headless testing is brittle
  }
});

I would like to be able to write

export default Ember.TextField.extend
  didInsertElement: ->
    @$()
      .focus()
      .addClass 'focus'
mbixby commented 10 years ago

@kimroen see @jashkenas's answer above

kimroen commented 10 years ago

I obviously read through the issue before commenting :)

No worries, I just thought it was worth reconsidering. Do with as you please.

alexgorbatchev commented 10 years ago

:+1:

mikejholly commented 10 years ago

:+1:

mrinterweb commented 10 years ago

:+1: I would really like this feature. I'd wager that we are going to start seeing more projects that use ES6 modules.

Even if the word "export" and "import" could be shortened to "exp" and "imp" respectively to get around keyword conflicts, that would be pretty great. I suppose an alias to those methods in the Square's ES6 module transpiler could be created. That may relieve coffeescript developers for a little time, but knowing that export and import are reserved words in ES6 makes me doubt that making those aliases outside of coffeescript would be well received.

simonexmachina commented 10 years ago

I've gotta say that, as much as I love CoffeeScript, I've moved away from it in my latest project because it doesn't support import, export and generator functions. It's a sad day, but all things must pass :)

mrinterweb commented 10 years ago

aexmachina, I'll much rather struggle to find a way to make CoffeeScript work with export and import than to stop using CoffeeScript. I keep hearing people say "JavaScript is fun." If JavaScript is so fun to write, why are there 100+ JS compilers?

I just posted an issue on the CoffeeScriptRedux project: https://github.com/michaelficarra/CoffeeScriptRedux/issues/281 Alternatively, I suppose there is nothing that would stop anyone from forking CoffeeScript and changing the reserved words. Doing so would likely break backwards compatibility.

vendethiel commented 10 years ago

There are 100+ compilers because 1) it's the only language that runs client-side (expected chromium-dart and such) 2) it's an easy compilation target

vendethiel commented 10 years ago

I meant excepted*. I can't type on phones ;)

xixixao commented 10 years ago

Creating a version of CoffeeScript that targets ES6/traceur might become important in near future. We don't want lose @aexmachina! I wouldn't worry about the things that don't add to CS (like destructuring), but this seems to make sense (as do generators).

Most importantly, this doesn't break IE6 - adding this to CS doesn't force you to use it.

michaelficarra commented 10 years ago

@xixixao: Before we do that, we need to syntactically and semantically align existing overlapping features. Ellipses for spread/rest need to be prefix to match ES6. super semantics need to be changed to match ES6. But we need to wait until it's finalised before making any of those changes. I know I've gone into some detail on this in an issue before, but good luck finding it...

xixixao commented 10 years ago

@michaelficarra I do not agree with that at all. But I guess that my position breaks the good old just JavaScript motto. On the other hand, == is an overlapping feature and has different semantics, so maybe that motto is not meant to be interpreted in this way.

tiye commented 10 years ago

As I read an article, linking some words here. http://shift.mirego.com/post/76526223016/javascript-next

I don’t think the team was enthusiastic about the idea of losing the classes, destructuring, rest arguments, defaut parameters and other cool features of CoffeeScript. I don’t blame them. I like these features too. But being future-friendly was more important to me. I wanted to use that ES6 syntax as soon as possible. With the new generation of auto-updating browsers, the time when we can all use ES6 is not so far away and being ahead of the curve could serve us well.

DougPuchalski commented 10 years ago

Backticks don't work with Ember App Kit Rails, at least.

vendethiel commented 10 years ago

Why not ?

DougPuchalski commented 10 years ago

@Nami-Doc A comparison here https://github.com/dockyard/ember-appkit-rails/issues/55#issuecomment-38101301

vendethiel commented 10 years ago

Unrelated, you're just using a global variable in the second example. Continue that discussion there though ;-).

chrisnicola commented 10 years ago

Worth noting that AngularJS 2.0 will be utilizing this feature. Might be time to revisit this soon.

kieran commented 10 years ago

While not meaning to beat this particular horse, I would love to see ES6 module syntax supported without backticks. Many popular frameworks are already embracing modules (ember, angular, etc...) today via transpilers.

import, export, and default are all reserved words in JS (as of es5), of which only default is used as a keyword in CS (and semantically distinguishably, at that). Since using these keywords essentially opts you in to the new es6 features, I don't fully understand compatibility argument. In so far as I understand, any language compatibility is pushed out to the JS interpreter, which only reinforces the axiom that CoffeeScript "is just JavaScript".

I can definitely see how other es6 features would break existing CS syntax, but is there a particular reason we need to all-or-nothing them?

I dunno, maybe it's time to re-examine this particular feature? It's definitely becoming more of a pita for me every day.

gangster commented 10 years ago

+1

kebot commented 10 years ago

+1, es6-module-transpiler dropped CoffeeScript support

SeanRoberts commented 10 years ago

+1

DougPuchalski commented 10 years ago

The less reason people have to disparage the use of CoffeeScript, the better.

athowe commented 10 years ago

Have the major browsers all made a statement/put a point on their roadmaps for generator support? I think it's reasonable to expect a timeframe or roadmap from the CS devs but only if they have an idea of when browsers will be doing the same.

nathanpalmer commented 10 years ago

Would love if support for this was reconsidered so that things like the es6-module-transpiler and ember-cli can work well with CoffeeScript.

iki commented 10 years ago

+1 we love coffeescript here and used it for lot of client projects in last 2 years, however we're starting to play with angular 2 and es6 transpilers and would really appreciate coffeescript support for es6 constructs

theworkerant commented 10 years ago

+1

xixixao commented 10 years ago

If anyone interested has the time, I am sure that a PR would have a good chance of getting in (along with yield support).

bjmiller commented 10 years ago

"import" and "yield" should be two separate PRs, I suspect.

backspaces commented 10 years ago

Just to be clear: when you use backticks for the import/export module syntax, do you then include the traceur runtime? I'm fairly sure the System object import/export is not yet available, right?

backspaces commented 10 years ago

Answered my own question. Our es6 work now includes concatenating the runtime to our js/es6 framework. This means we get both import/export but also all the polyfills.

rattrayalex commented 10 years ago

ES6 is increasingly important, and I think it may be too big a deal to do piecemeal by PR's.

Personally, I'd love to see something from @jashkenas / @xixixao on the intended direction for this. How will CS's class work with ES6's? Modules? etc. I imagine there may need to be some non-backwards-compatible changes made, in which case this would be a major release. While sooner rather than later is nice, I'm personally more interested in hearing about a strong, reliable plan for the future of CoffeeScript than a few patches thrown on tomorrow.

backspaces commented 10 years ago

TL;DR: Modules are not es6, they are separate. CS can easily use import/export or System.js polyfills. This has nothing to do with current browsers. Define your goals and you can achieve a reasonable result.

Long Form: I am currently integrating a modestly large CS project with a team who has adamantly rejected CS, God knows why .. we all have run across this and it seems to be that its just one more thing to learn. Shit! But...

We have come to peace over all this by agreeing that modules really are not es6, they are separate. Even traceur uses a separate module for import/export. The "right" solution is to use the System object, and following/messaging with Guy Bedford, the daddy of current es6/system.js, has helped a lot. The CS/JS war is somewhat ameliorated by meeting at module. So the JS/CS folks are converging via modules. This is a Good Thing .. more small modules seem more used. DRY.

We traced two reasonable solutions: a System.js polyfill, and es6 import/export. After a couple of weeks of exploring these, we agreed on import/export and using the traceur runtime if needed. There are several workflows to achieve this.

One huge advantage is that it appears that we may no longer have to state a specific CS concatenation of our CS modules into dependency order. (Only tried on a small sample) Traceur appears to do that for us.

We also can use only the parts of the framework we want by exposing our use of import/export. The resulting concatenation will include only the transitive closure .. not the entire framework.

All this is to urge you to separate es6 features from modules. We've been cursed by differing module systems for far too long and System.js & import/export promise to unite them.

Jeremy is right to say we shouldn't include es6 features until universal. But it is wrong for CS to avoid the module problem. Really.

DougPuchalski commented 10 years ago

Yes, people are rejecting CS often for irrational reasons. JS is evolving rapidly however and if CS doesn't keep up there will be more reasons to abandon it. I vote for incremental improvements over delayed major releases.

searls commented 10 years ago

Is it correct to say that the only real "issue" here is that CoffeeScript's compiler throws an error whenever import or export is encountered? Is it adding much value for CoffeeScript to do this versus falling back on interpreters to raise alarm? To me, the only benefit to these errors is slightly-faster-feedback that I've just run afoul of a runtime constraint, but that's a marginal benefit compared to the inconvenience people are describing in this thread. Seems like a lot of pain would be avoided by simply removing the compilation errors at little cost to everyone else.

In cases like these, where post-CoffeeScript-compilation transpilers are being used by many projects (I stumbled upon this trying to start a new project in ember-cli, for example), whether or not the ultimate runtime interpreter supports a given ES6 feature is not the most pressing question to answer when asked whether CoffeeScript should throw an error. Instead, what's the most valuable behavior to achieve developer happiness most of the time while still being "just JavaScript"? In this case, removing the error thrown when these reserved words are used seems to be the smart call. :shrug:

backspaces commented 10 years ago

It is trivial to backtick import/export and it works fine. It requires a runtime .. I think only the System polyfill. And it has all the advantages import/export provides .. leaving out modules that are no longer needed.

This is a huge advance to the usual Coffee stunt of concatenating your whole system and then compiling. I've tried it on a small demo and all seems well. Gets the dependencies in the correct order and handles transitive closure over modules.

This has completely changed my CS usage. I'm way more modular, and my team can accept my modules as if they were es6.

-- Owen

On Mon, Nov 3, 2014 at 8:37 PM, Justin Searls notifications@github.com wrote:

Is it correct to say that the only real "issue" here is that CoffeeScript's compiler throws an error whenever import or export is encountered? Is it adding much value for CoffeeScript to do this versus falling back on interpreters to raise alarm? Seems like a lot of pain would be avoided by simply removing the compilation errors at little cost to everyone else.

In cases like these, where post-CoffeeScript-compilation transpilers are being used by many projects (I stumbled upon this trying to start a new project in ember-cli, for example), whether or not the ultimate runtime interpreter supports a given ES6 feature is not the most pressing question to answer when asked whether CoffeeScript should throw an error. Instead, what's the most valuable behavior to achieve developer happiness while still being "just JavaScript"? In this case, removing the error thrown when these reserved words are used seems to be the smart call. :shrug:

— Reply to this email directly or view it on GitHub https://github.com/jashkenas/coffeescript/issues/3162#issuecomment-61589063 .

jeremyhaile commented 9 years ago

+1

Bitaru commented 9 years ago

+1

lolmaus commented 9 years ago

As CoffeeScript is locked at ES5 by its maintainer, i've started a discussion of a potential ES6-friendly CoffeeScript replacement here: https://github.com/coffeescript-cookbook/coffeescript-cookbook.github.io/issues/128

Please, participate and spread the word throughout the CoffeeScript community.

bjmiller commented 9 years ago

You know what? I need to say this, to get it off my chest.

You don't need ES6. At all.

There, I said it. What am I talking about, exactly? Let's face it, most of the proposed features are either completely unnecessary (e.g. let/const, Map/Set, Symbol), done better by CoffeeScript (arrow functions, class-extends, spread/rest, for-of, destructuring, template strings, comprehensions...), or done better by libraries (Promises, modules).

The most important feature of ES6 is still not implemented anywhere, and is likely to arrive last because it doesn't change/affect syntax and is apparently harder to do than I think: Tail call optimization. The most divergent (and, widely in use already) feature in ES6 is generators, and the next release of CS will have full support for them.

ES6 modules are kind of terrible, and no one can figure out why the TC didn't just use CommonJS, which everyone loves. Browserify handles modules and modularity better than the ES6 "modules" feature for the client side, and any use cases that fall outside of what Browserify does are probably handled well by Webpack.

So much of ES6 is straight up hype. "Solutions" that we've already solved ourselves by building libraries, or which only solve problems that come out of a textbook on computing theory.

With all that said, a small subset of ES6 things should probably be allowed to "pass through" to JS without the use of backticks, because some people will be happier that way, and everyone else can just ignore it. Especially if it's easy to implement, with no special syntax. But, even if it isn't, CS still does what it does very well, and you can build anything that you need using it.

ES6 will be obsolete before CoffeeScript is.