jashkenas / coffeescript

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

CS2 Discussion: Features: import/export #4905

Closed coffeescriptbot closed 6 years ago

coffeescriptbot commented 6 years ago

From @dadleyy on July 21, 2016 18:1

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 and export keywords are treated by the coffescript lexer as reserved words and throws a compile-time error when encountered.

original comment

Copied from original issue: coffeescript6/discuss#7

coffeescriptbot commented 6 years ago

From @carlmathisen on July 22, 2016 6:2

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.

coffeescriptbot commented 6 years ago

From @rattrayalex on July 22, 2016 17:7

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.

coffeescriptbot commented 6 years ago

From @rattrayalex on July 22, 2016 17:10

I hope to respond with more depth later, but off the top of my head, the chief advantages of import/export include:

Considering a better alternative to import React, * as ReactStuff from 'react' might be worthwhile, though it doesn't bother me too much personally.

Thoughts?

coffeescriptbot commented 6 years ago

From @rattrayalex on July 22, 2016 17:14

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?

coffeescriptbot commented 6 years ago

From @GeoffreyBooth on July 26, 2016 17:45

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.

coffeescriptbot commented 6 years ago

From @rattrayalex on July 26, 2016 17:57

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.

coffeescriptbot commented 6 years ago

From @GeoffreyBooth on July 26, 2016 18:11

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.

coffeescriptbot commented 6 years ago

From @JimPanic on July 26, 2016 19:2

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?

coffeescriptbot commented 6 years ago

From @GeoffreyBooth on July 26, 2016 19:13

@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.

coffeescriptbot commented 6 years ago

From @JimPanic on July 26, 2016 19:19

Understood and I agree. :+1:

coffeescriptbot commented 6 years ago

From @JimPanic on July 27, 2016 9:23

@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…

coffeescriptbot commented 6 years ago

From @JimPanic on July 27, 2016 15:17

I managed to get the first two test cases working:

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.

coffeescriptbot commented 6 years ago

From @JimPanic on July 27, 2016 17:13

See https://github.com/GeoffreyBooth/coffeescript/pull/2/files

coffeescriptbot commented 6 years ago

From @mrmowgli on July 29, 2016 20:28

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

coffeescriptbot commented 6 years ago

From @GeoffreyBooth on July 29, 2016 21:59

@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.

coffeescriptbot commented 6 years ago

From @dadleyy on August 1, 2016 15:32

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.

coffeescriptbot commented 6 years ago

From @GeoffreyBooth on September 17, 2016 2:29

Now that https://github.com/jashkenas/coffeescript/commit/7667cb2370c1ebd1f61061d71b117be5ede78ecb has happened, I think we can cross this one off the list. One down!

coffeescriptbot commented 6 years ago

From @carlmathisen on September 18, 2016 4:42

Thank you all for your hard work on getting import/export support into CoffeeScript!