package/LICENSE 000644 0000002046 3560116604 010267 0 ustar 00 000000 000000 MIT License Copyright (c) 2020 Babel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. package/lib/index.js 000644 0000002657 3560116604 011505 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = void 0; var _path = _interopRequireDefault(require("path")); var _helperPluginUtils = require("@babel/helper-plugin-utils"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @babel/preset-modules produces clean, minimal output for ES Modules-supporting browsers. * @param {Object} [options] * @param {boolean} [options.loose=false] Loose mode skips seldom-needed transforms that increase output size. */ var _default = (0, _helperPluginUtils.declare)((api, opts) => { api.assertVersion(7); const loose = opts.loose === true; return { plugins: [_path.default.resolve(__dirname, "./plugins/transform-edge-default-parameters"), _path.default.resolve(__dirname, "./plugins/transform-tagged-template-caching"), _path.default.resolve(__dirname, "./plugins/transform-jsx-spread"), _path.default.resolve(__dirname, "./plugins/transform-safari-for-shadowing"), _path.default.resolve(__dirname, "./plugins/transform-safari-block-shadowing"), _path.default.resolve(__dirname, "./plugins/transform-async-arrows-in-class"), !loose && _path.default.resolve(__dirname, "./plugins/transform-edge-function-name"), // Proposals require.resolve("@babel/plugin-proposal-unicode-property-regex"), require.resolve("@babel/plugin-transform-dotall-regex")].filter(Boolean) }; }); exports.default = _default; module.exports = exports.default; package/lib/plugins/transform-async-arrows-in-class/index.js 000644 0000002174 3560116604 021330 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = void 0; /** * Safari 10.3 had an issue where async arrow function expressions within any class method would throw. * After an initial fix, any references to the instance via `this` within those methods would also throw. * This is fixed by converting arrow functions in class methods into equivalent function expressions. * @see https://bugs.webkit.org/show_bug.cgi?id=166879 * * @example * class X{ a(){ async () => {}; } } // throws * class X{ a(){ async function() {}; } } // works * * @example * class X{ a(){ * async () => this.a; // throws * } } * class X{ a(){ * var _this=this; * async function() { return _this.a }; // works * } } */ const OPTS = { allowInsertArrow: false, specCompliant: false }; var _default = ({ types: t }) => ({ name: "transform-async-arrows-in-class", visitor: { ArrowFunctionExpression(path) { if (path.node.async && path.findParent(t.isClassMethod)) { path.arrowFunctionToExpression(OPTS); } } } }); exports.default = _default; module.exports = exports.default; package/lib/plugins/transform-edge-default-parameters/index.js 000644 0000002142 3560116604 021653 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = void 0; /** * Converts destructured parameters with default values to non-shorthand syntax. * This fixes the only arguments-related bug in ES Modules-supporting browsers (Edge 16 & 17). * Use this plugin instead of @babel/plugin-transform-parameters when targeting ES Modules. */ var _default = ({ types: t }) => { const isArrowParent = p => p.parentKey === "params" && p.parentPath && t.isArrowFunctionExpression(p.parentPath); return { name: "transform-edge-default-parameters", visitor: { AssignmentPattern(path) { const arrowArgParent = path.find(isArrowParent); if (arrowArgParent && path.parent.shorthand) { // In Babel 7+, there is no way to force non-shorthand properties. path.parent.shorthand = false; (path.parent.extra || {}).shorthand = false; // So, to ensure non-shorthand, rename the local identifier so it no longer matches: path.scope.rename(path.parent.key.name); } } } }; }; exports.default = _default; module.exports = exports.default; package/lib/plugins/transform-edge-function-name/index.js 000644 0000002631 3560116604 020634 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = void 0; /** * Edge 16 & 17 do not infer function.name from variable assignment. * All other `function.name` behavior works fine, so we can skip most of @babel/transform-function-name. * @see https://kangax.github.io/compat-table/es6/#test-function_name_property_variables_(function) * * Note: contrary to various Github issues, Edge 16+ *does* correctly infer the name of Arrow Functions. * The variable declarator name inference issue only affects function expressions, so that's all we fix here. * * A Note on Minification: Terser undoes this transform *by default* unless `keep_fnames` is set to true. * There is by design - if Function.name is critical to your application, you must configure * your minifier to preserve function names. */ var _default = ({ types: t }) => ({ name: "transform-edge-function-name", visitor: { FunctionExpression: { exit(path) { if (!path.node.id && t.isIdentifier(path.parent.id)) { const id = t.cloneNode(path.parent.id); const binding = path.scope.getBinding(id.name); // if the binding gets reassigned anywhere, rename it if (binding == null ? void 0 : binding.constantViolations.length) { path.scope.rename(id.name); } path.node.id = id; } } } } }); exports.default = _default; module.exports = exports.default; package/lib/plugins/transform-jsx-spread/index.js 000644 0000006620 3560116604 017251 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = void 0; var _esutils = _interopRequireDefault(require("esutils")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Converts JSX Spread arguments into Object Spread, avoiding Babel's helper or Object.assign injection. * Input: *
* Output: * * ...which Babel converts to: * h("div", { a: "1", ...b }) */ var _default = ({ types: t }) => { // converts a set of JSXAttributes to an Object.assign() call function convertAttributesAssign(attributes) { const args = []; for (let i = 0, current; i < attributes.length; i++) { const node = attributes[i]; if (t.isJSXSpreadAttribute(node)) { // the first attribute is a spread, avoid copying all other attributes onto it if (i === 0) { args.push(t.objectExpression([])); } current = null; args.push(node.argument); } else { const name = getAttributeName(node); const value = getAttributeValue(node); if (!current) { current = t.objectExpression([]); args.push(current); } current.properties.push(t.objectProperty(name, value)); } } return t.callExpression(t.memberExpression(t.identifier("Object"), t.identifier("assign")), args); } // Converts a JSXAttribute to the equivalent ObjectExpression property function convertAttributeSpread(node) { if (t.isJSXSpreadAttribute(node)) { return t.spreadElement(node.argument); } const name = getAttributeName(node); const value = getAttributeValue(node); return t.inherits(t.objectProperty(name, value), node); } // Convert a JSX attribute name to an Object expression property name function getAttributeName(node) { if (t.isJSXNamespacedName(node.name)) { return t.stringLiteral(node.name.namespace.name + ":" + node.name.name.name); } if (_esutils.default.keyword.isIdentifierNameES6(node.name.name)) { return t.identifier(node.name.name); } return t.stringLiteral(node.name.name); } // Convert a JSX attribute value to a JavaScript expression value function getAttributeValue(node) { let value = node.value || t.booleanLiteral(true); if (t.isJSXExpressionContainer(value)) { value = value.expression; } else if (t.isStringLiteral(value)) { value.value = value.value.replace(/\n\s+/g, " "); // "raw" JSXText should not be used from a StringLiteral because it needs to be escaped. if (value.extra && value.extra.raw) { delete value.extra.raw; } } return value; } return { name: "transform-jsx-spread", visitor: { JSXOpeningElement(path, state) { const useSpread = state.opts.useSpread === true; const hasSpread = path.node.attributes.some(attr => t.isJSXSpreadAttribute(attr)); // ignore JSX Elements without spread or with lone spread: if (!hasSpread || path.node.attributes.length === 1) return; if (useSpread) { path.node.attributes = [t.jsxSpreadAttribute(t.objectExpression(path.node.attributes.map(convertAttributeSpread)))]; } else { path.node.attributes = [t.jsxSpreadAttribute(convertAttributesAssign(path.node.attributes))]; } } } }; }; exports.default = _default; module.exports = exports.default; package/lib/plugins/transform-safari-block-shadowing/index.js 000644 0000002473 3560116604 021511 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = _default; /** * Fixes block-shadowed let/const bindings in Safari 10/11. * https://kangax.github.io/compat-table/es6/#test-let_scope_shadow_resolution */ function _default({ types: t }) { return { name: "transform-safari-block-shadowing", visitor: { VariableDeclarator(path) { // the issue only affects let and const bindings: const kind = path.parent.kind; if (kind !== "let" && kind !== "const") return; // ignore non-block-scoped bindings: const block = path.scope.block; if (t.isFunction(block) || t.isProgram(block)) return; const bindings = t.getOuterBindingIdentifiers(path.node.id); for (const name of Object.keys(bindings)) { let scope = path.scope; // ignore parent bindings (note: impossible due to let/const?) if (!scope.hasOwnBinding(name)) continue; // check if shadowed within the nearest function/program boundary while (scope = scope.parent) { if (scope.hasOwnBinding(name)) { path.scope.rename(name); break; } if (t.isFunction(scope.block) || t.isProgram(scope.block)) { break; } } } } } }; } module.exports = exports.default; package/lib/plugins/transform-safari-for-shadowing/index.js 000644 0000002150 3560116604 021175 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = void 0; /** * Safari ~11 has an issue where variable declarations in a For statement throw if they shadow parameters. * This is fixed by renaming any declarations in the left/init part of a For* statement so they don't shadow. * @see https://bugs.webkit.org/show_bug.cgi?id=171041 * * @example * e => { for (let e of []) e } // throws * e => { for (let _e of []) _e } // works */ function handle(declaration) { if (!declaration.isVariableDeclaration()) return; const fn = declaration.getFunctionParent(); const { name } = declaration.node.declarations[0].id; // check if there is a shadowed binding coming from a parameter if (fn && fn.scope.hasOwnBinding(name) && fn.scope.getOwnBinding(name).kind === "param") { declaration.scope.rename(name); } } var _default = () => ({ name: "transform-safari-for-shadowing", visitor: { ForXStatement(path) { handle(path.get("left")); }, ForStatement(path) { handle(path.get("init")); } } }); exports.default = _default; module.exports = exports.default; package/lib/plugins/transform-tagged-template-caching/index.js 000644 0000006117 3560116604 021630 0 ustar 00 000000 000000 "use strict"; exports.__esModule = true; exports.default = void 0; /** * Converts destructured parameters with default values to non-shorthand syntax. * This fixes the only Tagged Templates-related bug in ES Modules-supporting browsers (Safari 10 & 11). * Use this plugin instead of `@babel/plugin-transform-template-literals` when targeting ES Modules. * * @example * // Bug 1: Safari 10/11 doesn't reliably return the same Strings value. * // The value changes depending on invocation and function optimization state. * function f() { return Object`` } * f() === new f() // false, should be true. * * @example * // Bug 2: Safari 10/11 use the same cached strings value when the string parts are the same. * // This behavior comes from an earlier version of the spec, and can cause tricky bugs. * Object``===Object`` // true, should be false. * * Benchmarks: https://jsperf.com/compiled-tagged-template-performance */ var _default = ({ types: t }) => ({ name: "transform-tagged-template-caching", visitor: { TaggedTemplateExpression(path, state) { // tagged templates we've already dealt with let processed = state.get("processed"); if (!processed) { processed = new Map(); state.set("processed", processed); } if (processed.has(path.node)) return path.skip(); // Grab the expressions from the original tag. // tag`a${'hello'}` // ['hello'] const expressions = path.node.quasi.expressions; // Create an identity function helper: // identity = t => t let identity = state.get("identity"); if (!identity) { identity = path.scope.getProgramParent().generateDeclaredUidIdentifier("_"); state.set("identity", identity); const binding = path.scope.getBinding(identity.name); binding.path.get("init").replaceWith(t.arrowFunctionExpression( // re-use the helper identifier for compressability [t.identifier("t")], t.identifier("t"))); } // Use the identity function helper to get a reference to the template's Strings. // We replace all expressions with `0` ensure Strings has the same shape. // identity`a${0}` const template = t.taggedTemplateExpression(identity, t.templateLiteral(path.node.quasi.quasis, expressions.map(() => t.numericLiteral(0)))); processed.set(template, true); // Install an inline cache at the callsite using the global variable: // _t || (_t = identity`a${0}`) const ident = path.scope.getProgramParent().generateDeclaredUidIdentifier("t"); path.scope.getBinding(ident.name).path.parent.kind = "let"; const inlineCache = t.logicalExpression("||", ident, t.assignmentExpression("=", ident, template)); // The original tag function becomes a plain function call. // The expressions omitted from the cached Strings tag are directly applied as arguments. // tag(_t || (_t = Object`a${0}`), 'hello') const node = t.callExpression(path.node.tag, [inlineCache, ...expressions]); path.replaceWith(node); } } }); exports.default = _default; module.exports = exports.default; package/src/index.js 000644 0000002230 3560116604 011511 0 ustar 00 000000 000000 import path from "path"; import { declare } from "@babel/helper-plugin-utils"; /** * @babel/preset-modules produces clean, minimal output for ES Modules-supporting browsers. * @param {Object} [options] * @param {boolean} [options.loose=false] Loose mode skips seldom-needed transforms that increase output size. */ export default declare((api, opts) => { api.assertVersion(7); const loose = opts.loose === true; return { plugins: [ path.resolve(__dirname, "./plugins/transform-edge-default-parameters"), path.resolve(__dirname, "./plugins/transform-tagged-template-caching"), path.resolve(__dirname, "./plugins/transform-jsx-spread"), path.resolve(__dirname, "./plugins/transform-safari-for-shadowing"), path.resolve(__dirname, "./plugins/transform-safari-block-shadowing"), path.resolve(__dirname, "./plugins/transform-async-arrows-in-class"), !loose && path.resolve(__dirname, "./plugins/transform-edge-function-name"), // Proposals require.resolve("@babel/plugin-proposal-unicode-property-regex"), require.resolve("@babel/plugin-transform-dotall-regex"), ].filter(Boolean), }; }); package/src/plugins/transform-async-arrows-in-class/index.js 000644 0000001772 3560116604 021354 0 ustar 00 000000 000000 /** * Safari 10.3 had an issue where async arrow function expressions within any class method would throw. * After an initial fix, any references to the instance via `this` within those methods would also throw. * This is fixed by converting arrow functions in class methods into equivalent function expressions. * @see https://bugs.webkit.org/show_bug.cgi?id=166879 * * @example * class X{ a(){ async () => {}; } } // throws * class X{ a(){ async function() {}; } } // works * * @example * class X{ a(){ * async () => this.a; // throws * } } * class X{ a(){ * var _this=this; * async function() { return _this.a }; // works * } } */ const OPTS = { allowInsertArrow: false, specCompliant: false, }; export default ({ types: t }) => ({ name: "transform-async-arrows-in-class", visitor: { ArrowFunctionExpression(path) { if (path.node.async && path.findParent(t.isClassMethod)) { path.arrowFunctionToExpression(OPTS); } }, }, }); package/src/plugins/transform-edge-default-parameters/index.js 000644 0000001764 3560116604 021705 0 ustar 00 000000 000000 /** * Converts destructured parameters with default values to non-shorthand syntax. * This fixes the only arguments-related bug in ES Modules-supporting browsers (Edge 16 & 17). * Use this plugin instead of @babel/plugin-transform-parameters when targeting ES Modules. */ export default ({ types: t }) => { const isArrowParent = p => p.parentKey === "params" && p.parentPath && t.isArrowFunctionExpression(p.parentPath); return { name: "transform-edge-default-parameters", visitor: { AssignmentPattern(path) { const arrowArgParent = path.find(isArrowParent); if (arrowArgParent && path.parent.shorthand) { // In Babel 7+, there is no way to force non-shorthand properties. path.parent.shorthand = false; (path.parent.extra || {}).shorthand = false; // So, to ensure non-shorthand, rename the local identifier so it no longer matches: path.scope.rename(path.parent.key.name); } }, }, }; }; package/src/plugins/transform-edge-function-name/index.js 000644 0000002405 3560116604 020654 0 ustar 00 000000 000000 /** * Edge 16 & 17 do not infer function.name from variable assignment. * All other `function.name` behavior works fine, so we can skip most of @babel/transform-function-name. * @see https://kangax.github.io/compat-table/es6/#test-function_name_property_variables_(function) * * Note: contrary to various Github issues, Edge 16+ *does* correctly infer the name of Arrow Functions. * The variable declarator name inference issue only affects function expressions, so that's all we fix here. * * A Note on Minification: Terser undoes this transform *by default* unless `keep_fnames` is set to true. * There is by design - if Function.name is critical to your application, you must configure * your minifier to preserve function names. */ export default ({ types: t }) => ({ name: "transform-edge-function-name", visitor: { FunctionExpression: { exit(path) { if (!path.node.id && t.isIdentifier(path.parent.id)) { const id = t.cloneNode(path.parent.id); const binding = path.scope.getBinding(id.name); // if the binding gets reassigned anywhere, rename it if (binding?.constantViolations.length) { path.scope.rename(id.name); } path.node.id = id; } }, }, }, }); package/src/plugins/transform-jsx-spread/index.js 000644 0000006462 3560116604 017276 0 ustar 00 000000 000000 import esutils from "esutils"; /** * Converts JSX Spread arguments into Object Spread, avoiding Babel's helper or Object.assign injection. * Input: * * Output: * * ...which Babel converts to: * h("div", { a: "1", ...b }) */ export default ({ types: t }) => { // converts a set of JSXAttributes to an Object.assign() call function convertAttributesAssign(attributes) { const args = []; for (let i = 0, current; i < attributes.length; i++) { const node = attributes[i]; if (t.isJSXSpreadAttribute(node)) { // the first attribute is a spread, avoid copying all other attributes onto it if (i === 0) { args.push(t.objectExpression([])); } current = null; args.push(node.argument); } else { const name = getAttributeName(node); const value = getAttributeValue(node); if (!current) { current = t.objectExpression([]); args.push(current); } current.properties.push(t.objectProperty(name, value)); } } return t.callExpression( t.memberExpression(t.identifier("Object"), t.identifier("assign")), args ); } // Converts a JSXAttribute to the equivalent ObjectExpression property function convertAttributeSpread(node) { if (t.isJSXSpreadAttribute(node)) { return t.spreadElement(node.argument); } const name = getAttributeName(node); const value = getAttributeValue(node); return t.inherits(t.objectProperty(name, value), node); } // Convert a JSX attribute name to an Object expression property name function getAttributeName(node) { if (t.isJSXNamespacedName(node.name)) { return t.stringLiteral( node.name.namespace.name + ":" + node.name.name.name ); } if (esutils.keyword.isIdentifierNameES6(node.name.name)) { return t.identifier(node.name.name); } return t.stringLiteral(node.name.name); } // Convert a JSX attribute value to a JavaScript expression value function getAttributeValue(node) { let value = node.value || t.booleanLiteral(true); if (t.isJSXExpressionContainer(value)) { value = value.expression; } else if (t.isStringLiteral(value)) { value.value = value.value.replace(/\n\s+/g, " "); // "raw" JSXText should not be used from a StringLiteral because it needs to be escaped. if (value.extra && value.extra.raw) { delete value.extra.raw; } } return value; } return { name: "transform-jsx-spread", visitor: { JSXOpeningElement(path, state) { const useSpread = state.opts.useSpread === true; const hasSpread = path.node.attributes.some(attr => t.isJSXSpreadAttribute(attr) ); // ignore JSX Elements without spread or with lone spread: if (!hasSpread || path.node.attributes.length === 1) return; if (useSpread) { path.node.attributes = [ t.jsxSpreadAttribute( t.objectExpression( path.node.attributes.map(convertAttributeSpread) ) ), ]; } else { path.node.attributes = [ t.jsxSpreadAttribute(convertAttributesAssign(path.node.attributes)), ]; } }, }, }; }; package/src/plugins/transform-safari-block-shadowing/index.js 000644 0000002364 3560116604 021531 0 ustar 00 000000 000000 /** * Fixes block-shadowed let/const bindings in Safari 10/11. * https://kangax.github.io/compat-table/es6/#test-let_scope_shadow_resolution */ export default function({ types: t }) { return { name: "transform-safari-block-shadowing", visitor: { VariableDeclarator(path) { // the issue only affects let and const bindings: const kind = path.parent.kind; if (kind !== "let" && kind !== "const") return; // ignore non-block-scoped bindings: const block = path.scope.block; if (t.isFunction(block) || t.isProgram(block)) return; const bindings = t.getOuterBindingIdentifiers(path.node.id); for (const name of Object.keys(bindings)) { let scope = path.scope; // ignore parent bindings (note: impossible due to let/const?) if (!scope.hasOwnBinding(name)) continue; // check if shadowed within the nearest function/program boundary while ((scope = scope.parent)) { if (scope.hasOwnBinding(name)) { path.scope.rename(name); break; } if (t.isFunction(scope.block) || t.isProgram(scope.block)) { break; } } } }, }, }; } package/src/plugins/transform-safari-for-shadowing/index.js 000644 0000001764 3560116604 021230 0 ustar 00 000000 000000 /** * Safari ~11 has an issue where variable declarations in a For statement throw if they shadow parameters. * This is fixed by renaming any declarations in the left/init part of a For* statement so they don't shadow. * @see https://bugs.webkit.org/show_bug.cgi?id=171041 * * @example * e => { for (let e of []) e } // throws * e => { for (let _e of []) _e } // works */ function handle(declaration) { if (!declaration.isVariableDeclaration()) return; const fn = declaration.getFunctionParent(); const { name } = declaration.node.declarations[0].id; // check if there is a shadowed binding coming from a parameter if ( fn && fn.scope.hasOwnBinding(name) && fn.scope.getOwnBinding(name).kind === "param" ) { declaration.scope.rename(name); } } export default () => ({ name: "transform-safari-for-shadowing", visitor: { ForXStatement(path) { handle(path.get("left")); }, ForStatement(path) { handle(path.get("init")); }, }, }); package/src/plugins/transform-tagged-template-caching/index.js 000644 0000006270 3560116604 021651 0 ustar 00 000000 000000 /** * Converts destructured parameters with default values to non-shorthand syntax. * This fixes the only Tagged Templates-related bug in ES Modules-supporting browsers (Safari 10 & 11). * Use this plugin instead of `@babel/plugin-transform-template-literals` when targeting ES Modules. * * @example * // Bug 1: Safari 10/11 doesn't reliably return the same Strings value. * // The value changes depending on invocation and function optimization state. * function f() { return Object`` } * f() === new f() // false, should be true. * * @example * // Bug 2: Safari 10/11 use the same cached strings value when the string parts are the same. * // This behavior comes from an earlier version of the spec, and can cause tricky bugs. * Object``===Object`` // true, should be false. * * Benchmarks: https://jsperf.com/compiled-tagged-template-performance */ export default ({ types: t }) => ({ name: "transform-tagged-template-caching", visitor: { TaggedTemplateExpression(path, state) { // tagged templates we've already dealt with let processed = state.get("processed"); if (!processed) { processed = new Map(); state.set("processed", processed); } if (processed.has(path.node)) return path.skip(); // Grab the expressions from the original tag. // tag`a${'hello'}` // ['hello'] const expressions = path.node.quasi.expressions; // Create an identity function helper: // identity = t => t let identity = state.get("identity"); if (!identity) { identity = path.scope .getProgramParent() .generateDeclaredUidIdentifier("_"); state.set("identity", identity); const binding = path.scope.getBinding(identity.name); binding.path.get("init").replaceWith( t.arrowFunctionExpression( // re-use the helper identifier for compressability [t.identifier("t")], t.identifier("t") ) ); } // Use the identity function helper to get a reference to the template's Strings. // We replace all expressions with `0` ensure Strings has the same shape. // identity`a${0}` const template = t.taggedTemplateExpression( identity, t.templateLiteral( path.node.quasi.quasis, expressions.map(() => t.numericLiteral(0)) ) ); processed.set(template, true); // Install an inline cache at the callsite using the global variable: // _t || (_t = identity`a${0}`) const ident = path.scope .getProgramParent() .generateDeclaredUidIdentifier("t"); path.scope.getBinding(ident.name).path.parent.kind = "let"; const inlineCache = t.logicalExpression( "||", ident, t.assignmentExpression("=", ident, template) ); // The original tag function becomes a plain function call. // The expressions omitted from the cached Strings tag are directly applied as arguments. // tag(_t || (_t = Object`a${0}`), 'hello') const node = t.callExpression(path.node.tag, [ inlineCache, ...expressions, ]); path.replaceWith(node); }, }, }); package/package.json 000644 0000005347 3560116604 011557 0 ustar 00 000000 000000 { "name": "@babel/preset-modules", "version": "0.1.4", "description": "A Babel preset that targets modern browsers by fixing engine bugs.", "main": "lib/index.js", "license": "MIT", "scripts": { "start": "concurrently -r 'npm:watch:* -s'", "build": "babel src -d lib --ignore '**/*.test.js'", "test": "eslint src test && jest --colors", "test:browser": "cd test/browser && karmatic --no-coverage --browsers chrome:headless,sauce-chrome-61,sauce-firefox-60,sauce-safari-10,sauce-safari-11,sauce-edge-16,sauce-edge-17 '**/*.js'", "test:local": "cd test/browser && karmatic --no-coverage '**/*.js'", "test:safari": "npm run test:local -- --browsers sauce-safari-10", "test:edge": "npm run test:local -- --browsers sauce-edge-16", "watch:test": "jest --watch", "watch:build": "npm run -s build -- -w" }, "keywords": [ "babel", "preset", "preset-env", "modern", "modules", "ES Modules", "module/nomodule" ], "files": [ "src", "lib" ], "lint-staged": { "*.js": [ "eslint --format=codeframe" ] }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "jest": { "testEnvironment": "node", "roots": [ "src", "test" ] }, "eslintConfig": { "extends": "developit", "rules": { "no-console": 0, "new-cap": 0 } }, "eslintIgnore": [ "test/fixtures/**/*", "test/integration/**/*" ], "authors": [ "Jason Miller