Closed nathanhammond closed 9 years ago
This seems like it can be solved with #86 The compiled output (AMD) would have to be something like:
define(
['foo', 'exports'],
function(__dependency1__, __exports__) {
var foo = __dependency1__.__esModule ?
__dependency1__["default"] :
__dependency1__;
import "foo" as bar;
is not a valid syntax as today, the consideration at this point is import * as bar from "foo";
I had support for module foo from "foo"
for a bit, but as that syntax is in flux I've removed it. Once TC39 decides what to do about it vs import * as foo from "foo"
and esprima supports it I'll add support.
@eventualbuddha I'm working on the esprima branch for that. One thing to notice though, the branch of esprima used by 0.5.x is very old (git://github.com/thomasboyt/esprima#4be906f1abcbb), do you have any plan to align it with the esprima#harmony branch?
@caridy yes, as soon as the export default
problem is fixed (ariya/esprima#252).
It looks like import * as foo from "foo"
is the new way to import all of a modules named exports. However I would wonder how feasible it might be to add support for module foo from "foo"
and log out a warning about it. Basically interpret it the same was as the new syntax. The reason I ask this is as I look to use existing es6 module projects (ones using 0.4.x of the transpiler) with newer ones I am running into weird inconsistencies. It appears that the upgrade path to 0.5.x+ is rather rough and there seems to be very little momentum behind it.
I am trying to us a build workflow that brings in the raw es6 source files of my dependencies and then runs the transpiler over the entire tree of files. This is basically working save for the fact that many projects on the old version of transpiler are using slightly different syntax and in some cases broken syntax that once silently failed.
From Handlebars src:
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
var isFunction = function(value) {
return typeof value === 'function';
};
// fallback for older versions of Chrome and Safari
if (isFunction(/x/)) {
isFunction = function(value) {
return typeof value === 'function' && toString.call(value) === '[object Function]';
};
}
export var isFunction;
This is a static error in es5 code considering it's a double declare of isFunction but this didn't fail in the old transpiler it's just broken in a strange way (that handlebars seems to not be affected by).
It should instead be written:
// Sourced from lodash
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
var isFunction = function(value) {
return typeof value === 'function';
};
// fallback for older versions of Chrome and Safari
if (isFunction(/x/)) {
isFunction = function(value) {
return typeof value === 'function' && toString.call(value) === '[object Function]';
};
}
export { isFunction }
Strongly against adding legacy features. If you want legacy features, use legacy versions. And then make sure all your code is compatible with the new version. No compromises.
@domenic After thinking about it more I can see why you think that and honestly I think I agree. ES6 modules are entering one of the most important (and currently difficult) phases of their existence. There has been some adoption and tooling built up but there has also been some recent spec adjustments and the tools are starting to get smarter and stricter.
My worry is that if module authors are forced to adjust their usage of the syntax too often it will quickly become more of a pain than a gain.
What else can be done to encourage conversion to the new syntax and transpiler? Should there be a release of the 0.4.x transpiler that either implements the new syntax changes or at the very least spits out warnings about changes? Are the authors of the grunt/gulp/broccoli/etc plugins actively working on upgrading to the new transpiler version?
The state of much of this leaves me feeling uneasy. I'll continue trying to do what I can do, limited as it may be.
@matthewrobb @domenic, the beauty of this is that module foo from "foo"
and import * as foo from "foo"
will probably produce the same AST since their semantic is identical. Based on that assumption, and the fact that the current esprima implementation has a lot of code and tests to support module foo from "foo"
, I think we should start by adding support for the new syntax to esprima, producing the exact same AST, update the transpiler to transform that AST (which it doesn't support today), and then eventually clean up esprima from the old syntax.
I'm willing to take this one, but I will need some help! :)
@caridy @domenic For some "legacy" es6 features that may have seen decently wide use it would be best, when possible, to keep esprima's support in place. It may not be a feature used by the transpiler but it could be very useful for a validator or a linter.
I really don't think nonstandard features have any place in Esprima. It doesn't parse JSX or VBScript, and it shouldn't parse module x from "y"
.
@matthewrobb I agree with @domenic, there is no room for such things. Updating scripts using that syntax is a one time operation.
My goal with filing this bug was simply to have the transpiler support whole-module import syntax, which I believe has changed since I filed this bug.
I'm editing the title for this bug report from Support
import "foo" as bar;whole-module import syntax.`` to
Support ES6-specified whole-module import syntax.`
I haven't tested to make sure that it doesn't work, so if whole-module import has been created already you may safely close this issue by my opinion.
@domenic @caridy Is there any reason you couldn't do
import { * as foo } from "foo";
It seems like it actually makes more sense but beside that it would be nice to be able to import some named imports and then import the rest to a single identifier.
import {
* as lodash,
bind
} from "lodash";
I am trying to determine how this would tokenize in esprima. Currently module crypto from "crypto"
is a ModuleDeclaration. The AST generated from import *
couldn't possibly be compatible with the current whole-module import AST.
In the case that it cannot appear within curlies then it must be a new special "kind". Options for that would be: "*", "star", "all", "whole", "module". Or something along those lines.
Having it able to appear in curlies complicates things some despite my opinion that it's useful.
I'm looking at adding the following test:
'import * as crypto from "crypto"': {
type: 'ImportDeclaration',
specifiers: [{
type: 'ImportBatchSpecifier',
id: {
type: 'Identifier',
name: 'crypto',
range: [12, 18],
loc: {
start: { line: 1, column: 12 },
end: { line: 1, column: 18 }
}
},
name: null,
range: [12, 18],
loc: {
start: { line: 1, column: 12 },
end: { line: 1, column: 18 }
}
}],
kind: 'batch',
source: {
type: 'Literal',
value: 'crypto',
raw: '"crypto"',
range: [24, 32],
loc: {
start: { line: 1, column: 24 },
end: { line: 1, column: 32 }
}
},
range: [0, 32],
loc: {
start: { line: 1, column: 0 },
end: { line: 1, column: 32 }
}
}
I borrowed the batch terminology from export *
. Still not sure if it should be a specifier or there should be special-case parsing similar to default imports. Currently no specifier other than export *
contains a non-identifier.
Because that's not what's in the spec
From: Matthew Robbmailto:notifications@github.com Sent: ý2014-ý08-ý23 11:40 To: esnext/es6-module-transpilermailto:es6-module-transpiler@noreply.github.com Cc: Domenic Denicolamailto:domenic@domenicdenicola.com Subject: Re: [es6-module-transpiler] Support ES6-specified whole-module import syntax. (#119)
@domenichttps://github.com/domenic @caridyhttps://github.com/caridy Is there any reason you couldn't do
import { * as foo } from "foo";
It seems like it actually makes more sense but beside that it would be nice to be able to import some named imports and then import the rest to a single identifier.
import {
— Reply to this email directly or view it on GitHubhttps://github.com/esnext/es6-module-transpiler/issues/119#issuecomment-53156354.
recommendations:
kind
equal binding
instead of default
or batch
since you can't combine them.specifier
instead of specifiers
since you can have only one specifier when using the * as
syntax.This has landed in v0.9.0. See the editor for a demo.
Currently fails parsing. My current workaround requires in everything named and then re-exports it as default: