diff --git a/.babelrc.js b/.babelrc.js index 81f0ab9b61..c9e2261620 100644 --- a/.babelrc.js +++ b/.babelrc.js @@ -31,27 +31,34 @@ function istanbulHacks() { } let envOpts = { - loose: true + loose: true, + exclude: ["transform-typeof-symbol"], }; -module.exports = { +const config = { comments: false, presets: [ ["@babel/env", envOpts], - "@babel/stage-0", "@babel/flow" ], - env: { - cov: { - auxiliaryCommentBefore: "istanbul ignore next", - plugins: [istanbulHacks] - } - } + plugins: [ + ["@babel/proposal-class-properties", { loose: true }], + "@babel/proposal-export-namespace", + "@babel/proposal-numeric-separator", + ["@babel/proposal-object-rest-spread", { useBuiltIns: true}], + ] }; +if (process.env.BABEL_ENV === "cov") { + config.auxiliaryCommentBefore = "istanbul ignore next"; + config.plugins.push(istanbulHacks); +} + if (process.env.BABEL_ENV === "development") { envOpts.targets = { node: "current" }; envOpts.debug = true; } + +module.exports = config; diff --git a/packages/babel-preset-react/README.md b/packages/babel-preset-react/README.md index 6bc22054d3..e45e1b94dc 100644 --- a/packages/babel-preset-react/README.md +++ b/packages/babel-preset-react/README.md @@ -29,12 +29,28 @@ npm install --save-dev @babel/preset-react **.babelrc** +Without options: + ```json { "presets": ["@babel/react"] } ``` +With options: + +```json +{ + "presets": [ + ["@babel/react", { + "pragma": "dom", // default pragma is React.createElement + "pragmaFrag": "DomFrag", // default is React.Fragment + "throwIfNamespace": false // defaults to true + }] + ] +} +``` + ### Via CLI ```sh @@ -51,6 +67,24 @@ require("@babel/core").transform("code", { ## Options +### `pragma` + +`string`, defaults to `React.createElement`. + +Replace the function used when compiling JSX expressions. + +### `pragmaFrag` + +`string`, defaults to `React.Fragment`. + +Replace the component used when compiling JSX fragments. + +### `useBuiltIns` + +`boolean`, defaults to `false`. + +Will use the native built-in instead of trying to polyfill behavior for any plugins that require one. + ### `development` `boolean`, defaults to `false`. @@ -59,13 +93,23 @@ Toggles plugins that aid in development, such as [`@babel/plugin-transform-react This is useful when combined with either a `babelrc.js` or [env option in a .babelrc](https://babeljs.io/docs/usage/babelrc/#env-option) configuration: +### `throwIfNamespace` + +`boolean`, defaults to `true`. + +Toggles whether or not to throw an error if a XML namespaced tag name is used. For example: + + + +Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it. + #### babelrc.js ```js module.exports = { presets: [ ["@babel/react", { - development: process.env.BABEL_ENV === "development" + development: process.env.BABEL_ENV === "development", }], ], } diff --git a/packages/babel-preset-react/src/index.js b/packages/babel-preset-react/src/index.js index 6a854c2b8d..a3402042fb 100644 --- a/packages/babel-preset-react/src/index.js +++ b/packages/babel-preset-react/src/index.js @@ -5,15 +5,25 @@ import transformReactJSXSource from "@babel/plugin-transform-react-jsx-source"; import transformReactJSXSelf from "@babel/plugin-transform-react-jsx-self"; export default function(context, opts = {}) { - const development = opts.development || false; + const pragma = opts.pragma || "React.createElement"; + const pragmaFrag = opts.pragmaFrag || "React.Fragment"; + const throwIfNamespace = + opts.throwIfNamespace === undefined ? true : !!opts.throwIfNamespace; + const development = !!opts.development; + const useBuiltIns = !!opts.useBuiltIns; if (typeof development !== "boolean") { - throw new Error("Preset react 'development' option must be a boolean."); + throw new Error( + "@babel/preset-react 'development' option must be a boolean.", + ); } return { plugins: [ - transformReactJSX, + [ + transformReactJSX, + { pragma, pragmaFrag, throwIfNamespace, useBuiltIns }, + ], transformSyntaxJSX, transformReactDisplayName, diff --git a/packages/babel-preset-react/test/index.js b/packages/babel-preset-react/test/index.js index eaa4969a9b..92a7d30391 100644 --- a/packages/babel-preset-react/test/index.js +++ b/packages/babel-preset-react/test/index.js @@ -7,14 +7,4 @@ describe("react preset", () => { react(null); }).not.to.throw(); }); - - describe("options", () => { - describe("development", () => { - it("throws on non-boolean value", () => { - expect(function() { - react(null, { development: 1 }); - }).to.throw(/must be a boolean/); - }); - }); - }); }); diff --git a/packages/babel-preset-stage-0/README.md b/packages/babel-preset-stage-0/README.md index fd8edcb73e..0fa0338e1f 100644 --- a/packages/babel-preset-stage-0/README.md +++ b/packages/babel-preset-stage-0/README.md @@ -33,3 +33,17 @@ require("@babel/core").transform("code", { presets: ["@babel/stage-0"] }); ``` + +## Options + +### `loose` + +`boolean`, defaults to `false`. + +Enable "loose" transformations for any plugins in this preset that allow them. + +### `useBuiltIns` + +`boolean`, defaults to `false`. + +Will use the native built-in instead of trying to polyfill behavior for any plugins that require one. diff --git a/packages/babel-preset-stage-0/src/index.js b/packages/babel-preset-stage-0/src/index.js index 799abdf1ad..a439e6f460 100644 --- a/packages/babel-preset-stage-0/src/index.js +++ b/packages/babel-preset-stage-0/src/index.js @@ -3,9 +3,26 @@ import presetStage1 from "@babel/preset-stage-1"; import transformDoExpressions from "@babel/plugin-proposal-do-expressions"; import transformFunctionBind from "@babel/plugin-proposal-function-bind"; -export default function() { +export default function(context, opts = {}) { + let loose = false; + let useBuiltIns = false; + + if (opts !== undefined) { + if (opts.loose !== undefined) loose = opts.loose; + if (opts.useBuiltIns !== undefined) useBuiltIns = opts.useBuiltIns; + } + + if (typeof loose !== "boolean") { + throw new Error("@babel/preset-stage-0 'loose' option must be a boolean."); + } + if (typeof useBuiltIns !== "boolean") { + throw new Error( + "@babel/preset-stage-0 'useBuiltIns' option must be a boolean.", + ); + } + return { - presets: [presetStage1], + presets: [[presetStage1, { loose, useBuiltIns }]], plugins: [transformDoExpressions, transformFunctionBind], }; } diff --git a/packages/babel-preset-stage-1/README.md b/packages/babel-preset-stage-1/README.md index 287a7393d5..5a8f2623eb 100644 --- a/packages/babel-preset-stage-1/README.md +++ b/packages/babel-preset-stage-1/README.md @@ -44,6 +44,20 @@ require("@babel/core").transform("code", { }); ``` +## Options + +### `loose` + +`boolean`, defaults to `false`. + +Enable "loose" transformations for any plugins in this preset that allow them. + +### `useBuiltIns` + +`boolean`, defaults to `false`. + +Will use the native built-in instead of trying to polyfill behavior for any plugins that require one. + ## References - Chapter "[The TC39 process for ECMAScript features](http://exploringjs.com/es2016-es2017/ch_tc39-process.html)" in "Exploring ES2016 and ES2017" by Axel Rauschmayer diff --git a/packages/babel-preset-stage-1/src/index.js b/packages/babel-preset-stage-1/src/index.js index 18a29d7955..f92e6e3a8a 100644 --- a/packages/babel-preset-stage-1/src/index.js +++ b/packages/babel-preset-stage-1/src/index.js @@ -6,15 +6,32 @@ import transformOptionalChaining from "@babel/plugin-proposal-optional-chaining" import transformPipelineOperator from "@babel/plugin-proposal-pipeline-operator"; import transformNullishCoalescingOperator from "@babel/plugin-proposal-nullish-coalescing-operator"; -export default function() { +export default function(context, opts = {}) { + let loose = false; + let useBuiltIns = false; + + if (opts !== undefined) { + if (opts.loose !== undefined) loose = opts.loose; + if (opts.useBuiltIns !== undefined) useBuiltIns = opts.useBuiltIns; + } + + if (typeof loose !== "boolean") { + throw new Error("@babel/preset-stage-1 'loose' option must be a boolean."); + } + if (typeof useBuiltIns !== "boolean") { + throw new Error( + "@babel/preset-stage-1 'useBuiltIns' option must be a boolean.", + ); + } + return { - presets: [presetStage2], + presets: [[presetStage2, { loose, useBuiltIns }]], plugins: [ transformDecorators, transformExportDefault, - transformOptionalChaining, + [transformOptionalChaining, { loose }], transformPipelineOperator, - transformNullishCoalescingOperator, + [transformNullishCoalescingOperator, { loose }], ], }; } diff --git a/packages/babel-preset-stage-2/README.md b/packages/babel-preset-stage-2/README.md index 5c364ecfba..d2f0519bf1 100644 --- a/packages/babel-preset-stage-2/README.md +++ b/packages/babel-preset-stage-2/README.md @@ -12,8 +12,6 @@ The gist of Stage 2 is: > > **What’s next?** Only incremental changes are expected from now on. - - ## Install ```sh @@ -45,6 +43,21 @@ require("@babel/core").transform("code", { presets: ["@babel/stage-2"] }); ``` + +## Options + +### `loose` + +`boolean`, defaults to `false`. + +Enable "loose" transformations for any plugins in this preset that allow them. + +### `useBuiltIns` + +`boolean`, defaults to `false`. + +Will use the native built-in instead of trying to polyfill behavior for any plugins that require one. + ## References - Chapter "[The TC39 process for ECMAScript features](http://exploringjs.com/es2016-es2017/ch_tc39-process.html)" in "Exploring ES2016 and ES2017" by Axel Rauschmayer diff --git a/packages/babel-preset-stage-2/src/index.js b/packages/babel-preset-stage-2/src/index.js index 46c68d6a2d..b8a7afc0c9 100644 --- a/packages/babel-preset-stage-2/src/index.js +++ b/packages/babel-preset-stage-2/src/index.js @@ -5,9 +5,26 @@ import transformExportNamespace from "@babel/plugin-proposal-export-namespace"; import transformNumericSeparator from "@babel/plugin-proposal-numeric-separator"; import transformThrowExpressions from "@babel/plugin-proposal-throw-expressions"; -export default function() { +export default function(context, opts = {}) { + let loose = false; + let useBuiltIns = false; + + if (opts !== undefined) { + if (opts.loose !== undefined) loose = opts.loose; + if (opts.useBuiltIns !== undefined) useBuiltIns = opts.useBuiltIns; + } + + if (typeof loose !== "boolean") { + throw new Error("@babel/preset-stage-2 'loose' option must be a boolean."); + } + if (typeof useBuiltIns !== "boolean") { + throw new Error( + "@babel/preset-stage-2 'useBuiltIns' option must be a boolean.", + ); + } + return { - presets: [presetStage3], + presets: [[presetStage3, { loose, useBuiltIns }]], plugins: [ transformFunctionSent, transformExportNamespace, diff --git a/packages/babel-preset-stage-3/README.md b/packages/babel-preset-stage-3/README.md index d4f2680dc3..034f050014 100644 --- a/packages/babel-preset-stage-3/README.md +++ b/packages/babel-preset-stage-3/README.md @@ -12,8 +12,6 @@ The gist of Stage 3 is: > > **What’s next?** Henceforth, changes should only be made in response to critical issues raised by the implementations and their use. - - ## Install ```sh @@ -46,6 +44,20 @@ require("@babel/core").transform("code", { }); ``` +## Options + +### `loose` + +`boolean`, defaults to `false`. + +Enable "loose" transformations for any plugins in this preset that allow them. + +### `useBuiltIns` + +`boolean`, defaults to `false`. + +Will use the native built-in instead of trying to polyfill behavior for any plugins that require one. + ## References - Chapter "[The TC39 process for ECMAScript features](http://exploringjs.com/es2016-es2017/ch_tc39-process.html)" in "Exploring ES2016 and ES2017" by Axel Rauschmayer diff --git a/packages/babel-preset-stage-3/src/index.js b/packages/babel-preset-stage-3/src/index.js index 730ab6425a..9d07cf1b0c 100644 --- a/packages/babel-preset-stage-3/src/index.js +++ b/packages/babel-preset-stage-3/src/index.js @@ -5,13 +5,30 @@ import transformObjectRestSpread from "@babel/plugin-proposal-object-rest-spread import transformOptionalCatchBinding from "@babel/plugin-proposal-optional-catch-binding"; import transformUnicodePropertyRegex from "@babel/plugin-proposal-unicode-property-regex"; -export default function() { +export default function(context, opts = {}) { + let loose = false; + let useBuiltIns = false; + + if (opts !== undefined) { + if (opts.loose !== undefined) loose = opts.loose; + if (opts.useBuiltIns !== undefined) useBuiltIns = opts.useBuiltIns; + } + + if (typeof loose !== "boolean") { + throw new Error("@babel/preset-stage-3 'loose' option must be a boolean."); + } + if (typeof useBuiltIns !== "boolean") { + throw new Error( + "@babel/preset-stage-3 'useBuiltIns' option must be a boolean.", + ); + } + return { plugins: [ syntaxDynamicImport, transformAsyncGeneratorFunctions, - transformClassProperties, - transformObjectRestSpread, + [transformClassProperties, { loose }], + [transformObjectRestSpread, { useBuiltIns }], transformOptionalCatchBinding, transformUnicodePropertyRegex, ], diff --git a/packages/babylon/package.json b/packages/babylon/package.json index 0289526ca5..268c0525ac 100644 --- a/packages/babylon/package.json +++ b/packages/babylon/package.json @@ -24,6 +24,7 @@ }, "devDependencies": { "@babel/helper-fixtures": "7.0.0-beta.5", + "babel-plugin-transform-for-of-as-array": "1.0.4", "rollup": "^0.50.0", "rollup-plugin-babel": "^4.0.0-beta.0", "rollup-plugin-node-resolve": "^3.0.0", diff --git a/packages/babylon/rollup.config.js b/packages/babylon/rollup.config.js index 2d9d89cd7b..7ed7a136b4 100644 --- a/packages/babylon/rollup.config.js +++ b/packages/babylon/rollup.config.js @@ -9,6 +9,7 @@ export default { }, plugins: [ babel({ + externalHelpersWhitelist: ["inheritsLoose"], babelrc: false, presets: [ [ @@ -23,6 +24,7 @@ export default { ], "@babel/flow", ], + plugins: ["transform-for-of-as-array"], }), nodeResolve(), ], diff --git a/packages/babylon/src/parser/lval.js b/packages/babylon/src/parser/lval.js index 01ab50f485..e703d97939 100644 --- a/packages/babylon/src/parser/lval.js +++ b/packages/babylon/src/parser/lval.js @@ -56,12 +56,10 @@ export default class LValParser extends NodeUtils { case "ObjectExpression": node.type = "ObjectPattern"; - for (const [index, prop] of node.properties.entries()) { - this.toAssignableObjectExpressionProp( - prop, - isBinding, - index === node.properties.length - 1, - ); + for (let index = 0; index < node.properties.length; index++) { + const prop = node.properties[index]; + const isLast = index === node.properties.length - 1; + this.toAssignableObjectExpressionProp(prop, isBinding, isLast); } break;