diff --git a/doc/modules.md b/doc/modules.md index 7e82c98fd2..1050c601c8 100644 --- a/doc/modules.md +++ b/doc/modules.md @@ -51,6 +51,69 @@ var test = 5; exports.test = test; exports.default = test; ``` +### Common interop + +**In** + +```javascript +import "foo"; + +import foo from "foo"; +import * as foo from "foo"; + +import {bar} from "foo"; +import {foo as bar} from "foo"; + +export {test}; +export var test = 5; + +export default test; +``` + +**Out** + +```javascript +var _interopRequire = function (obj) { + return obj && (obj["default"] || obj); +}; + +require("foo"); + +var foo = _interopRequire(require("foo")); +var foo = require("foo"); + +var bar = require("foo").bar; +var bar = require("foo").foo; + +exports.test = test; +var test = exports.test = 5; + +exports["default"] = test; +``` + +#### module.exports behaviour + +If there exist no other non-default `export`s then `default exports` are +exported as `module.exports` instead of `exports.default`. + +**In** + +```javascript +export default function foo() { + +} +``` + +**Out** + +```javascript +module.exports = foo; + +function foo() { + +} +``` + ### AMD **In** diff --git a/lib/6to5/templates/exports-default-module.js b/lib/6to5/templates/exports-default-module.js new file mode 100644 index 0000000000..d10890f8a2 --- /dev/null +++ b/lib/6to5/templates/exports-default-module.js @@ -0,0 +1 @@ +module.exports = VALUE; diff --git a/lib/6to5/transformation/modules/common-interop.js b/lib/6to5/transformation/modules/common-interop.js index 2e8ceafa0e..ad378606c0 100644 --- a/lib/6to5/transformation/modules/common-interop.js +++ b/lib/6to5/transformation/modules/common-interop.js @@ -3,9 +3,11 @@ module.exports = CommonJSInteropFormatter; var CommonJSFormatter = require("./common"); var util = require("../../util"); var t = require("../../types"); +var _ = require("lodash"); function CommonJSInteropFormatter(file) { - this.file = file; + this.has = false; + CommonJSFormatter.apply(this, arguments); } util.inherits(CommonJSInteropFormatter, CommonJSFormatter); @@ -26,3 +28,27 @@ CommonJSInteropFormatter.prototype.importSpecifier = function (specifier, node, CommonJSFormatter.prototype.importSpecifier.apply(this, arguments); } }; + +CommonJSInteropFormatter.prototype.export = function (node, nodes, parent) { + if (node.default && !this.has) { + var declar = node.declaration; + + // module.exports = VALUE; + var assign = util.template("exports-default-module", { + VALUE: this._pushStatement(declar, nodes) + }, true); + + // hoist to the top if this default is a function + nodes.push(this._hoistExport(declar, assign)); + return; + } else { + this.has = true; + } + + CommonJSFormatter.prototype.export.apply(this, arguments); +}; + +CommonJSInteropFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { + this.has = true; + CommonJSFormatter.prototype.exportSpecifier.apply(this, arguments); +}; diff --git a/lib/6to5/transformation/modules/common.js b/lib/6to5/transformation/modules/common.js index b4950484b3..09dbb78816 100644 --- a/lib/6to5/transformation/modules/common.js +++ b/lib/6to5/transformation/modules/common.js @@ -38,23 +38,32 @@ CommonJSFormatter.prototype.importSpecifier = function (specifier, node, nodes) })); }; +CommonJSFormatter.prototype._hoistExport = function (declar, assign) { + if (t.isFunctionDeclaration(declar)) { + assign._blockHoist = true; + } + + return assign; +}; + +CommonJSFormatter.prototype._pushStatement = function (ref, nodes) { + if (t.isClass(ref) || t.isFunction(ref)) { + if (ref.id) { + nodes.push(t.toStatement(ref)); + ref = ref.id; + } + } + return ref; +}; + CommonJSFormatter.prototype.export = function (node, nodes) { var declar = node.declaration; if (node.default) { - var ref = declar; - - if (t.isClass(ref) || t.isFunction(ref)) { - if (ref.id) { - nodes.push(t.toStatement(ref)); - ref = ref.id; - } - } - nodes.push(util.template("exports-default", { //inherits: node, - VALUE: ref + VALUE: this._pushStatement(declar, nodes) }, true)); } else { var assign; @@ -83,9 +92,7 @@ CommonJSFormatter.prototype.export = function (node, nodes) { nodes.push(t.toStatement(declar)); nodes.push(assign); - if (t.isFunctionDeclaration(declar)) { - assign._blockHoist = true; - } + this._hoistExport(declar, assign); } } }; @@ -126,7 +133,7 @@ CommonJSFormatter.prototype._exportSpecifier = function (getRef, specifier, node }; CommonJSFormatter.prototype.exportSpecifier = function (specifier, node, nodes) { - return this._exportSpecifier(function () { + this._exportSpecifier(function () { return t.callExpression(t.identifier("require"), [node.source]); }, specifier, node, nodes); }; diff --git a/lib/6to5/transformation/transformers/es6-modules.js b/lib/6to5/transformation/transformers/es6-modules.js index c93aab04bc..cfcd991f5c 100644 --- a/lib/6to5/transformation/transformers/es6-modules.js +++ b/lib/6to5/transformation/transformers/es6-modules.js @@ -5,10 +5,10 @@ exports.ImportDeclaration = function (node, parent, file) { if (node.specifiers.length) { _.each(node.specifiers, function (specifier) { - file.moduleFormatter.importSpecifier(specifier, node, nodes); + file.moduleFormatter.importSpecifier(specifier, node, nodes, parent); }); } else { - file.moduleFormatter.import(node, nodes); + file.moduleFormatter.import(node, nodes, parent); } return nodes; @@ -18,10 +18,10 @@ exports.ExportDeclaration = function (node, parent, file) { var nodes = []; if (node.declaration) { - file.moduleFormatter.export(node, nodes); + file.moduleFormatter.export(node, nodes, parent); } else { _.each(node.specifiers, function (specifier) { - file.moduleFormatter.exportSpecifier(specifier, node, nodes); + file.moduleFormatter.exportSpecifier(specifier, node, nodes, parent); }); } diff --git a/test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js b/test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js index 9a3b8194a0..a73e640e16 100644 --- a/test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js +++ b/test/fixtures/transformation/es6-modules-common-interop/exports-default/expected.js @@ -1,13 +1,13 @@ "use strict"; -exports["default"] = 42; -exports["default"] = {}; -exports["default"] = []; -exports["default"] = foo; -exports["default"] = function () {}; -exports["default"] = function () {}; +module.exports = foo; +module.exports = 42; +module.exports = {}; +module.exports = []; +module.exports = foo; +module.exports = function () {}; +module.exports = function () {}; function foo() {} -exports["default"] = foo; var Foo = function Foo() {}; -exports["default"] = Foo; +module.exports = Foo; diff --git a/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js b/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js index 744eae39ec..2a41ca5ca2 100644 --- a/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js +++ b/test/fixtures/transformation/es6-rest-parameters/arrow-functions/expected.js @@ -1,6 +1,5 @@ "use strict"; -var _arguments = arguments; var _argumentsToArray = function (args) { var target = new Array(args.length); for (var i = 0; i < args.length; i++) { @@ -11,5 +10,5 @@ var _argumentsToArray = function (args) { }; var concat = function () { - var arrs = _argumentsToArray(_arguments); + var arrs = _argumentsToArray(arguments); };