Added babel-helper-split-export-declaration (#7313)
This commit is contained in:
parent
ea3f2d9299
commit
4d164bd8e6
@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-module-imports": "7.0.0-beta.40",
|
"@babel/helper-module-imports": "7.0.0-beta.40",
|
||||||
"@babel/helper-simple-access": "7.0.0-beta.40",
|
"@babel/helper-simple-access": "7.0.0-beta.40",
|
||||||
|
"@babel/helper-split-export-declaration": "7.0.0-beta.40",
|
||||||
"@babel/template": "7.0.0-beta.40",
|
"@babel/template": "7.0.0-beta.40",
|
||||||
"@babel/types": "7.0.0-beta.40",
|
"@babel/types": "7.0.0-beta.40",
|
||||||
"lodash": "^4.2.0"
|
"lodash": "^4.2.0"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { basename, extname } from "path";
|
import { basename, extname } from "path";
|
||||||
|
|
||||||
import * as t from "@babel/types";
|
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||||
|
|
||||||
export type ModuleMetadata = {
|
export type ModuleMetadata = {
|
||||||
exportName: string,
|
exportName: string,
|
||||||
@ -399,35 +399,7 @@ function nameAnonymousExports(programPath: NodePath) {
|
|||||||
// Name anonymous exported locals.
|
// Name anonymous exported locals.
|
||||||
programPath.get("body").forEach(child => {
|
programPath.get("body").forEach(child => {
|
||||||
if (!child.isExportDefaultDeclaration()) return;
|
if (!child.isExportDefaultDeclaration()) return;
|
||||||
|
splitExportDeclaration(child);
|
||||||
// export default foo;
|
|
||||||
const declaration = child.get("declaration");
|
|
||||||
if (declaration.isFunctionDeclaration()) {
|
|
||||||
if (!declaration.node.id) {
|
|
||||||
declaration.node.id = declaration.scope.generateUidIdentifier(
|
|
||||||
"default",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (declaration.isClassDeclaration()) {
|
|
||||||
if (!declaration.node.id) {
|
|
||||||
declaration.node.id = declaration.scope.generateUidIdentifier(
|
|
||||||
"default",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const id = declaration.scope.generateUidIdentifier("default");
|
|
||||||
const namedDecl = t.exportNamedDeclaration(null, [
|
|
||||||
t.exportSpecifier(t.identifier(id.name), t.identifier("default")),
|
|
||||||
]);
|
|
||||||
namedDecl._blockHoist = child.node._blockHoist;
|
|
||||||
|
|
||||||
const varDecl = t.variableDeclaration("var", [
|
|
||||||
t.variableDeclarator(id, declaration.node),
|
|
||||||
]);
|
|
||||||
varDecl._blockHoist = child.node._blockHoist;
|
|
||||||
|
|
||||||
child.replaceWithMultiple([namedDecl, varDecl]);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -112,6 +112,7 @@ const rewriteBindingInitVisitor = {
|
|||||||
|
|
||||||
Object.keys(path.getOuterBindingIdentifiers()).forEach(localName => {
|
Object.keys(path.getOuterBindingIdentifiers()).forEach(localName => {
|
||||||
const exportNames = exported.get(localName) || [];
|
const exportNames = exported.get(localName) || [];
|
||||||
|
|
||||||
if (exportNames.length > 0) {
|
if (exportNames.length > 0) {
|
||||||
const statement = t.expressionStatement(
|
const statement = t.expressionStatement(
|
||||||
buildBindingExportAssignmentExpression(
|
buildBindingExportAssignmentExpression(
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
src
|
||||||
|
test
|
||||||
|
*.log
|
||||||
23
packages/babel-helper-split-export-declaration/README.md
Normal file
23
packages/babel-helper-split-export-declaration/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# @babel/helper-split-export-declaration
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
```js
|
||||||
|
declare export default splitExportDeclaration(path: NodePath);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```js
|
||||||
|
import traverse from "@babel/traverse";
|
||||||
|
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
traverse(file, {
|
||||||
|
ExportDefaultDeclaration(path) {
|
||||||
|
if (!path.get("declaration").isClassDeclaration()) return;
|
||||||
|
splitExportDeclaration(path);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
11
packages/babel-helper-split-export-declaration/package.json
Normal file
11
packages/babel-helper-split-export-declaration/package.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "@babel/helper-split-export-declaration",
|
||||||
|
"version": "7.0.0-beta.40",
|
||||||
|
"description": "",
|
||||||
|
"repository": "https://github.com/babel/babel/tree/master/packages/babel-helper-split-export-declaration",
|
||||||
|
"license": "MIT",
|
||||||
|
"main": "lib/index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/types": "7.0.0-beta.40"
|
||||||
|
}
|
||||||
|
}
|
||||||
76
packages/babel-helper-split-export-declaration/src/index.js
Normal file
76
packages/babel-helper-split-export-declaration/src/index.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
|
export default function splitExportDeclaration(exportDeclaration) {
|
||||||
|
if (!exportDeclaration.isExportDeclaration()) {
|
||||||
|
throw new Error("Only export declarations can be splitted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// build specifiers that point back to this export declaration
|
||||||
|
const isDefault = exportDeclaration.isExportDefaultDeclaration();
|
||||||
|
const declaration = exportDeclaration.get("declaration");
|
||||||
|
const isClassDeclaration = declaration.isClassDeclaration();
|
||||||
|
|
||||||
|
if (isDefault) {
|
||||||
|
const standaloneDeclaration =
|
||||||
|
declaration.isFunctionDeclaration() || isClassDeclaration;
|
||||||
|
|
||||||
|
const scope = declaration.isScope()
|
||||||
|
? declaration.scope.parent
|
||||||
|
: declaration.scope;
|
||||||
|
|
||||||
|
let id = declaration.node.id;
|
||||||
|
let needBindingRegistration = false;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
needBindingRegistration = true;
|
||||||
|
|
||||||
|
id = scope.generateUidIdentifier("default");
|
||||||
|
|
||||||
|
if (
|
||||||
|
standaloneDeclaration ||
|
||||||
|
declaration.isFunctionExpression() ||
|
||||||
|
declaration.isClassExpression()
|
||||||
|
) {
|
||||||
|
declaration.node.id = t.cloneNode(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedDeclaration = standaloneDeclaration
|
||||||
|
? declaration
|
||||||
|
: t.variableDeclaration("var", [
|
||||||
|
t.variableDeclarator(t.cloneNode(id), declaration.node),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const updatedExportDeclaration = t.exportNamedDeclaration(null, [
|
||||||
|
t.exportSpecifier(t.cloneNode(id), t.identifier("default")),
|
||||||
|
]);
|
||||||
|
|
||||||
|
exportDeclaration.insertAfter(updatedExportDeclaration);
|
||||||
|
exportDeclaration.replaceWith(updatedDeclaration);
|
||||||
|
|
||||||
|
if (needBindingRegistration) {
|
||||||
|
scope.registerBinding(
|
||||||
|
isClassDeclaration ? "let" : "var",
|
||||||
|
exportDeclaration,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exportDeclaration;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exportDeclaration.get("specifiers").length > 0) {
|
||||||
|
throw new Error("It doesn't make sense to split exported specifiers.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const bindingIdentifiers = declaration.getOuterBindingIdentifiers();
|
||||||
|
|
||||||
|
const specifiers = Object.keys(bindingIdentifiers).map(name => {
|
||||||
|
return t.exportSpecifier(t.identifier(name), t.identifier(name));
|
||||||
|
});
|
||||||
|
|
||||||
|
const aliasDeclar = t.exportNamedDeclaration(null, specifiers);
|
||||||
|
|
||||||
|
exportDeclaration.insertAfter(aliasDeclar);
|
||||||
|
exportDeclaration.replaceWith(declaration.node);
|
||||||
|
return exportDeclaration;
|
||||||
|
}
|
||||||
@ -9,15 +9,15 @@ call((_temp = _class = function _class() {
|
|||||||
value: true
|
value: true
|
||||||
}), _temp));
|
}), _temp));
|
||||||
|
|
||||||
var _class2 = function _class2() {
|
var _default = function _default() {
|
||||||
babelHelpers.classCallCheck(this, _class2);
|
babelHelpers.classCallCheck(this, _default);
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.defineProperty(_class2, "test", {
|
Object.defineProperty(_default, "test", {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
writable: true,
|
writable: true,
|
||||||
value: true
|
value: true
|
||||||
});
|
});
|
||||||
export { _class2 as default };
|
export { _default as default };
|
||||||
;
|
;
|
||||||
|
|||||||
@ -4,10 +4,10 @@ call((_temp = _class = function _class() {
|
|||||||
babelHelpers.classCallCheck(this, _class);
|
babelHelpers.classCallCheck(this, _class);
|
||||||
}, _class.test = true, _temp));
|
}, _class.test = true, _temp));
|
||||||
|
|
||||||
var _class2 = function _class2() {
|
var _default = function _default() {
|
||||||
babelHelpers.classCallCheck(this, _class2);
|
babelHelpers.classCallCheck(this, _default);
|
||||||
};
|
};
|
||||||
|
|
||||||
_class2.test = true;
|
_default.test = true;
|
||||||
export { _class2 as default };
|
export { _default as default };
|
||||||
;
|
;
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
"@babel/helper-function-name": "7.0.0-beta.40",
|
"@babel/helper-function-name": "7.0.0-beta.40",
|
||||||
"@babel/helper-optimise-call-expression": "7.0.0-beta.40",
|
"@babel/helper-optimise-call-expression": "7.0.0-beta.40",
|
||||||
"@babel/helper-replace-supers": "7.0.0-beta.40",
|
"@babel/helper-replace-supers": "7.0.0-beta.40",
|
||||||
|
"@babel/helper-split-export-declaration": "7.0.0-beta.40",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import LooseTransformer from "./loose";
|
|||||||
import VanillaTransformer from "./vanilla";
|
import VanillaTransformer from "./vanilla";
|
||||||
import annotateAsPure from "@babel/helper-annotate-as-pure";
|
import annotateAsPure from "@babel/helper-annotate-as-pure";
|
||||||
import nameFunction from "@babel/helper-function-name";
|
import nameFunction from "@babel/helper-function-name";
|
||||||
|
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||||
import { types as t } from "@babel/core";
|
import { types as t } from "@babel/core";
|
||||||
import globals from "globals";
|
import globals from "globals";
|
||||||
|
|
||||||
@ -24,19 +25,7 @@ export default function(api, options) {
|
|||||||
visitor: {
|
visitor: {
|
||||||
ExportDefaultDeclaration(path) {
|
ExportDefaultDeclaration(path) {
|
||||||
if (!path.get("declaration").isClassDeclaration()) return;
|
if (!path.get("declaration").isClassDeclaration()) return;
|
||||||
|
splitExportDeclaration(path);
|
||||||
const { node } = path;
|
|
||||||
const ref =
|
|
||||||
node.declaration.id || path.scope.generateUidIdentifier("class");
|
|
||||||
node.declaration.id = ref;
|
|
||||||
|
|
||||||
// Split the class declaration and the export into two separate statements.
|
|
||||||
path.replaceWith(node.declaration);
|
|
||||||
path.insertAfter(
|
|
||||||
t.exportNamedDeclaration(null, [
|
|
||||||
t.exportSpecifier(t.cloneNode(ref), t.identifier("default")),
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ClassDeclaration(path) {
|
ClassDeclaration(path) {
|
||||||
|
|||||||
@ -5,8 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|||||||
});
|
});
|
||||||
exports.default = void 0;
|
exports.default = void 0;
|
||||||
|
|
||||||
var _class = function _class() {
|
var _default = function _default() {
|
||||||
babelHelpers.classCallCheck(this, _class);
|
babelHelpers.classCallCheck(this, _default);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.default = _class;
|
exports.default = _default;
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
var _class =
|
var _default =
|
||||||
/*#__PURE__*/
|
/*#__PURE__*/
|
||||||
function (_A) {
|
function (_A) {
|
||||||
babelHelpers.inherits(_class, _A);
|
babelHelpers.inherits(_default, _A);
|
||||||
|
|
||||||
function _class() {
|
function _default() {
|
||||||
babelHelpers.classCallCheck(this, _class);
|
babelHelpers.classCallCheck(this, _default);
|
||||||
return babelHelpers.possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments));
|
return babelHelpers.possibleConstructorReturn(this, (_default.__proto__ || Object.getPrototypeOf(_default)).apply(this, arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _class;
|
return _default;
|
||||||
}(A);
|
}(A);
|
||||||
|
|
||||||
export { _class as default };
|
export { _default as default };
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
export { _whatever as whatever };
|
|
||||||
export { _wowzers as default };
|
|
||||||
var _foo = "yes",
|
var _foo = "yes",
|
||||||
foob = "no";
|
foob = "no";
|
||||||
export { _foo as foo, foob };
|
export { _foo as foo, foob };
|
||||||
|
|
||||||
function _whatever() {}
|
function _whatever() {}
|
||||||
|
|
||||||
|
export { _whatever as whatever };
|
||||||
|
|
||||||
function _wowzers() {}
|
function _wowzers() {}
|
||||||
|
|
||||||
|
export { _wowzers as default };
|
||||||
var bar = {
|
var bar = {
|
||||||
foo: function foo() {
|
foo: function foo() {
|
||||||
_foo;
|
_foo;
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
export { _foo as foo };
|
|
||||||
|
|
||||||
function _foo(bar) {}
|
function _foo(bar) {}
|
||||||
|
|
||||||
|
export { _foo as foo };
|
||||||
var bar = {
|
var bar = {
|
||||||
foo: function foo() {
|
foo: function foo() {
|
||||||
_foo;
|
_foo;
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
"@babel/code-frame": "7.0.0-beta.40",
|
"@babel/code-frame": "7.0.0-beta.40",
|
||||||
"@babel/generator": "7.0.0-beta.40",
|
"@babel/generator": "7.0.0-beta.40",
|
||||||
"@babel/helper-function-name": "7.0.0-beta.40",
|
"@babel/helper-function-name": "7.0.0-beta.40",
|
||||||
|
"@babel/helper-split-export-declaration": "7.0.0-beta.40",
|
||||||
"@babel/types": "7.0.0-beta.40",
|
"@babel/types": "7.0.0-beta.40",
|
||||||
"babylon": "7.0.0-beta.40",
|
"babylon": "7.0.0-beta.40",
|
||||||
"debug": "^3.0.1",
|
"debug": "^3.0.1",
|
||||||
|
|||||||
@ -210,7 +210,7 @@ export default class Scope {
|
|||||||
* Generate a unique identifier and add it to the current scope.
|
* Generate a unique identifier and add it to the current scope.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
generateDeclaredUidIdentifier(name: string = "temp") {
|
generateDeclaredUidIdentifier(name?: string) {
|
||||||
const id = this.generateUidIdentifier(name);
|
const id = this.generateUidIdentifier(name);
|
||||||
this.push({ id });
|
this.push({ id });
|
||||||
return t.cloneNode(id);
|
return t.cloneNode(id);
|
||||||
@ -220,7 +220,7 @@ export default class Scope {
|
|||||||
* Generate a unique identifier.
|
* Generate a unique identifier.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
generateUidIdentifier(name: string = "temp") {
|
generateUidIdentifier(name?: string) {
|
||||||
return t.identifier(this.generateUid(name));
|
return t.identifier(this.generateUid(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import Binding from "../binding";
|
import Binding from "../binding";
|
||||||
|
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||||
import * as t from "@babel/types";
|
import * as t from "@babel/types";
|
||||||
|
|
||||||
const renameVisitor = {
|
const renameVisitor = {
|
||||||
@ -40,48 +41,20 @@ export default class Renamer {
|
|||||||
binding: Binding;
|
binding: Binding;
|
||||||
|
|
||||||
maybeConvertFromExportDeclaration(parentDeclar) {
|
maybeConvertFromExportDeclaration(parentDeclar) {
|
||||||
const exportDeclar =
|
const maybeExportDeclar = parentDeclar.parentPath;
|
||||||
parentDeclar.parentPath.isExportDeclaration() && parentDeclar.parentPath;
|
|
||||||
if (!exportDeclar) return;
|
|
||||||
|
|
||||||
// build specifiers that point back to this export declaration
|
if (!maybeExportDeclar.isExportDeclaration()) {
|
||||||
const isDefault = exportDeclar.isExportDefaultDeclaration();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isDefault &&
|
maybeExportDeclar.isExportDefaultDeclaration() &&
|
||||||
(parentDeclar.isFunctionDeclaration() ||
|
!maybeExportDeclar.get("declaration").node.id
|
||||||
parentDeclar.isClassDeclaration()) &&
|
|
||||||
!parentDeclar.node.id
|
|
||||||
) {
|
) {
|
||||||
// Ensure that default class and function exports have a name so they have a identifier to
|
return;
|
||||||
// reference from the export specifier list.
|
|
||||||
parentDeclar.node.id = parentDeclar.scope.generateUidIdentifier(
|
|
||||||
"default",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bindingIdentifiers = parentDeclar.getOuterBindingIdentifiers();
|
splitExportDeclaration(maybeExportDeclar);
|
||||||
const specifiers = [];
|
|
||||||
|
|
||||||
for (const name in bindingIdentifiers) {
|
|
||||||
const localName = name === this.oldName ? this.newName : name;
|
|
||||||
const exportedName = isDefault ? "default" : name;
|
|
||||||
specifiers.push(
|
|
||||||
t.exportSpecifier(t.identifier(localName), t.identifier(exportedName)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (specifiers.length) {
|
|
||||||
const aliasDeclar = t.exportNamedDeclaration(null, specifiers);
|
|
||||||
|
|
||||||
// hoist to the top if it's a function
|
|
||||||
if (parentDeclar.isFunctionDeclaration()) {
|
|
||||||
aliasDeclar._blockHoist = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
exportDeclar.insertAfter(aliasDeclar);
|
|
||||||
exportDeclar.replaceWith(parentDeclar.node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
maybeConvertFromClassFunctionDeclaration(path) {
|
maybeConvertFromClassFunctionDeclaration(path) {
|
||||||
@ -129,7 +102,10 @@ export default class Renamer {
|
|||||||
const { scope, path } = binding;
|
const { scope, path } = binding;
|
||||||
|
|
||||||
const parentDeclar = path.find(
|
const parentDeclar = path.find(
|
||||||
path => path.isDeclaration() || path.isFunctionExpression(),
|
path =>
|
||||||
|
path.isDeclaration() ||
|
||||||
|
path.isFunctionExpression() ||
|
||||||
|
path.isClassExpression(),
|
||||||
);
|
);
|
||||||
if (parentDeclar) {
|
if (parentDeclar) {
|
||||||
this.maybeConvertFromExportDeclaration(parentDeclar);
|
this.maybeConvertFromExportDeclaration(parentDeclar);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user