Added babel-helper-split-export-declaration (#7313)
This commit is contained in:
parent
ea3f2d9299
commit
4d164bd8e6
@ -10,6 +10,7 @@
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "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/types": "7.0.0-beta.40",
|
||||
"lodash": "^4.2.0"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { basename, extname } from "path";
|
||||
|
||||
import * as t from "@babel/types";
|
||||
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||
|
||||
export type ModuleMetadata = {
|
||||
exportName: string,
|
||||
@ -399,35 +399,7 @@ function nameAnonymousExports(programPath: NodePath) {
|
||||
// Name anonymous exported locals.
|
||||
programPath.get("body").forEach(child => {
|
||||
if (!child.isExportDefaultDeclaration()) return;
|
||||
|
||||
// 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]);
|
||||
}
|
||||
splitExportDeclaration(child);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -112,6 +112,7 @@ const rewriteBindingInitVisitor = {
|
||||
|
||||
Object.keys(path.getOuterBindingIdentifiers()).forEach(localName => {
|
||||
const exportNames = exported.get(localName) || [];
|
||||
|
||||
if (exportNames.length > 0) {
|
||||
const statement = t.expressionStatement(
|
||||
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
|
||||
}), _temp));
|
||||
|
||||
var _class2 = function _class2() {
|
||||
babelHelpers.classCallCheck(this, _class2);
|
||||
var _default = function _default() {
|
||||
babelHelpers.classCallCheck(this, _default);
|
||||
};
|
||||
|
||||
Object.defineProperty(_class2, "test", {
|
||||
Object.defineProperty(_default, "test", {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: true
|
||||
});
|
||||
export { _class2 as default };
|
||||
export { _default as default };
|
||||
;
|
||||
|
||||
@ -4,10 +4,10 @@ call((_temp = _class = function _class() {
|
||||
babelHelpers.classCallCheck(this, _class);
|
||||
}, _class.test = true, _temp));
|
||||
|
||||
var _class2 = function _class2() {
|
||||
babelHelpers.classCallCheck(this, _class2);
|
||||
var _default = function _default() {
|
||||
babelHelpers.classCallCheck(this, _default);
|
||||
};
|
||||
|
||||
_class2.test = true;
|
||||
export { _class2 as default };
|
||||
_default.test = true;
|
||||
export { _default as default };
|
||||
;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
"@babel/helper-function-name": "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-split-export-declaration": "7.0.0-beta.40",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
@ -2,6 +2,7 @@ import LooseTransformer from "./loose";
|
||||
import VanillaTransformer from "./vanilla";
|
||||
import annotateAsPure from "@babel/helper-annotate-as-pure";
|
||||
import nameFunction from "@babel/helper-function-name";
|
||||
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||
import { types as t } from "@babel/core";
|
||||
import globals from "globals";
|
||||
|
||||
@ -24,19 +25,7 @@ export default function(api, options) {
|
||||
visitor: {
|
||||
ExportDefaultDeclaration(path) {
|
||||
if (!path.get("declaration").isClassDeclaration()) return;
|
||||
|
||||
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")),
|
||||
]),
|
||||
);
|
||||
splitExportDeclaration(path);
|
||||
},
|
||||
|
||||
ClassDeclaration(path) {
|
||||
|
||||
@ -5,8 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
||||
});
|
||||
exports.default = void 0;
|
||||
|
||||
var _class = function _class() {
|
||||
babelHelpers.classCallCheck(this, _class);
|
||||
var _default = function _default() {
|
||||
babelHelpers.classCallCheck(this, _default);
|
||||
};
|
||||
|
||||
exports.default = _class;
|
||||
exports.default = _default;
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
var _class =
|
||||
var _default =
|
||||
/*#__PURE__*/
|
||||
function (_A) {
|
||||
babelHelpers.inherits(_class, _A);
|
||||
babelHelpers.inherits(_default, _A);
|
||||
|
||||
function _class() {
|
||||
babelHelpers.classCallCheck(this, _class);
|
||||
return babelHelpers.possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments));
|
||||
function _default() {
|
||||
babelHelpers.classCallCheck(this, _default);
|
||||
return babelHelpers.possibleConstructorReturn(this, (_default.__proto__ || Object.getPrototypeOf(_default)).apply(this, arguments));
|
||||
}
|
||||
|
||||
return _class;
|
||||
return _default;
|
||||
}(A);
|
||||
|
||||
export { _class as default };
|
||||
export { _default as default };
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
export { _whatever as whatever };
|
||||
export { _wowzers as default };
|
||||
var _foo = "yes",
|
||||
foob = "no";
|
||||
export { _foo as foo, foob };
|
||||
|
||||
function _whatever() {}
|
||||
|
||||
export { _whatever as whatever };
|
||||
|
||||
function _wowzers() {}
|
||||
|
||||
export { _wowzers as default };
|
||||
var bar = {
|
||||
foo: function foo() {
|
||||
_foo;
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
export { _foo as foo };
|
||||
|
||||
function _foo(bar) {}
|
||||
|
||||
export { _foo as foo };
|
||||
var bar = {
|
||||
foo: function foo() {
|
||||
_foo;
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
"@babel/code-frame": "7.0.0-beta.40",
|
||||
"@babel/generator": "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",
|
||||
"babylon": "7.0.0-beta.40",
|
||||
"debug": "^3.0.1",
|
||||
|
||||
@ -210,7 +210,7 @@ export default class Scope {
|
||||
* Generate a unique identifier and add it to the current scope.
|
||||
*/
|
||||
|
||||
generateDeclaredUidIdentifier(name: string = "temp") {
|
||||
generateDeclaredUidIdentifier(name?: string) {
|
||||
const id = this.generateUidIdentifier(name);
|
||||
this.push({ id });
|
||||
return t.cloneNode(id);
|
||||
@ -220,7 +220,7 @@ export default class Scope {
|
||||
* Generate a unique identifier.
|
||||
*/
|
||||
|
||||
generateUidIdentifier(name: string = "temp") {
|
||||
generateUidIdentifier(name?: string) {
|
||||
return t.identifier(this.generateUid(name));
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import Binding from "../binding";
|
||||
import splitExportDeclaration from "@babel/helper-split-export-declaration";
|
||||
import * as t from "@babel/types";
|
||||
|
||||
const renameVisitor = {
|
||||
@ -40,48 +41,20 @@ export default class Renamer {
|
||||
binding: Binding;
|
||||
|
||||
maybeConvertFromExportDeclaration(parentDeclar) {
|
||||
const exportDeclar =
|
||||
parentDeclar.parentPath.isExportDeclaration() && parentDeclar.parentPath;
|
||||
if (!exportDeclar) return;
|
||||
const maybeExportDeclar = parentDeclar.parentPath;
|
||||
|
||||
// build specifiers that point back to this export declaration
|
||||
const isDefault = exportDeclar.isExportDefaultDeclaration();
|
||||
if (!maybeExportDeclar.isExportDeclaration()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
isDefault &&
|
||||
(parentDeclar.isFunctionDeclaration() ||
|
||||
parentDeclar.isClassDeclaration()) &&
|
||||
!parentDeclar.node.id
|
||||
maybeExportDeclar.isExportDefaultDeclaration() &&
|
||||
!maybeExportDeclar.get("declaration").node.id
|
||||
) {
|
||||
// Ensure that default class and function exports have a name so they have a identifier to
|
||||
// reference from the export specifier list.
|
||||
parentDeclar.node.id = parentDeclar.scope.generateUidIdentifier(
|
||||
"default",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const bindingIdentifiers = parentDeclar.getOuterBindingIdentifiers();
|
||||
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);
|
||||
}
|
||||
splitExportDeclaration(maybeExportDeclar);
|
||||
}
|
||||
|
||||
maybeConvertFromClassFunctionDeclaration(path) {
|
||||
@ -129,7 +102,10 @@ export default class Renamer {
|
||||
const { scope, path } = binding;
|
||||
|
||||
const parentDeclar = path.find(
|
||||
path => path.isDeclaration() || path.isFunctionExpression(),
|
||||
path =>
|
||||
path.isDeclaration() ||
|
||||
path.isFunctionExpression() ||
|
||||
path.isClassExpression(),
|
||||
);
|
||||
if (parentDeclar) {
|
||||
this.maybeConvertFromExportDeclaration(parentDeclar);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user