Skip to content

Commit

Permalink
Tolerate undeclared exports until @babel/parser@7.5.0 is released.
Browse files Browse the repository at this point in the history
babel/babel#9864

This hack narrowly targets @babel/parser@7.4.x by tricking
Array.from(this.scope.undefinedExports) into returning an empty array,
thereby simulating the effect of enabling the allowUndeclaredExports
option (which will become available in @babel/parser@7.5.0).
  • Loading branch information
benjamn committed Jun 20, 2019
1 parent 7aa8992 commit e168ffd
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 10 deletions.
35 changes: 25 additions & 10 deletions lib/parsers/babel.js
@@ -1,18 +1,13 @@
"use strict";

// Prefer the new @babel/parser package, but fall back to babylon if
// that's what's available.
const babelParser = function () {
try {
return require("@babel/parser");
} catch (e) {
return require("babylon");
}
}();
const babelParser = require("@babel/parser");
const babelParserVersion = require("@babel/parser/package.json").version;

exports.options = {
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
// This won't work until @babel/parser@7.5.0 is released.
allowUndeclaredExports: true,
plugins: [
"*", "flow", "jsx",
// The "*" glob no longer seems to include the following plugins:
Expand Down Expand Up @@ -55,4 +50,24 @@ function parse(code) {
return babelParser.parse(code, exports.options);
}

exports.parse = parse;
function tolerantParse(code) {
const arrayFrom = Array.from;
// There is only one use of Array.from in the @babel/parser@7.4.x code,
// Array.from(this.scope.undefinedExports), which determines whether the
// parser complains prematurely about exporting identifiers that were
// not declared in the current module scope. By returning an empty array
// when the source argument is a Map, we can effectively disable that
// error behavior, until https://github.com/babel/babel/pull/9864 is
// released in @babel/parser@7.5.0.
Array.from = function (source) {
return source instanceof Map ? [] :
arrayFrom.apply(this, arguments);
};
try {
return parse(code);
} finally {
Array.from = arrayFrom;
}
}

exports.parse = babelParserVersion.startsWith("7.4.") ? tolerantParse : parse;
5 changes: 5 additions & 0 deletions test/export-tests.js
Expand Up @@ -317,4 +317,9 @@ describe("export declarations", () => {
"from-ordering-c.js",
]);
});

it("should be tolerant of exporting undeclared identifiers", () => {
import { GlobalArray } from "./undeclared-export.js";
assert.strictEqual(GlobalArray, Array);
});
});
1 change: 1 addition & 0 deletions test/undeclared-export.js
@@ -0,0 +1 @@
export { Array as GlobalArray }

0 comments on commit e168ffd

Please sign in to comment.