Merge pull request #4892 from kaicataldo/babelrcjs
Add support for .babelrc.js files
This commit is contained in:
commit
02473a72c1
@ -1,4 +1,3 @@
|
||||
|
||||
import type Logger from "../logger";
|
||||
import resolve from "../../../helpers/resolve";
|
||||
import json5 from "json5";
|
||||
@ -8,9 +7,10 @@ import fs from "fs";
|
||||
const existsCache = {};
|
||||
const jsonCache = {};
|
||||
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
const BABELRC_FILENAME = ".babelrc";
|
||||
const BABELRC_JS_FILENAME = ".babelrc.js";
|
||||
const PACKAGE_FILENAME = "package.json";
|
||||
const BABELIGNORE_FILENAME = ".babelignore";
|
||||
|
||||
function exists(filename) {
|
||||
const cached = existsCache[filename];
|
||||
@ -46,7 +46,12 @@ class ConfigChainBuilder {
|
||||
this.log = log;
|
||||
}
|
||||
|
||||
findConfigs(loc) {
|
||||
errorMultipleConfigs(loc1: string, loc2: string) {
|
||||
throw new Error(`Multiple configuration files found. Please remove one:\n- ${
|
||||
loc1}\n- ${loc2}`);
|
||||
}
|
||||
|
||||
findConfigs(loc: string) {
|
||||
if (!loc) return;
|
||||
|
||||
if (!path.isAbsolute(loc)) {
|
||||
@ -59,15 +64,26 @@ class ConfigChainBuilder {
|
||||
while (loc !== (loc = path.dirname(loc))) {
|
||||
if (!foundConfig) {
|
||||
const configLoc = path.join(loc, BABELRC_FILENAME);
|
||||
if (exists(configLoc)) {
|
||||
this.addConfig(configLoc);
|
||||
foundConfig = true;
|
||||
}
|
||||
|
||||
const configJSLoc = path.join(loc, BABELRC_JS_FILENAME);
|
||||
const pkgLoc = path.join(loc, PACKAGE_FILENAME);
|
||||
if (!foundConfig && exists(pkgLoc)) {
|
||||
foundConfig = this.addConfig(pkgLoc, "babel", JSON);
|
||||
}
|
||||
const configLocs = [configLoc, configJSLoc, pkgLoc];
|
||||
const foundConfigs = configLocs.reduce((arr, config) => {
|
||||
if (exists(config)) {
|
||||
const configAdded = config === pkgLoc
|
||||
? this.addConfig(config, "babel", JSON)
|
||||
: this.addConfig(config);
|
||||
|
||||
if (configAdded && arr.length) {
|
||||
this.errorMultipleConfigs(arr.pop(), config);
|
||||
}
|
||||
|
||||
arr.push(config);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}, []);
|
||||
|
||||
foundConfig = !!foundConfigs.length;
|
||||
}
|
||||
|
||||
if (!foundIgnore) {
|
||||
@ -82,7 +98,7 @@ class ConfigChainBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
addIgnoreConfig(loc) {
|
||||
addIgnoreConfig(loc: string) {
|
||||
const file = fs.readFileSync(loc, "utf8");
|
||||
let lines = file.split("\n");
|
||||
|
||||
@ -106,15 +122,35 @@ class ConfigChainBuilder {
|
||||
|
||||
this.resolvedConfigs.push(loc);
|
||||
|
||||
const content = fs.readFileSync(loc, "utf8");
|
||||
let options;
|
||||
if (path.extname(loc) === ".js") {
|
||||
try {
|
||||
const configModule = require(loc);
|
||||
options = configModule && configModule.__esModule ? configModule.default : configModule;
|
||||
} catch (err) {
|
||||
err.message = `${loc}: Error while loading config - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
options = jsonCache[content] = jsonCache[content] || json.parse(content);
|
||||
if (key) options = options[key];
|
||||
} catch (err) {
|
||||
err.message = `${loc}: Error while parsing JSON - ${err.message}`;
|
||||
throw err;
|
||||
if (!options || typeof options !== "object") {
|
||||
throw new Error("Configuration should be an exported JavaScript object.");
|
||||
}
|
||||
} else {
|
||||
const content = fs.readFileSync(loc, "utf8");
|
||||
try {
|
||||
options = jsonCache[content] = jsonCache[content] || json.parse(content);
|
||||
} catch (err) {
|
||||
err.message = `${loc}: Error while parsing JSON - ${err.message}`;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
if (key) {
|
||||
if (!options[key]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
options = options[key];
|
||||
}
|
||||
|
||||
this.mergeConfig({
|
||||
|
||||
@ -294,4 +294,253 @@ describe("buildConfigChain", function () {
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("js-config", function () {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config", "src.js"),
|
||||
});
|
||||
|
||||
const expected = [
|
||||
{
|
||||
options: {
|
||||
plugins: [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
},
|
||||
alias: fixture("js-config", ".babelrc.js"),
|
||||
loc: fixture("js-config", ".babelrc.js"),
|
||||
dirname: fixture("js-config"),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
filename: fixture("js-config", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: fixture("js-config"),
|
||||
},
|
||||
];
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("js-config-default - should read transpiled export default", function () {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-default", "src.js"),
|
||||
});
|
||||
|
||||
const expected = [
|
||||
{
|
||||
options: {
|
||||
plugins: [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
},
|
||||
alias: fixture("js-config-default", ".babelrc.js"),
|
||||
loc: fixture("js-config-default", ".babelrc.js"),
|
||||
dirname: fixture("js-config-default"),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
filename: fixture("js-config-default", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: fixture("js-config-default"),
|
||||
},
|
||||
];
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
it("js-config-extended", function () {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("js-config-extended", "src.js"),
|
||||
});
|
||||
|
||||
const expected = [
|
||||
{
|
||||
options: {
|
||||
plugins: [
|
||||
"extended",
|
||||
],
|
||||
},
|
||||
alias: fixture("extended.babelrc.json"),
|
||||
loc: fixture("extended.babelrc.json"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
plugins: [
|
||||
"foo",
|
||||
"bar",
|
||||
],
|
||||
},
|
||||
alias: fixture("js-config-extended", ".babelrc.js"),
|
||||
loc: fixture("js-config-extended", ".babelrc.js"),
|
||||
dirname: fixture("js-config-extended"),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
filename: fixture("js-config-extended", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: fixture("js-config-extended"),
|
||||
},
|
||||
];
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("json-pkg-config-no-babel - should not throw if" +
|
||||
" package.json doesn't contain a `babel` field", function () {
|
||||
const chain = buildConfigChain({
|
||||
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
||||
});
|
||||
|
||||
const expected = [
|
||||
{
|
||||
options: {
|
||||
plugins: [
|
||||
"json",
|
||||
],
|
||||
},
|
||||
alias: fixture("json-pkg-config-no-babel", ".babelrc"),
|
||||
loc: fixture("json-pkg-config-no-babel", ".babelrc"),
|
||||
dirname: fixture("json-pkg-config-no-babel"),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
ignore: [
|
||||
"root-ignore",
|
||||
],
|
||||
},
|
||||
alias: fixture(".babelignore"),
|
||||
loc: fixture(".babelignore"),
|
||||
dirname: fixture(),
|
||||
},
|
||||
{
|
||||
options: {
|
||||
filename: fixture("json-pkg-config-no-babel", "src.js"),
|
||||
},
|
||||
alias: "base",
|
||||
loc: "base",
|
||||
dirname: fixture("json-pkg-config-no-babel"),
|
||||
},
|
||||
];
|
||||
|
||||
assert.deepEqual(chain, expected);
|
||||
});
|
||||
|
||||
it("js-json-config - should throw an error if both a .babelrc" +
|
||||
" and a .babelrc.js are present", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-json-config", "src.js"),
|
||||
});
|
||||
},
|
||||
/Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*\.babelrc\.js/
|
||||
);
|
||||
});
|
||||
|
||||
it("js-pkg-config - should throw an error if both a .babelrc.js" +
|
||||
" and a package.json with a babel field are present", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-pkg-config", "src.js"),
|
||||
});
|
||||
},
|
||||
/Multiple configuration files found\.(.|\n)*\.babelrc\.js(.|\n)*package\.json/
|
||||
);
|
||||
});
|
||||
|
||||
it("json-pkg-config - should throw an error if both a .babelrc" +
|
||||
" and a package.json with a babel field are present", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
buildConfigChain({
|
||||
filename: fixture("json-pkg-config", "src.js"),
|
||||
});
|
||||
},
|
||||
/Multiple configuration files found\.(.|\n)*\.babelrc(.|\n)*package\.json/
|
||||
);
|
||||
});
|
||||
|
||||
it("js-config-error", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error", "src.js"),
|
||||
});
|
||||
},
|
||||
/Error while loading config/
|
||||
);
|
||||
});
|
||||
|
||||
it("js-config-error2", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error2", "src.js"),
|
||||
});
|
||||
},
|
||||
/Configuration should be an exported JavaScript object/
|
||||
);
|
||||
});
|
||||
|
||||
it("js-config-error3", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
buildConfigChain({
|
||||
filename: fixture("js-config-error3", "src.js"),
|
||||
});
|
||||
},
|
||||
/Configuration should be an exported JavaScript object/
|
||||
);
|
||||
});
|
||||
|
||||
it("json-config-error", function () {
|
||||
assert.throws(
|
||||
function () {
|
||||
buildConfigChain({
|
||||
filename: fixture("json-config-error", "src.js"),
|
||||
});
|
||||
},
|
||||
/Error while parsing JSON/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
10
packages/babel-core/test/fixtures/config/js-config-default/.babelrc.js
vendored
Normal file
10
packages/babel-core/test/fixtures/config/js-config-default/.babelrc.js
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
var plugins = ["foo", "bar"];
|
||||
|
||||
exports.default = {
|
||||
plugins: plugins
|
||||
};
|
||||
1
packages/babel-core/test/fixtures/config/js-config-default/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config-default/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
2
packages/babel-core/test/fixtures/config/js-config-error/.babelrc.js
vendored
Normal file
2
packages/babel-core/test/fixtures/config/js-config-error/.babelrc.js
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
throw new Error("Something bad happened!");
|
||||
module.exports = {}
|
||||
1
packages/babel-core/test/fixtures/config/js-config-error/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config-error/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
1
packages/babel-core/test/fixtures/config/js-config-error2/.babelrc.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config-error2/.babelrc.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = '';
|
||||
1
packages/babel-core/test/fixtures/config/js-config-error2/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config-error2/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
1
packages/babel-core/test/fixtures/config/js-config-error3/.babelrc.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config-error3/.babelrc.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
module.exports = null;
|
||||
1
packages/babel-core/test/fixtures/config/js-config-error3/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config-error3/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
6
packages/babel-core/test/fixtures/config/js-config-extended/.babelrc.js
vendored
Normal file
6
packages/babel-core/test/fixtures/config/js-config-extended/.babelrc.js
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
var plugins = ["foo", "bar"];
|
||||
|
||||
module.exports = {
|
||||
extends: "../extended.babelrc.json",
|
||||
plugins: plugins
|
||||
}
|
||||
1
packages/babel-core/test/fixtures/config/js-config-extended/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config-extended/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
5
packages/babel-core/test/fixtures/config/js-config/.babelrc.js
vendored
Normal file
5
packages/babel-core/test/fixtures/config/js-config/.babelrc.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
var plugins = ["foo", "bar"];
|
||||
|
||||
module.exports = {
|
||||
plugins: plugins
|
||||
}
|
||||
1
packages/babel-core/test/fixtures/config/js-config/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-config/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
5
packages/babel-core/test/fixtures/config/js-json-config/.babelrc
vendored
Normal file
5
packages/babel-core/test/fixtures/config/js-json-config/.babelrc
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
"json"
|
||||
]
|
||||
}
|
||||
5
packages/babel-core/test/fixtures/config/js-json-config/.babelrc.js
vendored
Normal file
5
packages/babel-core/test/fixtures/config/js-json-config/.babelrc.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
"js"
|
||||
]
|
||||
}
|
||||
1
packages/babel-core/test/fixtures/config/js-json-config/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-json-config/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
5
packages/babel-core/test/fixtures/config/js-pkg-config/.babelrc.js
vendored
Normal file
5
packages/babel-core/test/fixtures/config/js-pkg-config/.babelrc.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
"js"
|
||||
]
|
||||
}
|
||||
3
packages/babel-core/test/fixtures/config/js-pkg-config/package.json
vendored
Normal file
3
packages/babel-core/test/fixtures/config/js-pkg-config/package.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"babel": {}
|
||||
}
|
||||
1
packages/babel-core/test/fixtures/config/js-pkg-config/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/js-pkg-config/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
3
packages/babel-core/test/fixtures/config/json-config-error/.babelrc
vendored
Normal file
3
packages/babel-core/test/fixtures/config/json-config-error/.babelrc
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"bad: "json"
|
||||
}
|
||||
1
packages/babel-core/test/fixtures/config/json-config-error/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/json-config-error/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
5
packages/babel-core/test/fixtures/config/json-pkg-config-no-babel/.babelrc
vendored
Normal file
5
packages/babel-core/test/fixtures/config/json-pkg-config-no-babel/.babelrc
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
"json"
|
||||
]
|
||||
}
|
||||
1
packages/babel-core/test/fixtures/config/json-pkg-config-no-babel/package.json
vendored
Normal file
1
packages/babel-core/test/fixtures/config/json-pkg-config-no-babel/package.json
vendored
Normal file
@ -0,0 +1 @@
|
||||
{}
|
||||
1
packages/babel-core/test/fixtures/config/json-pkg-config-no-babel/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/json-pkg-config-no-babel/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
5
packages/babel-core/test/fixtures/config/json-pkg-config/.babelrc
vendored
Normal file
5
packages/babel-core/test/fixtures/config/json-pkg-config/.babelrc
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": [
|
||||
"json"
|
||||
]
|
||||
}
|
||||
3
packages/babel-core/test/fixtures/config/json-pkg-config/package.json
vendored
Normal file
3
packages/babel-core/test/fixtures/config/json-pkg-config/package.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"babel": {}
|
||||
}
|
||||
1
packages/babel-core/test/fixtures/config/json-pkg-config/src.js
vendored
Normal file
1
packages/babel-core/test/fixtures/config/json-pkg-config/src.js
vendored
Normal file
@ -0,0 +1 @@
|
||||
// empty
|
||||
@ -10,9 +10,7 @@ import type { Format } from "./printer";
|
||||
*/
|
||||
|
||||
class Generator extends Printer {
|
||||
constructor(ast, opts, code) {
|
||||
opts = opts || {};
|
||||
|
||||
constructor(ast, opts = {}, code) {
|
||||
const tokens = ast.tokens || [];
|
||||
const format = normalizeOptions(code, opts, tokens);
|
||||
const map = opts.sourceMaps ? new SourceMap(opts, code) : null;
|
||||
|
||||
@ -34,12 +34,8 @@ export function NullableTypeAnnotation(node: Object, parent: Object): boolean {
|
||||
export { NullableTypeAnnotation as FunctionTypeAnnotation };
|
||||
|
||||
export function UpdateExpression(node: Object, parent: Object): boolean {
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
// (foo++).test()
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
// (foo++).test()
|
||||
return t.isMemberExpression(parent) && parent.object === node;
|
||||
}
|
||||
|
||||
export function ObjectExpression(node: Object, parent: Object, printStack: Array<Object>): boolean {
|
||||
@ -51,15 +47,11 @@ export function DoExpression(node: Object, parent: Object, printStack: Array<Obj
|
||||
}
|
||||
|
||||
export function Binary(node: Object, parent: Object): boolean {
|
||||
if ((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isMemberExpression(parent) && parent.object === node) {
|
||||
if (
|
||||
((t.isCallExpression(parent) || t.isNewExpression(parent)) && parent.callee === node) ||
|
||||
t.isUnaryLike(parent) ||
|
||||
(t.isMemberExpression(parent) && parent.object === node)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -70,12 +62,11 @@ export function Binary(node: Object, parent: Object): boolean {
|
||||
const nodeOp = node.operator;
|
||||
const nodePos = PRECEDENCE[nodeOp];
|
||||
|
||||
if (parentPos > nodePos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Logical expressions with the same precedence don't need parens.
|
||||
if (parentPos === nodePos && parent.right === node && !t.isLogicalExpression(parent)) {
|
||||
if (
|
||||
// Logical expressions with the same precedence don't need parens.
|
||||
(parentPos === nodePos && parent.right === node && !t.isLogicalExpression(parent)) ||
|
||||
parentPos > nodePos
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -84,55 +75,27 @@ export function Binary(node: Object, parent: Object): boolean {
|
||||
}
|
||||
|
||||
export function BinaryExpression(node: Object, parent: Object): boolean {
|
||||
if (node.operator === "in") {
|
||||
// let i = (1 in []);
|
||||
if (t.isVariableDeclarator(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// for ((1 in []);;);
|
||||
if (t.isFor(parent)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
// let i = (1 in []);
|
||||
// for ((1 in []);;);
|
||||
return node.operator === "in" && (t.isVariableDeclarator(parent) || t.isFor(parent));
|
||||
}
|
||||
|
||||
export function SequenceExpression(node: Object, parent: Object): boolean {
|
||||
if (t.isForStatement(parent)) {
|
||||
|
||||
if (
|
||||
// Although parentheses wouldn"t hurt around sequence
|
||||
// expressions in the head of for loops, traditional style
|
||||
// dictates that e.g. i++, j++ should not be wrapped with
|
||||
// parentheses.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isExpressionStatement(parent) && parent.expression === node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isReturnStatement(parent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isThrowStatement(parent)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isSwitchStatement(parent) && parent.discriminant === node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isWhileStatement(parent) && parent.test === node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isIfStatement(parent) && parent.test === node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (t.isForInStatement(parent) && parent.right === node) {
|
||||
t.isForStatement(parent) ||
|
||||
t.isThrowStatement(parent) ||
|
||||
t.isReturnStatement(parent) ||
|
||||
(t.isIfStatement(parent) && parent.test === node) ||
|
||||
(t.isWhileStatement(parent) && parent.test === node) ||
|
||||
(t.isForInStatement(parent) && parent.right === node) ||
|
||||
(t.isSwitchStatement(parent) && parent.discriminant === node) ||
|
||||
(t.isExpressionStatement(parent) && parent.expression === node)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -158,15 +121,9 @@ export function ClassExpression(node: Object, parent: Object, printStack: Array<
|
||||
}
|
||||
|
||||
export function UnaryLike(node: Object, parent: Object): boolean {
|
||||
if (t.isMemberExpression(parent, { object: node })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isCallExpression(parent, { callee: node }) || t.isNewExpression(parent, { callee: node })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return t.isMemberExpression(parent, { object: node }) ||
|
||||
t.isCallExpression(parent, { callee: node }) ||
|
||||
t.isNewExpression(parent, { callee: node });
|
||||
}
|
||||
|
||||
export function FunctionExpression(node: Object, parent: Object, printStack: Array<Object>): boolean {
|
||||
@ -189,19 +146,12 @@ export function ArrowFunctionExpression(node: Object, parent: Object): boolean {
|
||||
}
|
||||
|
||||
export function ConditionalExpression(node: Object, parent: Object): boolean {
|
||||
if (t.isUnaryLike(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isBinary(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isConditionalExpression(parent, { test: node })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isAwaitExpression(parent)) {
|
||||
if (
|
||||
t.isUnaryLike(parent) ||
|
||||
t.isBinary(parent) ||
|
||||
t.isConditionalExpression(parent, { test: node }) ||
|
||||
t.isAwaitExpression(parent)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -227,28 +177,23 @@ function isFirstInStatement(printStack: Array<Object>, {
|
||||
i--;
|
||||
let parent = printStack[i];
|
||||
while (i > 0) {
|
||||
if (t.isExpressionStatement(parent, { expression: node })) {
|
||||
if (
|
||||
t.isExpressionStatement(parent, { expression: node }) ||
|
||||
t.isTaggedTemplateExpression(parent) ||
|
||||
considerDefaultExports && t.isExportDefaultDeclaration(parent, { declaration: node }) ||
|
||||
considerArrow && t.isArrowFunctionExpression(parent, { body: node })
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (t.isTaggedTemplateExpression(parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (considerDefaultExports && t.isExportDefaultDeclaration(parent, { declaration: node })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (considerArrow && t.isArrowFunctionExpression(parent, { body: node })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((t.isCallExpression(parent, { callee: node })) ||
|
||||
(t.isSequenceExpression(parent) && parent.expressions[0] === node) ||
|
||||
(t.isMemberExpression(parent, { object: node })) ||
|
||||
(t.isConditional(parent, { test: node })) ||
|
||||
(t.isBinary(parent, { left: node })) ||
|
||||
(t.isAssignmentExpression(parent, { left: node }))) {
|
||||
if (
|
||||
t.isCallExpression(parent, { callee: node }) ||
|
||||
(t.isSequenceExpression(parent) && parent.expressions[0] === node) ||
|
||||
t.isMemberExpression(parent, { object: node }) ||
|
||||
t.isConditional(parent, { test: node }) ||
|
||||
t.isBinary(parent, { left: node }) ||
|
||||
t.isAssignmentExpression(parent, { left: node })
|
||||
) {
|
||||
node = parent;
|
||||
i--;
|
||||
parent = printStack[i];
|
||||
|
||||
@ -332,9 +332,11 @@ export default class Printer {
|
||||
this._maybeAddAuxComment(this._insideAux && !oldInAux);
|
||||
|
||||
let needsParens = n.needsParens(node, parent, this._printStack);
|
||||
if (this.format.retainFunctionParens &&
|
||||
node.type === "FunctionExpression" &&
|
||||
node.extra && node.extra.parenthesized) {
|
||||
if (
|
||||
this.format.retainFunctionParens &&
|
||||
node.type === "FunctionExpression" &&
|
||||
node.extra && node.extra.parenthesized
|
||||
) {
|
||||
needsParens = true;
|
||||
}
|
||||
if (needsParens) this.token("(");
|
||||
|
||||
@ -4,19 +4,22 @@
|
||||
|
||||
## Example
|
||||
|
||||
### Rest Properties
|
||||
|
||||
```js
|
||||
// Rest properties
|
||||
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
|
||||
console.log(x); // 1
|
||||
console.log(y); // 2
|
||||
console.log(z); // { a: 3, b: 4 }
|
||||
```
|
||||
|
||||
// Spread properties
|
||||
### Spread Properties
|
||||
|
||||
```js
|
||||
let n = { x, y, ...z };
|
||||
console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
|
||||
```
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
@ -35,27 +38,6 @@ npm install --save-dev babel-plugin-transform-object-rest-spread
|
||||
}
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
This plugin will use babel's `extends` helper, which will polyfill `Object.assign` by default.
|
||||
|
||||
* `useBuiltIns` - Do not use Babel's helper's and just transform to use the built-in method (Disabled by default).
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
["transform-object-rest-spread", { "useBuiltIns": true }]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
// source
|
||||
z = { x, ...y };
|
||||
// compiled
|
||||
z = Object.assign({ x }, y);
|
||||
```
|
||||
|
||||
### Via CLI
|
||||
|
||||
```sh
|
||||
@ -70,6 +52,36 @@ require("babel-core").transform("code", {
|
||||
});
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### `useBuiltIns`
|
||||
|
||||
`boolean`, defaults to `false`.
|
||||
|
||||
By default, this plugin uses Babel's `extends` helper which polyfills `Object.assign`. Enabling this option will use `Object.assign` directly.
|
||||
|
||||
**.babelrc**
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
["transform-object-rest-spread", { "useBuiltIns": true }]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**In**
|
||||
|
||||
```js
|
||||
z = { x, ...y };
|
||||
```
|
||||
|
||||
**Out**
|
||||
|
||||
```js
|
||||
z = Object.assign({ x }, y);
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
* [Proposal: Object Rest/Spread Properties for ECMAScript](https://github.com/sebmarkbage/ecmascript-rest-spread)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user