Closed dadleyy closed 8 years ago
IMO, module syntax should be the import statement from ES6.
I totally agree that some of the features in import
might feel a little dirty, but I don't think it's a good idea to skip such an important feature such as how you require code files. The define/require approach you outlined can in any case always be supported with a library required in rumtime.
By dropping the import
statement, we are in the same pickle the original CoffeeScript is, where people feel like they can't use CS because it is lacking features ES6 has.
It made sense that CoffeeScript had its own class implementation or could have its own module implementation in the old days of ES5, because back then every library or toolset had to cater for themselves anyway. Currently, with ES6, a lot of these features are being consolidated, and it makes sense to support it.
Welcome @dadleyy and @carlmathisen ! Very happy to have both of you here.
@dadleyy raises some interesting points and does so in a well-reasoned way. If nothing else, I certainly agree with this:
I think in order to move forward with the import/export we should first draw up a list of benefits we achieve by implementing that format over the require + destructure.
I also agree with this:
people feel like they can't use CS because it is lacking features ES6 has.
and expect to use it as a fall-back argument for other such features in the future. Given this effort is likely to result in a major-version-bump at the very least, folks uninterested in the new features are always welcome to use CS v1.
I hope to respond with more depth later, but off the top of my head, the chief advantages of import
/export
include:
default
member, primarily for compatibility with pure-es6 code. I might recommend a bit of reading on the subject. require
's are, in my opinion, an anti-pattern that should not be encouraged (though also not disallowed). Considering a better alternative to import React, * as ReactStuff from 'react'
might be worthwhile, though it doesn't bother me too much personally.
Thoughts?
I would also like to throw out an additional proposal:
from 'react' import React
The primary motivation is situations when you have a long list of member imports, having the "from" at the end is a little weird:
import {
MemberOne,
MemberTwo,
MemberThree,
} from 'my-module';
could instead be:
from 'my-module' import
MemberOne
MemberTwo
MemberThree
though we'd need to think about what to do when you import React, { PropTypes } from 'react'
if going without {}
.
I'm not convinced this proposal would be worth the departure from ES6 but wanted to share it. Thoughts?
Full ES2015 module support is, in my mind, the top-priority most-pressing issue facing CoffeeScript today, and the No. 1 reason that people are abandoning it in favor of ES6. I’ve written documentation explaining how to use CommonJS require
to work with modules in CoffeeScript in Meteor, but I recognize that at best it is a workaround. You can see in some of the issues in the Meteor repo places where require
is no substitute for import
, even though at present that’s what require
is compiled into.
I consider module support to be so urgent that I think it should be built into the current CoffeeScript 1.x, not put off until whenever this new project gets off the ground. The consensus from the various issues in the main repo is that we want to essentially support ES2015 syntax as is, seeing as it’s so coffee-like already; and we would output import
and export
statements, leaving the conversion to CommonJS for other tools like Babel further down the chain. Adding this support would not be a breaking change, since import
, export
and default
are reserved words in CoffeeScript already; the only caveat would be a warning in the docs that it would be the developer’s responsibility to pass CoffeeScript’s output through Babel if the developer was using modules.
Someone made a slapdash attempt at implementation in this pull request; I’ve continued a conversation on that thread to try to scope out what a proper implementation would be. I haven’t had much time to work on it, but I’m hoping to get at least a rough draft up on GitHub for others to poke holes in and gradually get polished, and get merged into CoffeeScript 1.x. I wholeheartedly support the idea of CoffeeScript6 and revamping the language for ES2015+ more broadly, but I think module support is so important and so urgently needed that we should make the effort to implement it now in the CoffeeScript we have, even if it means reimplementing it in a new architecture later.
I agree 100% with @GeoffreyBooth .
While I'd love to see from ... import
as described above, my guess is that'd have too much friction relative to the minor benefit.
@GeoffreyBooth I hope you share your forthcoming PR here at an early stage so that members of this community can contribute. Personally I'd love to take part.
I’ve been working here. It’s in the very, very early stages: I have failing tests, and I can handle import 'module-name'
, but that’s it. Struggling to figure out how to parse import foo from 'lib'
within grammar.coffee
. Any and all help most appreciated! I’m happy to add contributors to this repo, or we can move the work to somewhere else if there’s someplace more appropriate.
This is awesome, @GeoffreyBooth and I can only second what @rattrayalex said. I'll have a look at it as well sometime this week.
Side note: with working on this PR, we're basically agreeing to do initial work on the original coffeescript codebase and not redux or decaf. Is that correct?
@JimPanic yes, that’s what I meant about potentially reimplementing this later. I have a hunch that the Redux codebase would likely make a better starting point for the CS6 effort (this is a topic for an entirely separate thread, so let’s please not get into it here) so this PR will likely be the last major new feature in CoffeeScript 1.x, and we’ll have to redo it in CS6. But I think the potential duplication of effort is worth it, to stanch the bleeding of developers abandoning CoffeeScript in the meantime until CS6 can get anywhere close to beta.
Understood and I agree. :+1:
@GeoffreyBooth Oh man, this is kind of a mess. I have the same problem as you: I don't understand how those three files play together. Maybe this is also what the redux codebase was trying to fix. :)
I'll continue to try to wrap my head around how all this works…
I managed to get the first two test cases working:
import 'module-name'
import foo from 'module-name'
The rest and especially the next one (import { foo } from 'module-name'
) are not yet working. I'll push if I find some time this evening or tomorrow during the day.
I would also like to mention that currently Coffeescript/CommonJS and ES6 handle namespaces differently. There needs to be a common way of making sure that both require environments co-exist correctly.
In addition to that, and something I've run into a lot with CommonJS loading, is how to handle circular references with require statements. See this issue in Meteor for a good breakdown of this problem: https://github.com/meteor/meteor/issues/6381
@mrmowgli, the plan at least for the PR I'm working on is for CoffeeScript to leave the module handling to downstream tools, just as it does now with require
. So just as:
_ = require 'lodash'
gets output as
var _;
_ = require('lodash');
An import statement like:
import _ from 'lodash'
would get output as
import _ from 'lodash';
In other words, just as CoffeeScript relies on other tools to process the require
statements and wire the modules together today, CoffeeScript would still rely on other tools to process import
and export
statements. I don’t see the need to add module resolving to CoffeeScript’s scope.
Just updated my original comment on this issue. I'd say its pretty clear we're going to have import
and export
and I'm very much okay with that.
Now that https://github.com/jashkenas/coffeescript/commit/7667cb2370c1ebd1f61061d71b117be5ede78ecb has happened, I think we can cross this one off the list. One down!
Thank you all for your hard work on getting import/export support into CoffeeScript!
This issue was moved to jashkenas/coffeescript#4905
With the adoption of es6 by many, many, many popular javascript frameworks and libraries, supporting
import
/export
has become very relevant to the adoption of coffescript in the codebases that use those frameworks. This issue has been brought up several times in the original coffeescript repository - see also #3162.At the time of writing this, the
import
andexport
keywords are treated by the coffescript lexer as reserved words and throws a compile-time error when encountered.original comment