Skip to content
This repository has been archived by the owner on Feb 19, 2018. It is now read-only.

CS2 Discussion: Features: import/export #7

Closed
dadleyy opened this issue Jul 21, 2016 · 19 comments
Closed

CS2 Discussion: Features: import/export #7

dadleyy opened this issue Jul 21, 2016 · 19 comments

Comments

@dadleyy
Copy link

dadleyy commented Jul 21, 2016

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

@dadleyy dadleyy changed the title Module syntaxt Module syntax Jul 21, 2016
@carlmathisen
Copy link

carlmathisen commented Jul 22, 2016

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.

@rattrayalex
Copy link
Contributor

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.

@rattrayalex
Copy link
Contributor

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

  • proper use of the default member, primarily for compatibility with pure-es6 code. I might recommend a bit of reading on the subject.
  • "static" rather than dynamic imports – conditional or dynamically constructed 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?

@rattrayalex
Copy link
Contributor

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?

@rattrayalex rattrayalex changed the title Module syntax import/export Jul 23, 2016
@GeoffreyBooth
Copy link
Collaborator

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.

@rattrayalex
Copy link
Contributor

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.

@GeoffreyBooth
Copy link
Collaborator

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.

@JimPanic
Copy link
Contributor

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?

@GeoffreyBooth
Copy link
Collaborator

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

@JimPanic
Copy link
Contributor

JimPanic commented Jul 26, 2016 via email

@JimPanic
Copy link
Contributor

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

@JimPanic
Copy link
Contributor

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.

@JimPanic
Copy link
Contributor

@mrmowgli
Copy link

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:
meteor/meteor#6381

@GeoffreyBooth
Copy link
Collaborator

GeoffreyBooth commented Jul 29, 2016

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

@dadleyy
Copy link
Author

dadleyy commented Aug 1, 2016

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.

@GeoffreyBooth
Copy link
Collaborator

Now that jashkenas/coffeescript@7667cb2 has happened, I think we can cross this one off the list. One down!

@carlmathisen
Copy link

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

@coffeescriptbot coffeescriptbot changed the title import/export CS2 Discussion: Features: import/export Feb 19, 2018
@coffeescriptbot
Copy link
Collaborator

This issue was moved to jashkenas/coffeescript#4905

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants