From c0816a71a405c40c7e8cc9cecae26942d126ba56 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Wed, 8 Feb 2017 23:18:59 +0100 Subject: [PATCH 01/10] Implement transform-built-ins plugin --- .../.npmignore | 4 + .../README.md | 51 ++++++++++++ .../__tests__/transform-built-ins.js | 64 +++++++++++++++ .../package.json | 17 ++++ .../src/builtins.js | 79 +++++++++++++++++++ .../src/index.js | 66 ++++++++++++++++ 6 files changed, 281 insertions(+) create mode 100644 packages/babel-plugin-transform-built-ins/.npmignore create mode 100644 packages/babel-plugin-transform-built-ins/README.md create mode 100644 packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js create mode 100644 packages/babel-plugin-transform-built-ins/package.json create mode 100644 packages/babel-plugin-transform-built-ins/src/builtins.js create mode 100644 packages/babel-plugin-transform-built-ins/src/index.js diff --git a/packages/babel-plugin-transform-built-ins/.npmignore b/packages/babel-plugin-transform-built-ins/.npmignore new file mode 100644 index 000000000..22250660e --- /dev/null +++ b/packages/babel-plugin-transform-built-ins/.npmignore @@ -0,0 +1,4 @@ +src +__tests__ +node_modules +*.log diff --git a/packages/babel-plugin-transform-built-ins/README.md b/packages/babel-plugin-transform-built-ins/README.md new file mode 100644 index 000000000..6c38ea34c --- /dev/null +++ b/packages/babel-plugin-transform-built-ins/README.md @@ -0,0 +1,51 @@ +# babel-plugin-transform-built-ins + +Transform Standard built-in Objects + +## Example + +**In** + +```javascript +Math.floor(2) + Math.floor(3) +``` + +**Out** + +```javascript +var _temp = Math.floor; + +_temp(2) + _temp(3); +``` + +## Installation + +```sh +npm install babel-plugin-transform-built-ins +``` + +## Usage + +### Via `.babelrc` (Recommended) + +**.babelrc** + +```json +{ + "plugins": ["transform-built-ins"] +} +``` + +### Via CLI + +```sh +babel --plugins transform-built-ins script.js +``` + +### Via Node API + +```javascript +require("babel-core").transform("code", { + plugins: ["transform-built-ins"] +}); +``` diff --git a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js new file mode 100644 index 000000000..0f103b009 --- /dev/null +++ b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js @@ -0,0 +1,64 @@ +jest.autoMockOff(); + +const babel = require("babel-core"); +const unpad = require("../../../utils/unpad"); +const plugin = require("../src/index"); + +function transform(code) { + return babel.transform(code, { + plugins: [plugin], + }).code; +} + +describe("transform-built-ins", () => { + it("should only transform standard built in methods", () => { + const source = unpad(` + Math.max(2, 1) + Math.max(1, 2) + `); + const expected = unpad(` + var _temp = Math.max; + _temp(2, 1) + _temp(1, 2); + `); + expect(transform(source)).toBe(expected); + }); + + it("should only transform standard built in properties", () => { + const source = unpad(` + function a () { + return Math.PI + Math.PI + } + `); + const expected = unpad(` + var _temp = Math.PI; + function a() { + return _temp + _temp; + } + `); + expect(transform(source)).toBe(expected); + }); + + it("should take no of occurences in to account", () => { + const source = unpad(` + function a() { + return Math.floor(1) + Math.floor(2) + Math.min(1, 2); + } + Math.floor(2, 1) + Math.sum(1, 2); + `); + const expected = unpad(` + var _temp = Math.floor; + function a() { + return _temp(1) + _temp(2) + Math.min(1, 2); + } + _temp(2, 1) + Math.sum(1, 2); + `); + expect(transform(source)).toBe(expected); + }); + + it("should not transform if its not a built in object", () => { + const source = unpad(` + Math.a(2, 1) + Math.a(1, 2); + `); + expect(transform(source)).toBe(source); + }); + +}); diff --git a/packages/babel-plugin-transform-built-ins/package.json b/packages/babel-plugin-transform-built-ins/package.json new file mode 100644 index 000000000..f51c3a162 --- /dev/null +++ b/packages/babel-plugin-transform-built-ins/package.json @@ -0,0 +1,17 @@ +{ + "name": "babel-plugin-transform-built-ins", + "version": "0.0.1", + "description": "Transform Standard built-in Objects", + "homepage": "https://github.com/babel/babili#readme", + "repository": "https://github.com/babel/babili/tree/master/packages/babel-plugin-transform-built-ins", + "main": "lib/index.js", + "bugs": "https://github.com/babel/babili/issues", + "keywords": [ + "babel-plugin", + "transform-built-ins" + ], + "author": "Vignesh Shanmugam (https://vigneshh.in)", + "license": "MIT", + "dependencies": {}, + "devDependencies": {} +} diff --git a/packages/babel-plugin-transform-built-ins/src/builtins.js b/packages/babel-plugin-transform-built-ins/src/builtins.js new file mode 100644 index 000000000..705a5bde4 --- /dev/null +++ b/packages/babel-plugin-transform-built-ins/src/builtins.js @@ -0,0 +1,79 @@ +module.exports = { + "properties": [ + "Number.EPSILON", + "Number.MAX_SAFE_INTEGER", + "Number.MAX_VALUE", + "Number.MIN_SAFE_INTEGER", + "Number.MIN_VALUE", + "Number.NEGATIVE_INFINITY", + "Number.POSITIVE_INFINITY", + "Number.NAN", + "Math.E", + "Math.LN10", + "Math.LN2", + "Math.LOG10E", + "Math.LOG2E", + "Math.PI", + "Math.SQRT1_2", + "Math.SQRT2" + ], + "methods": [ + "Number.isFinite", + "Number.isInteger", + "Number.isNaN", + "Number.isSafeInteger", + "Number.parseInt", + "Number.parseFloat", + "Date.now", + "Date.parse", + "Date.UTC", + "Math.min", + "Math.max", + "Math.floor", + "Math.abs", + "Math.acos", + "Math.acosh", + "Math.asin", + "Math.asinh", + "Math.atan", + "Math.atanh", + "Math.atan2", + "Math.ceil", + "Math.cbrt", + "Math.expm1", + "Math.clz32", + "Math.cos", + "Math.cosh", + "Math.exp", + "Math.floor", + "Math.fround", + "Math.hypot", + "Math.imul", + "Math.log", + "Math.log1p", + "Math.log2", + "Math.log10", + "Math.max", + "Math.min", + "Math.pow", + "Math.round", + "Math.sign", + "Math.sin", + "Math.sinh", + "Math.sqrt", + "Math.tan", + "Math.tanh", + "Math.trunc", + "Math.E", + "Math.LN10", + "Math.LN2", + "Math.LOG10E", + "Math.LOG2E", + "Math.PI", + "Math.SQRT1_2", + "Math.SQRT2", + "Math.random" + ] +}; + + diff --git a/packages/babel-plugin-transform-built-ins/src/index.js b/packages/babel-plugin-transform-built-ins/src/index.js new file mode 100644 index 000000000..e34727ef4 --- /dev/null +++ b/packages/babel-plugin-transform-built-ins/src/index.js @@ -0,0 +1,66 @@ +"use strict"; + +const { methods, properties } = require("./builtins"); + +function isBuiltin(expName) { + // Look for properties Eg - Number.PI + for (const property of properties) { + if (property === expName) { + return true; + } + } + // Look for Methods eg - Number.isNaN() + for (const method of methods) { + if (method === expName) { + return true; + } + } + return false; +} + +module.exports = function({ types: t }) { + const builtinsMap = new Map(); + + const collectVisitor = { + MemberExpression(path) { + const { node } = path.get("object"); + const { node: propertyNode } = path.get("property"); + const expName = `${node.name}.${propertyNode.name}`; + + if (isBuiltin(expName)) { + if (!builtinsMap.has(expName)) { + builtinsMap.set(expName, []); + } + builtinsMap.get(expName).push(path); + } + } + }; + + const replaceBuiltins = (programPath) => { + for (const paths of builtinsMap.values()) { + // Should only transform if there is more than 1 occurance + if (paths.length > 1) { + const uniqueIdentifier = programPath.scope.generateUidIdentifier(); + const newNode = t.variableDeclaration("var", [ + t.variableDeclarator(uniqueIdentifier, paths[0].node) + ]); + + for (const path of paths) { + path.replaceWith(uniqueIdentifier); + } + // hoist the created var to top of the program + programPath.unshiftContainer("body", newNode); + } + } + }; + + return { + name: "transform-builtins", + visitor: { + Program(path) { + path.traverse(collectVisitor); + replaceBuiltins(path); + } + }, + }; +}; From 7d3b38cd52ea54c2322a6279e939254b72654167 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Thu, 9 Feb 2017 14:44:14 +0100 Subject: [PATCH 02/10] fix tests and add to preset --- .../__tests__/transform-built-ins.js | 30 +++++++- .../src/index.js | 69 +++++++++++-------- .../__snapshots__/options-tests.js.snap | 10 +++ .../__tests__/options-tests.js | 1 + packages/babel-preset-babili/package.json | 1 + packages/babel-preset-babili/src/index.js | 2 + 6 files changed, 84 insertions(+), 29 deletions(-) diff --git a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js index 0f103b009..78a8be563 100644 --- a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js +++ b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js @@ -11,7 +11,7 @@ function transform(code) { } describe("transform-built-ins", () => { - it("should only transform standard built in methods", () => { + it("should transform standard built in methods", () => { const source = unpad(` Math.max(2, 1) + Math.max(1, 2) `); @@ -22,7 +22,7 @@ describe("transform-built-ins", () => { expect(transform(source)).toBe(expected); }); - it("should only transform standard built in properties", () => { + it("should transform standard built in properties", () => { const source = unpad(` function a () { return Math.PI + Math.PI @@ -54,6 +54,32 @@ describe("transform-built-ins", () => { expect(transform(source)).toBe(expected); }); + it("should collect and transform no matter any depth", () => { + const source = unpad(` + Math.max(2, 1) + Math.max(1, 2); + function a (){ + Math.max(2, 1); + return function b() { + const a = Math.floor(1); + Math.min(2, 1) * Math.floor(2); + } + } + `); + const expected = unpad(` + var _temp2 = Math.floor; + var _temp = Math.max; + _temp(2, 1) + _temp(1, 2); + function a() { + _temp(2, 1); + return function b() { + const a = _temp2(1); + Math.min(2, 1) * _temp2(2); + }; + } + `); + expect(transform(source)).toBe(expected); + }); + it("should not transform if its not a built in object", () => { const source = unpad(` Math.a(2, 1) + Math.a(1, 2); diff --git a/packages/babel-plugin-transform-built-ins/src/index.js b/packages/babel-plugin-transform-built-ins/src/index.js index e34727ef4..07feebd04 100644 --- a/packages/babel-plugin-transform-built-ins/src/index.js +++ b/packages/babel-plugin-transform-built-ins/src/index.js @@ -19,47 +19,62 @@ function isBuiltin(expName) { } module.exports = function({ types: t }) { - const builtinsMap = new Map(); - const collectVisitor = { - MemberExpression(path) { - const { node } = path.get("object"); - const { node: propertyNode } = path.get("property"); - const expName = `${node.name}.${propertyNode.name}`; + class BuiltInReplacer { + constructor(program) { + this.program = program; + this.pathsToUpdate = new Map; + } + + run() { + this.collect(); + this.replace(); + } + + collect() { + const context = this; + const collectVisitor = { + MemberExpression(path) { + const { node } = path.get("object"); + const { node: propertyNode } = path.get("property"); + const expName = `${node.name}.${propertyNode.name}`; - if (isBuiltin(expName)) { - if (!builtinsMap.has(expName)) { - builtinsMap.set(expName, []); + if (isBuiltin(expName)) { + if (!context.pathsToUpdate.has(expName)) { + context.pathsToUpdate.set(expName, []); + } + context.pathsToUpdate.get(expName).push(path); + } } - builtinsMap.get(expName).push(path); - } + }; + this.program.traverse(collectVisitor); } - }; - const replaceBuiltins = (programPath) => { - for (const paths of builtinsMap.values()) { - // Should only transform if there is more than 1 occurance - if (paths.length > 1) { - const uniqueIdentifier = programPath.scope.generateUidIdentifier(); - const newNode = t.variableDeclaration("var", [ - t.variableDeclarator(uniqueIdentifier, paths[0].node) - ]); + replace() { + for (const paths of this.pathsToUpdate.values()) { + // Should only transform if there is more than 1 occurence + if (paths.length > 1) { + const uniqueIdentifier = this.program.scope.generateUidIdentifier(); + const newNode = t.variableDeclaration("var", [ + t.variableDeclarator(uniqueIdentifier, paths[0].node) + ]); - for (const path of paths) { - path.replaceWith(uniqueIdentifier); + for (const path of paths) { + path.replaceWith(uniqueIdentifier); + } + // hoist the created var to top of the program + this.program.unshiftContainer("body", newNode); } - // hoist the created var to top of the program - programPath.unshiftContainer("body", newNode); } } - }; + } return { name: "transform-builtins", visitor: { Program(path) { - path.traverse(collectVisitor); - replaceBuiltins(path); + const builtInReplacer = new BuiltInReplacer(path); + builtInReplacer.run(); } }, }; diff --git a/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap b/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap index 3dad35702..a12d6569c 100644 --- a/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap +++ b/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap @@ -18,6 +18,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ], } @@ -48,6 +49,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ], } @@ -90,6 +92,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ], } @@ -142,6 +145,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ], } @@ -194,6 +198,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ], } @@ -222,6 +227,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ], } @@ -264,6 +270,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ], } @@ -289,6 +296,7 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ] `; @@ -313,6 +321,7 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ] `; @@ -337,6 +346,7 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", + "babel-plugin-transform-built-ins", "babel-plugin-transform-remove-undefined", ] `; diff --git a/packages/babel-preset-babili/__tests__/options-tests.js b/packages/babel-preset-babili/__tests__/options-tests.js index 2c83098e0..a1b3b1ecb 100644 --- a/packages/babel-preset-babili/__tests__/options-tests.js +++ b/packages/babel-preset-babili/__tests__/options-tests.js @@ -22,6 +22,7 @@ const mocks = [ "babel-plugin-transform-remove-undefined", "babel-plugin-transform-simplify-comparison-operators", "babel-plugin-transform-undefined-to-void", + "babel-plugin-transform-built-ins" ]; mocks.forEach((mockName) => { diff --git a/packages/babel-preset-babili/package.json b/packages/babel-preset-babili/package.json index 383b8ae41..4297f12a5 100644 --- a/packages/babel-preset-babili/package.json +++ b/packages/babel-preset-babili/package.json @@ -22,6 +22,7 @@ "babel-plugin-minify-replace": "^0.0.1", "babel-plugin-minify-simplify": "^0.0.7", "babel-plugin-minify-type-constructors": "^0.0.3", + "babel-plugin-transform-built-ins": "^0.0.1", "babel-plugin-transform-inline-consecutive-adds": "^0.0.2", "babel-plugin-transform-member-expression-literals": "^6.8.1", "babel-plugin-transform-merge-sibling-variables": "^6.8.2", diff --git a/packages/babel-preset-babili/src/index.js b/packages/babel-preset-babili/src/index.js index 1ae6ba704..236394124 100644 --- a/packages/babel-preset-babili/src/index.js +++ b/packages/babel-preset-babili/src/index.js @@ -26,6 +26,7 @@ const PLUGINS = [ ["simplifyComparisons", require("babel-plugin-transform-simplify-comparison-operators"), true], ["typeConstructors", require("babel-plugin-minify-type-constructors"), true], ["undefinedToVoid", require("babel-plugin-transform-undefined-to-void"), true], + ["builtIns", require("babel-plugin-transform-built-ins"), true], ]; module.exports = preset; @@ -77,6 +78,7 @@ function preset(context, _opts = {}) { optionsMap.booleans, optionsMap.undefinedToVoid, optionsMap.regexpConstructors, + optionsMap.builtIns, optionsMap.removeConsole, optionsMap.removeDebugger, From 9a6d50f69ea57b15971109c0f450c5be92b62de5 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Wed, 15 Feb 2017 18:11:57 +0100 Subject: [PATCH 03/10] optimize away expressions when necessary --- .../__tests__/transform-built-ins.js | 45 +++++++++++++------ .../package.json | 4 +- .../src/index.js | 40 ++++++++++++++++- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js index 78a8be563..9f11ef7a4 100644 --- a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js +++ b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js @@ -13,11 +13,11 @@ function transform(code) { describe("transform-built-ins", () => { it("should transform standard built in methods", () => { const source = unpad(` - Math.max(2, 1) + Math.max(1, 2) + Math.max(a, b) + Math.max(b, a) `); const expected = unpad(` var _temp = Math.max; - _temp(2, 1) + _temp(1, 2); + _temp(a, b) + _temp(b, a); `); expect(transform(source)).toBe(expected); }); @@ -40,40 +40,40 @@ describe("transform-built-ins", () => { it("should take no of occurences in to account", () => { const source = unpad(` function a() { - return Math.floor(1) + Math.floor(2) + Math.min(1, 2); + return Math.floor(a) + Math.floor(b) + Math.min(a, b); } - Math.floor(2, 1) + Math.sum(1, 2); + Math.floor(a) + Math.max(a, b); `); const expected = unpad(` var _temp = Math.floor; function a() { - return _temp(1) + _temp(2) + Math.min(1, 2); + return _temp(a) + _temp(b) + Math.min(a, b); } - _temp(2, 1) + Math.sum(1, 2); + _temp(a) + Math.max(a, b); `); expect(transform(source)).toBe(expected); }); it("should collect and transform no matter any depth", () => { const source = unpad(` - Math.max(2, 1) + Math.max(1, 2); + Math.max(a, b) + Math.max(a, b); function a (){ - Math.max(2, 1); + Math.max(b, a); return function b() { - const a = Math.floor(1); - Math.min(2, 1) * Math.floor(2); + const a = Math.floor(c); + Math.min(b, a) * Math.floor(b); } } `); const expected = unpad(` var _temp2 = Math.floor; var _temp = Math.max; - _temp(2, 1) + _temp(1, 2); + _temp(a, b) + _temp(a, b); function a() { - _temp(2, 1); + _temp(b, a); return function b() { - const a = _temp2(1); - Math.min(2, 1) * _temp2(2); + const a = _temp2(c); + Math.min(b, a) * _temp2(b); }; } `); @@ -87,4 +87,21 @@ describe("transform-built-ins", () => { expect(transform(source)).toBe(source); }); + it("should evalaute expressions if applicable and optimize it", () => { + const source = unpad(` + const a = Math.max(Math.floor(2), 5); + let b = 1.8; + let x = Math.floor(Math.max(a, b)); + foo(x); + `); + + const expected = unpad(` + const a = 5; + let b = 1.8; + let x = 5; + foo(x); + `); + expect(transform(source)).toBe(expected); + }); + }); diff --git a/packages/babel-plugin-transform-built-ins/package.json b/packages/babel-plugin-transform-built-ins/package.json index f51c3a162..1fdc6f2da 100644 --- a/packages/babel-plugin-transform-built-ins/package.json +++ b/packages/babel-plugin-transform-built-ins/package.json @@ -12,6 +12,8 @@ ], "author": "Vignesh Shanmugam (https://vigneshh.in)", "license": "MIT", - "dependencies": {}, + "dependencies": { + "babel-helper-evaluate-path": "^0.0.3" + }, "devDependencies": {} } diff --git a/packages/babel-plugin-transform-built-ins/src/index.js b/packages/babel-plugin-transform-built-ins/src/index.js index 07feebd04..d7d3ca35e 100644 --- a/packages/babel-plugin-transform-built-ins/src/index.js +++ b/packages/babel-plugin-transform-built-ins/src/index.js @@ -1,6 +1,7 @@ "use strict"; const { methods, properties } = require("./builtins"); +const evaluate = require("babel-helper-evaluate-path"); function isBuiltin(expName) { // Look for properties Eg - Number.PI @@ -33,8 +34,41 @@ module.exports = function({ types: t }) { collect() { const context = this; - const collectVisitor = { + + const methodVisitor = { + CallExpression: { + exit(path) { + const callee = path.get("callee"); + if (!t.isMemberExpression(callee)) { + return; + } + const { node } = callee.get("object"); + const { node: propertyNode } = callee.get("property"); + const expName = `${node.name}.${propertyNode.name}`; + + if (isBuiltin(expName)) { + const result = evaluate(path); + // Math.floor(1) --> 1 + if (result.confident && typeof result.value === "number") { + path.replaceWith(t.numericLiteral(result.value)); + } else { + if (!context.pathsToUpdate.has(expName)) { + context.pathsToUpdate.set(expName, []); + } + context.pathsToUpdate.get(expName).push(callee); + } + } + } + } + }; + + const propertyVisitor = { MemberExpression(path) { + const { parent } = path; + if (t.isCallExpression(parent)) { + return; + } + const { node } = path.get("object"); const { node: propertyNode } = path.get("property"); const expName = `${node.name}.${propertyNode.name}`; @@ -47,7 +81,9 @@ module.exports = function({ types: t }) { } } }; - this.program.traverse(collectVisitor); + + this.program.traverse(methodVisitor); + this.program.traverse(propertyVisitor); } replace() { From 5e3b23fe6ec2553a0382276aedeff6e92ffc7003 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Wed, 15 Feb 2017 18:33:28 +0100 Subject: [PATCH 04/10] single pass visitor and update snapshots --- .../__snapshots__/transform-built-ins.js.snap | 76 +++++++++++++++ .../__tests__/transform-built-ins.js | 49 ++-------- .../src/index.js | 97 +++++++++++-------- 3 files changed, 137 insertions(+), 85 deletions(-) create mode 100644 packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap diff --git a/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap b/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap new file mode 100644 index 000000000..a4f5f3f6b --- /dev/null +++ b/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap @@ -0,0 +1,76 @@ +exports[`transform-built-ins should collect and transform no matter any depth 1`] = ` +Object { + "_source": "Math.max(a, b) + Math.max(a, b); +function a (){ + Math.max(b, a); + return function b() { + const a = Math.floor(c); + Math.min(b, a) * Math.floor(b); + } +}", + "expected": "var _Mathfloor = Math.floor; +var _Mathmax = Math.max; +_Mathmax(a, b) + _Mathmax(a, b); +function a() { + _Mathmax(b, a); + return function b() { + const a = _Mathfloor(c); + Math.min(b, a) * _Mathfloor(b); + }; +}", +} +`; + +exports[`transform-built-ins should evalaute expressions if applicable and optimize it 1`] = ` +Object { + "_source": "const a = Math.max(Math.floor(2), 5); +let b = 1.8; +let x = Math.floor(Math.max(a, b)); +foo(x);", + "expected": "const a = 5; +let b = 1.8; +let x = 5; +foo(x);", +} +`; + +exports[`transform-built-ins should not transform if its not a built in object 1`] = ` +Object { + "_source": "Math.a(2, 1) + Math.a(1, 2);", + "expected": "Math.a(2, 1) + Math.a(1, 2);", +} +`; + +exports[`transform-built-ins should take no of occurences in to account 1`] = ` +Object { + "_source": "function a() { + return Math.floor(a) + Math.floor(b) + Math.min(a, b); +} +Math.floor(a) + Math.max(a, b);", + "expected": "var _Mathfloor = Math.floor; +function a() { + return _Mathfloor(a) + _Mathfloor(b) + Math.min(a, b); +} +_Mathfloor(a) + Math.max(a, b);", +} +`; + +exports[`transform-built-ins should transform standard built in methods 1`] = ` +Object { + "_source": "Math.max(a, b) + Math.max(b, a)", + "expected": "var _Mathmax = Math.max; +_Mathmax(a, b) + _Mathmax(b, a);", +} +`; + +exports[`transform-built-ins should transform standard built in properties 1`] = ` +Object { + "_source": "function a () { + return Math.PI + Math.PI +}", + "expected": "var _MathPI = Math.PI; +function a() { + return _MathPI + _MathPI; +}", +} +`; diff --git a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js index 9f11ef7a4..abc1041c6 100644 --- a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js +++ b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js @@ -15,11 +15,8 @@ describe("transform-built-ins", () => { const source = unpad(` Math.max(a, b) + Math.max(b, a) `); - const expected = unpad(` - var _temp = Math.max; - _temp(a, b) + _temp(b, a); - `); - expect(transform(source)).toBe(expected); + // Jest arranges in alphabetical order, So keeping it as _source + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); it("should transform standard built in properties", () => { @@ -28,13 +25,7 @@ describe("transform-built-ins", () => { return Math.PI + Math.PI } `); - const expected = unpad(` - var _temp = Math.PI; - function a() { - return _temp + _temp; - } - `); - expect(transform(source)).toBe(expected); + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); it("should take no of occurences in to account", () => { @@ -44,14 +35,7 @@ describe("transform-built-ins", () => { } Math.floor(a) + Math.max(a, b); `); - const expected = unpad(` - var _temp = Math.floor; - function a() { - return _temp(a) + _temp(b) + Math.min(a, b); - } - _temp(a) + Math.max(a, b); - `); - expect(transform(source)).toBe(expected); + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); it("should collect and transform no matter any depth", () => { @@ -65,26 +49,14 @@ describe("transform-built-ins", () => { } } `); - const expected = unpad(` - var _temp2 = Math.floor; - var _temp = Math.max; - _temp(a, b) + _temp(a, b); - function a() { - _temp(b, a); - return function b() { - const a = _temp2(c); - Math.min(b, a) * _temp2(b); - }; - } - `); - expect(transform(source)).toBe(expected); + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); it("should not transform if its not a built in object", () => { const source = unpad(` Math.a(2, 1) + Math.a(1, 2); `); - expect(transform(source)).toBe(source); + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); it("should evalaute expressions if applicable and optimize it", () => { @@ -94,14 +66,7 @@ describe("transform-built-ins", () => { let x = Math.floor(Math.max(a, b)); foo(x); `); - - const expected = unpad(` - const a = 5; - let b = 1.8; - let x = 5; - foo(x); - `); - expect(transform(source)).toBe(expected); + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); }); diff --git a/packages/babel-plugin-transform-built-ins/src/index.js b/packages/babel-plugin-transform-built-ins/src/index.js index d7d3ca35e..d00e0b24a 100644 --- a/packages/babel-plugin-transform-built-ins/src/index.js +++ b/packages/babel-plugin-transform-built-ins/src/index.js @@ -3,21 +3,7 @@ const { methods, properties } = require("./builtins"); const evaluate = require("babel-helper-evaluate-path"); -function isBuiltin(expName) { - // Look for properties Eg - Number.PI - for (const property of properties) { - if (property === expName) { - return true; - } - } - // Look for Methods eg - Number.isNaN() - for (const method of methods) { - if (method === expName) { - return true; - } - } - return false; -} + module.exports = function({ types: t }) { @@ -35,17 +21,28 @@ module.exports = function({ types: t }) { collect() { const context = this; - const methodVisitor = { + const collectVisitor = { + MemberExpression(path) { + if (path.parentPath.isCallExpression()) { + return; + } + + const expName = getExpressionName(path); + if (isBuiltin(expName)) { + if (!context.pathsToUpdate.has(expName)) { + context.pathsToUpdate.set(expName, []); + } + context.pathsToUpdate.get(expName).push(path); + } + }, CallExpression: { exit(path) { const callee = path.get("callee"); - if (!t.isMemberExpression(callee)) { + if (!callee.isMemberExpression()) { return; } - const { node } = callee.get("object"); - const { node: propertyNode } = callee.get("property"); - const expName = `${node.name}.${propertyNode.name}`; + const expName = getExpressionName(callee); if (isBuiltin(expName)) { const result = evaluate(path); // Math.floor(1) --> 1 @@ -62,35 +59,16 @@ module.exports = function({ types: t }) { } }; - const propertyVisitor = { - MemberExpression(path) { - const { parent } = path; - if (t.isCallExpression(parent)) { - return; - } - - const { node } = path.get("object"); - const { node: propertyNode } = path.get("property"); - const expName = `${node.name}.${propertyNode.name}`; - - if (isBuiltin(expName)) { - if (!context.pathsToUpdate.has(expName)) { - context.pathsToUpdate.set(expName, []); - } - context.pathsToUpdate.get(expName).push(path); - } - } - }; - - this.program.traverse(methodVisitor); - this.program.traverse(propertyVisitor); + this.program.traverse(collectVisitor); } replace() { for (const paths of this.pathsToUpdate.values()) { // Should only transform if there is more than 1 occurence if (paths.length > 1) { - const uniqueIdentifier = this.program.scope.generateUidIdentifier(); + const uniqueIdentifier = this.program.scope.generateUidIdentifier( + memberToString(paths[0]) + ); const newNode = t.variableDeclaration("var", [ t.variableDeclarator(uniqueIdentifier, paths[0].node) ]); @@ -114,4 +92,37 @@ module.exports = function({ types: t }) { } }, }; + + function memberToString(memberExpr) { + const {object, property} = memberExpr.node; + let result = ""; + + if (t.isIdentifier(object)) result += object.name; + if (t.isMemberExpression(object)) result += memberToString(object); + if (t.isIdentifier(property)) result += property.name; + + return result; + } }; + +function isBuiltin(expName) { + // Look for properties Eg - Number.PI + for (const property of properties) { + if (property === expName) { + return true; + } + } + // Look for Methods eg - Number.isNaN() + for (const method of methods) { + if (method === expName) { + return true; + } + } + return false; +} + +function getExpressionName(path) { + const { node } = path.get("object"); + const { node: propertyNode } = path.get("property"); + return `${node.name}.${propertyNode.name}`; +} From 39eed5d5aaea57cef2367cdaef35501a7f231d8d Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Wed, 15 Feb 2017 18:34:49 +0100 Subject: [PATCH 05/10] Update readme --- packages/babel-plugin-transform-built-ins/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/babel-plugin-transform-built-ins/README.md b/packages/babel-plugin-transform-built-ins/README.md index 6c38ea34c..b9ddecae8 100644 --- a/packages/babel-plugin-transform-built-ins/README.md +++ b/packages/babel-plugin-transform-built-ins/README.md @@ -7,15 +7,15 @@ Transform Standard built-in Objects **In** ```javascript -Math.floor(2) + Math.floor(3) +Math.floor(a) + Math.floor(b) ``` **Out** ```javascript -var _temp = Math.floor; +var _Mathfloor = Math.floor; -_temp(2) + _temp(3); +_Mathfloor(a) + _Mathfloor(b); ``` ## Installation From 06b44cf005c240cf2f06c8dc5d852f9717c44fd7 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Thu, 16 Feb 2017 11:48:18 +0100 Subject: [PATCH 06/10] fix computed properties and depot if impure --- .../__snapshots__/transform-built-ins.js.snap | 16 +++++++++++ .../__tests__/transform-built-ins.js | 15 ++++++++++ .../src/builtins.js | 2 -- .../src/index.js | 28 +++++++++++++++---- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap b/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap index a4f5f3f6b..59e6c0e1d 100644 --- a/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap +++ b/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap @@ -34,6 +34,22 @@ foo(x);", } `; +exports[`transform-built-ins should not evaluate if its has side effecty arguments 1`] = ` +Object { + "_source": "Math.max(foo(), 1);", + "expected": "Math.max(foo(), 1);", +} +`; + +exports[`transform-built-ins should not transform for computed properties 1`] = ` +Object { + "_source": "let max = \"floor\"; +Math[max](1.5);", + "expected": "let max = \"floor\"; +Math[max](1.5);", +} +`; + exports[`transform-built-ins should not transform if its not a built in object 1`] = ` Object { "_source": "Math.a(2, 1) + Math.a(1, 2);", diff --git a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js index abc1041c6..d4e674356 100644 --- a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js +++ b/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js @@ -69,4 +69,19 @@ describe("transform-built-ins", () => { expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); + it("should not evaluate if its has side effecty arguments", () => { + const source = unpad(` + Math.max(foo(), 1); + `); + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); + }); + + it("should not transform for computed properties", () => { + const source = unpad(` + let max = "floor"; + Math[max](1.5); + `); + expect({_source: source, expected: transform(source)}).toMatchSnapshot(); + }); + }); diff --git a/packages/babel-plugin-transform-built-ins/src/builtins.js b/packages/babel-plugin-transform-built-ins/src/builtins.js index 705a5bde4..0ca8c0252 100644 --- a/packages/babel-plugin-transform-built-ins/src/builtins.js +++ b/packages/babel-plugin-transform-built-ins/src/builtins.js @@ -75,5 +75,3 @@ module.exports = { "Math.random" ] }; - - diff --git a/packages/babel-plugin-transform-built-ins/src/index.js b/packages/babel-plugin-transform-built-ins/src/index.js index d00e0b24a..7bbfecbf6 100644 --- a/packages/babel-plugin-transform-built-ins/src/index.js +++ b/packages/babel-plugin-transform-built-ins/src/index.js @@ -3,8 +3,6 @@ const { methods, properties } = require("./builtins"); const evaluate = require("babel-helper-evaluate-path"); - - module.exports = function({ types: t }) { class BuiltInReplacer { @@ -28,7 +26,7 @@ module.exports = function({ types: t }) { } const expName = getExpressionName(path); - if (isBuiltin(expName)) { + if (!isComputed(path) && isBuiltin(expName)) { if (!context.pathsToUpdate.has(expName)) { context.pathsToUpdate.set(expName, []); } @@ -43,10 +41,15 @@ module.exports = function({ types: t }) { } const expName = getExpressionName(callee); - if (isBuiltin(expName)) { + // computed property should be not optimized + // Math[max]() -> Math.max() + if (!isComputed(callee) && isBuiltin(expName)) { const result = evaluate(path); + // deopt when we have side effecty evaluate-able arguments + // Math.max(foo(), 1) --> untouched // Math.floor(1) --> 1 - if (result.confident && typeof result.value === "number") { + if (result.confident && hasPureArgs(path) + && typeof result.value === "number") { path.replaceWith(t.numericLiteral(result.value)); } else { if (!context.pathsToUpdate.has(expName)) { @@ -105,6 +108,21 @@ module.exports = function({ types: t }) { } }; +function hasPureArgs(path) { + const args = path.get("arguments"); + for (const arg of args) { + if (!arg.isPure()) { + return false; + } + } + return true; +} + +function isComputed(path) { + const { node } = path; + return node.computed; +} + function isBuiltin(expName) { // Look for properties Eg - Number.PI for (const property of properties) { From 4cfdfba4de0b120dadaa1854ef6c95749c005043 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Thu, 16 Feb 2017 17:54:26 +0100 Subject: [PATCH 07/10] rename plugin and use builts from babel --- .../.npmignore | 0 .../README.md | 12 +-- .../__snapshots__/minify-builtins.js.snap} | 57 ++++++-------- .../__tests__/minify-builtins.js} | 17 ++-- .../package.json | 6 +- .../src/index.js | 58 ++++++-------- .../src/builtins.js | 77 ------------------- .../__snapshots__/options-tests.js.snap | 20 ++--- .../__tests__/options-tests.js | 4 +- packages/babel-preset-babili/package.json | 2 +- packages/babel-preset-babili/src/index.js | 2 +- 11 files changed, 78 insertions(+), 177 deletions(-) rename packages/{babel-plugin-transform-built-ins => babel-plugin-minify-builtins}/.npmignore (100%) rename packages/{babel-plugin-transform-built-ins => babel-plugin-minify-builtins}/README.md (61%) rename packages/{babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap => babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap} (64%) rename packages/{babel-plugin-transform-built-ins/__tests__/transform-built-ins.js => babel-plugin-minify-builtins/__tests__/minify-builtins.js} (79%) rename packages/{babel-plugin-transform-built-ins => babel-plugin-minify-builtins}/package.json (77%) rename packages/{babel-plugin-transform-built-ins => babel-plugin-minify-builtins}/src/index.js (75%) delete mode 100644 packages/babel-plugin-transform-built-ins/src/builtins.js diff --git a/packages/babel-plugin-transform-built-ins/.npmignore b/packages/babel-plugin-minify-builtins/.npmignore similarity index 100% rename from packages/babel-plugin-transform-built-ins/.npmignore rename to packages/babel-plugin-minify-builtins/.npmignore diff --git a/packages/babel-plugin-transform-built-ins/README.md b/packages/babel-plugin-minify-builtins/README.md similarity index 61% rename from packages/babel-plugin-transform-built-ins/README.md rename to packages/babel-plugin-minify-builtins/README.md index b9ddecae8..2e23c7e0c 100644 --- a/packages/babel-plugin-transform-built-ins/README.md +++ b/packages/babel-plugin-minify-builtins/README.md @@ -1,6 +1,6 @@ -# babel-plugin-transform-built-ins +# babel-plugin-minify-builtins -Transform Standard built-in Objects +Minify Standard built-in Objects ## Example @@ -21,7 +21,7 @@ _Mathfloor(a) + _Mathfloor(b); ## Installation ```sh -npm install babel-plugin-transform-built-ins +npm install babel-plugin-minify-builtins ``` ## Usage @@ -32,20 +32,20 @@ npm install babel-plugin-transform-built-ins ```json { - "plugins": ["transform-built-ins"] + "plugins": ["minify-builtins"] } ``` ### Via CLI ```sh -babel --plugins transform-built-ins script.js +babel --plugins minify-builtins script.js ``` ### Via Node API ```javascript require("babel-core").transform("code", { - plugins: ["transform-built-ins"] + plugins: ["minify-builtins"] }); ``` diff --git a/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap b/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap similarity index 64% rename from packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap rename to packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap index 59e6c0e1d..d31224a1a 100644 --- a/packages/babel-plugin-transform-built-ins/__tests__/__snapshots__/transform-built-ins.js.snap +++ b/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap @@ -1,4 +1,4 @@ -exports[`transform-built-ins should collect and transform no matter any depth 1`] = ` +exports[`minify-builtins should collect and minify no matter any depth 1`] = ` Object { "_source": "Math.max(a, b) + Math.max(a, b); function a (){ @@ -21,7 +21,7 @@ function a() { } `; -exports[`transform-built-ins should evalaute expressions if applicable and optimize it 1`] = ` +exports[`minify-builtins should evalaute expressions if applicable and optimize it 1`] = ` Object { "_source": "const a = Math.max(Math.floor(2), 5); let b = 1.8; @@ -34,14 +34,34 @@ foo(x);", } `; -exports[`transform-built-ins should not evaluate if its has side effecty arguments 1`] = ` +exports[`minify-builtins should minify standard built in methods 1`] = ` +Object { + "_source": "Math.max(a, b) + Math.max(b, a)", + "expected": "var _Mathmax = Math.max; +_Mathmax(a, b) + _Mathmax(b, a);", +} +`; + +exports[`minify-builtins should minify standard built in properties 1`] = ` +Object { + "_source": "function a () { + return Math.PI + Math.PI +}", + "expected": "var _MathPI = Math.PI; +function a() { + return _MathPI + _MathPI; +}", +} +`; + +exports[`minify-builtins should not evaluate if its has side effecty arguments 1`] = ` Object { "_source": "Math.max(foo(), 1);", "expected": "Math.max(foo(), 1);", } `; -exports[`transform-built-ins should not transform for computed properties 1`] = ` +exports[`minify-builtins should not minify for computed properties 1`] = ` Object { "_source": "let max = \"floor\"; Math[max](1.5);", @@ -50,14 +70,7 @@ Math[max](1.5);", } `; -exports[`transform-built-ins should not transform if its not a built in object 1`] = ` -Object { - "_source": "Math.a(2, 1) + Math.a(1, 2);", - "expected": "Math.a(2, 1) + Math.a(1, 2);", -} -`; - -exports[`transform-built-ins should take no of occurences in to account 1`] = ` +exports[`minify-builtins should take no of occurences in to account 1`] = ` Object { "_source": "function a() { return Math.floor(a) + Math.floor(b) + Math.min(a, b); @@ -70,23 +83,3 @@ function a() { _Mathfloor(a) + Math.max(a, b);", } `; - -exports[`transform-built-ins should transform standard built in methods 1`] = ` -Object { - "_source": "Math.max(a, b) + Math.max(b, a)", - "expected": "var _Mathmax = Math.max; -_Mathmax(a, b) + _Mathmax(b, a);", -} -`; - -exports[`transform-built-ins should transform standard built in properties 1`] = ` -Object { - "_source": "function a () { - return Math.PI + Math.PI -}", - "expected": "var _MathPI = Math.PI; -function a() { - return _MathPI + _MathPI; -}", -} -`; diff --git a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js b/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js similarity index 79% rename from packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js rename to packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js index d4e674356..2b1e16883 100644 --- a/packages/babel-plugin-transform-built-ins/__tests__/transform-built-ins.js +++ b/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js @@ -10,8 +10,8 @@ function transform(code) { }).code; } -describe("transform-built-ins", () => { - it("should transform standard built in methods", () => { +describe("minify-builtins", () => { + it("should minify standard built in methods", () => { const source = unpad(` Math.max(a, b) + Math.max(b, a) `); @@ -19,7 +19,7 @@ describe("transform-built-ins", () => { expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); - it("should transform standard built in properties", () => { + it("should minify standard built in properties", () => { const source = unpad(` function a () { return Math.PI + Math.PI @@ -38,7 +38,7 @@ describe("transform-built-ins", () => { expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); - it("should collect and transform no matter any depth", () => { + it("should collect and minify no matter any depth", () => { const source = unpad(` Math.max(a, b) + Math.max(a, b); function a (){ @@ -52,13 +52,6 @@ describe("transform-built-ins", () => { expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); - it("should not transform if its not a built in object", () => { - const source = unpad(` - Math.a(2, 1) + Math.a(1, 2); - `); - expect({_source: source, expected: transform(source)}).toMatchSnapshot(); - }); - it("should evalaute expressions if applicable and optimize it", () => { const source = unpad(` const a = Math.max(Math.floor(2), 5); @@ -76,7 +69,7 @@ describe("transform-built-ins", () => { expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); - it("should not transform for computed properties", () => { + it("should not minify for computed properties", () => { const source = unpad(` let max = "floor"; Math[max](1.5); diff --git a/packages/babel-plugin-transform-built-ins/package.json b/packages/babel-plugin-minify-builtins/package.json similarity index 77% rename from packages/babel-plugin-transform-built-ins/package.json rename to packages/babel-plugin-minify-builtins/package.json index 1fdc6f2da..9af2775ab 100644 --- a/packages/babel-plugin-transform-built-ins/package.json +++ b/packages/babel-plugin-minify-builtins/package.json @@ -1,9 +1,9 @@ { - "name": "babel-plugin-transform-built-ins", + "name": "babel-plugin-minify-builtins", "version": "0.0.1", - "description": "Transform Standard built-in Objects", + "description": "Minify Standard built-in Objects", "homepage": "https://github.com/babel/babili#readme", - "repository": "https://github.com/babel/babili/tree/master/packages/babel-plugin-transform-built-ins", + "repository": "https://github.com/babel/babili/tree/master/packages/babel-plugin-minify-builtins", "main": "lib/index.js", "bugs": "https://github.com/babel/babili/issues", "keywords": [ diff --git a/packages/babel-plugin-transform-built-ins/src/index.js b/packages/babel-plugin-minify-builtins/src/index.js similarity index 75% rename from packages/babel-plugin-transform-built-ins/src/index.js rename to packages/babel-plugin-minify-builtins/src/index.js index 7bbfecbf6..981f4a79a 100644 --- a/packages/babel-plugin-transform-built-ins/src/index.js +++ b/packages/babel-plugin-minify-builtins/src/index.js @@ -1,7 +1,10 @@ "use strict"; -const { methods, properties } = require("./builtins"); const evaluate = require("babel-helper-evaluate-path"); +// Assuming all the static methods from below array are side effect free evaluation +// except Math.random +const VALID_CALLEES = ["String", "Number", "Math"]; +const INVALID_METHODS = ["random"]; module.exports = function({ types: t }) { @@ -25,14 +28,15 @@ module.exports = function({ types: t }) { return; } - const expName = getExpressionName(path); - if (!isComputed(path) && isBuiltin(expName)) { + const expName = memberToString(path); + if (!isComputed(path) && isBuiltin(path)) { if (!context.pathsToUpdate.has(expName)) { context.pathsToUpdate.set(expName, []); } context.pathsToUpdate.get(expName).push(path); } }, + CallExpression: { exit(path) { const callee = path.get("callee"); @@ -40,10 +44,10 @@ module.exports = function({ types: t }) { return; } - const expName = getExpressionName(callee); + const expName = memberToString(callee); // computed property should be not optimized // Math[max]() -> Math.max() - if (!isComputed(callee) && isBuiltin(expName)) { + if (!isComputed(callee) && isBuiltin(callee)) { const result = evaluate(path); // deopt when we have side effecty evaluate-able arguments // Math.max(foo(), 1) --> untouched @@ -66,12 +70,10 @@ module.exports = function({ types: t }) { } replace() { - for (const paths of this.pathsToUpdate.values()) { + for (const [ expName, paths ] of this.pathsToUpdate) { // Should only transform if there is more than 1 occurence if (paths.length > 1) { - const uniqueIdentifier = this.program.scope.generateUidIdentifier( - memberToString(paths[0]) - ); + const uniqueIdentifier = this.program.scope.generateUidIdentifier(expName); const newNode = t.variableDeclaration("var", [ t.variableDeclarator(uniqueIdentifier, paths[0].node) ]); @@ -87,7 +89,7 @@ module.exports = function({ types: t }) { } return { - name: "transform-builtins", + name: "minify-builtins", visitor: { Program(path) { const builtInReplacer = new BuiltInReplacer(path); @@ -97,7 +99,7 @@ module.exports = function({ types: t }) { }; function memberToString(memberExpr) { - const {object, property} = memberExpr.node; + const { object, property } = memberExpr.node; let result = ""; if (t.isIdentifier(object)) result += object.name; @@ -106,6 +108,18 @@ module.exports = function({ types: t }) { return result; } + + function isBuiltin(memberExpr) { + const { object, property } = memberExpr.node; + + if (t.isIdentifier(object) && t.isIdentifier(property) + && VALID_CALLEES.includes(object.name) + && !INVALID_METHODS.includes(property.name)) { + return true; + } + return false; + } + }; function hasPureArgs(path) { @@ -122,25 +136,3 @@ function isComputed(path) { const { node } = path; return node.computed; } - -function isBuiltin(expName) { - // Look for properties Eg - Number.PI - for (const property of properties) { - if (property === expName) { - return true; - } - } - // Look for Methods eg - Number.isNaN() - for (const method of methods) { - if (method === expName) { - return true; - } - } - return false; -} - -function getExpressionName(path) { - const { node } = path.get("object"); - const { node: propertyNode } = path.get("property"); - return `${node.name}.${propertyNode.name}`; -} diff --git a/packages/babel-plugin-transform-built-ins/src/builtins.js b/packages/babel-plugin-transform-built-ins/src/builtins.js deleted file mode 100644 index 0ca8c0252..000000000 --- a/packages/babel-plugin-transform-built-ins/src/builtins.js +++ /dev/null @@ -1,77 +0,0 @@ -module.exports = { - "properties": [ - "Number.EPSILON", - "Number.MAX_SAFE_INTEGER", - "Number.MAX_VALUE", - "Number.MIN_SAFE_INTEGER", - "Number.MIN_VALUE", - "Number.NEGATIVE_INFINITY", - "Number.POSITIVE_INFINITY", - "Number.NAN", - "Math.E", - "Math.LN10", - "Math.LN2", - "Math.LOG10E", - "Math.LOG2E", - "Math.PI", - "Math.SQRT1_2", - "Math.SQRT2" - ], - "methods": [ - "Number.isFinite", - "Number.isInteger", - "Number.isNaN", - "Number.isSafeInteger", - "Number.parseInt", - "Number.parseFloat", - "Date.now", - "Date.parse", - "Date.UTC", - "Math.min", - "Math.max", - "Math.floor", - "Math.abs", - "Math.acos", - "Math.acosh", - "Math.asin", - "Math.asinh", - "Math.atan", - "Math.atanh", - "Math.atan2", - "Math.ceil", - "Math.cbrt", - "Math.expm1", - "Math.clz32", - "Math.cos", - "Math.cosh", - "Math.exp", - "Math.floor", - "Math.fround", - "Math.hypot", - "Math.imul", - "Math.log", - "Math.log1p", - "Math.log2", - "Math.log10", - "Math.max", - "Math.min", - "Math.pow", - "Math.round", - "Math.sign", - "Math.sin", - "Math.sinh", - "Math.sqrt", - "Math.tan", - "Math.tanh", - "Math.trunc", - "Math.E", - "Math.LN10", - "Math.LN2", - "Math.LOG10E", - "Math.LOG2E", - "Math.PI", - "Math.SQRT1_2", - "Math.SQRT2", - "Math.random" - ] -}; diff --git a/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap b/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap index a12d6569c..32c04cc7e 100644 --- a/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap +++ b/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap @@ -18,7 +18,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -49,7 +49,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -92,7 +92,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -145,7 +145,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -198,7 +198,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -227,7 +227,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -270,7 +270,7 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -296,7 +296,7 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ] `; @@ -321,7 +321,7 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ] `; @@ -346,7 +346,7 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-transform-built-ins", + "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ] `; diff --git a/packages/babel-preset-babili/__tests__/options-tests.js b/packages/babel-preset-babili/__tests__/options-tests.js index a1b3b1ecb..e67b1a1fb 100644 --- a/packages/babel-preset-babili/__tests__/options-tests.js +++ b/packages/babel-preset-babili/__tests__/options-tests.js @@ -1,6 +1,7 @@ jest.autoMockOff(); const mocks = [ + "babel-plugin-minify-builtins", "babel-plugin-minify-constant-folding", "babel-plugin-minify-dead-code-elimination", "babel-plugin-minify-flip-comparisons", @@ -21,8 +22,7 @@ const mocks = [ "babel-plugin-transform-remove-debugger", "babel-plugin-transform-remove-undefined", "babel-plugin-transform-simplify-comparison-operators", - "babel-plugin-transform-undefined-to-void", - "babel-plugin-transform-built-ins" + "babel-plugin-transform-undefined-to-void" ]; mocks.forEach((mockName) => { diff --git a/packages/babel-preset-babili/package.json b/packages/babel-preset-babili/package.json index 4297f12a5..4ccd821a7 100644 --- a/packages/babel-preset-babili/package.json +++ b/packages/babel-preset-babili/package.json @@ -12,6 +12,7 @@ "babel-preset" ], "dependencies": { + "babel-plugin-minify-builtins": "^0.0.1", "babel-plugin-minify-constant-folding": "^0.0.4", "babel-plugin-minify-dead-code-elimination": "^0.1.3", "babel-plugin-minify-flip-comparisons": "^0.0.2", @@ -22,7 +23,6 @@ "babel-plugin-minify-replace": "^0.0.1", "babel-plugin-minify-simplify": "^0.0.7", "babel-plugin-minify-type-constructors": "^0.0.3", - "babel-plugin-transform-built-ins": "^0.0.1", "babel-plugin-transform-inline-consecutive-adds": "^0.0.2", "babel-plugin-transform-member-expression-literals": "^6.8.1", "babel-plugin-transform-merge-sibling-variables": "^6.8.2", diff --git a/packages/babel-preset-babili/src/index.js b/packages/babel-preset-babili/src/index.js index 236394124..2c394f767 100644 --- a/packages/babel-preset-babili/src/index.js +++ b/packages/babel-preset-babili/src/index.js @@ -26,7 +26,7 @@ const PLUGINS = [ ["simplifyComparisons", require("babel-plugin-transform-simplify-comparison-operators"), true], ["typeConstructors", require("babel-plugin-minify-type-constructors"), true], ["undefinedToVoid", require("babel-plugin-transform-undefined-to-void"), true], - ["builtIns", require("babel-plugin-transform-built-ins"), true], + ["builtIns", require("babel-plugin-minify-builtins"), true], ]; module.exports = preset; From 99a7bce2be52926ac2d252d3e9d9d427765ea97f Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Thu, 16 Feb 2017 22:02:33 +0100 Subject: [PATCH 08/10] add some tests and fix replacement --- .../__tests__/minify-builtins.js | 10 ++++++++-- packages/babel-plugin-minify-builtins/src/index.js | 5 ++--- packages/babel-preset-babili/src/index.js | 4 ++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js b/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js index 2b1e16883..6aabb079b 100644 --- a/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js +++ b/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js @@ -13,7 +13,12 @@ function transform(code) { describe("minify-builtins", () => { it("should minify standard built in methods", () => { const source = unpad(` - Math.max(a, b) + Math.max(b, a) + Math.max(a, b) + Math.max(b, a); + function c() { + let a = 10; + const d = Number.isNaN(a); + return d && Number.isFinite(a); + } `); // Jest arranges in alphabetical order, So keeping it as _source expect({_source: source, expected: transform(source)}).toMatchSnapshot(); @@ -21,8 +26,9 @@ describe("minify-builtins", () => { it("should minify standard built in properties", () => { const source = unpad(` + Number.NAN + Number.NAN; function a () { - return Math.PI + Math.PI + return Math.PI + Math.PI + Number.EPSILON + Number.NAN; } `); expect({_source: source, expected: transform(source)}).toMatchSnapshot(); diff --git a/packages/babel-plugin-minify-builtins/src/index.js b/packages/babel-plugin-minify-builtins/src/index.js index 981f4a79a..970869d10 100644 --- a/packages/babel-plugin-minify-builtins/src/index.js +++ b/packages/babel-plugin-minify-builtins/src/index.js @@ -52,9 +52,8 @@ module.exports = function({ types: t }) { // deopt when we have side effecty evaluate-able arguments // Math.max(foo(), 1) --> untouched // Math.floor(1) --> 1 - if (result.confident && hasPureArgs(path) - && typeof result.value === "number") { - path.replaceWith(t.numericLiteral(result.value)); + if (result.confident && hasPureArgs(path)) { + path.replaceWith(t.valueToNode(result.value)); } else { if (!context.pathsToUpdate.has(expName)) { context.pathsToUpdate.set(expName, []); diff --git a/packages/babel-preset-babili/src/index.js b/packages/babel-preset-babili/src/index.js index 2c394f767..837585cb6 100644 --- a/packages/babel-preset-babili/src/index.js +++ b/packages/babel-preset-babili/src/index.js @@ -26,7 +26,7 @@ const PLUGINS = [ ["simplifyComparisons", require("babel-plugin-transform-simplify-comparison-operators"), true], ["typeConstructors", require("babel-plugin-minify-type-constructors"), true], ["undefinedToVoid", require("babel-plugin-transform-undefined-to-void"), true], - ["builtIns", require("babel-plugin-minify-builtins"), true], + ["builtIns", require("babel-plugin-minify-builtins"), true], ]; module.exports = preset; @@ -67,6 +67,7 @@ function preset(context, _opts = {}) { optionsMap.numericLiterals, optionsMap.replace, optionsMap.simplify, + optionsMap.builtIns, group("properties", [ optionsMap.consecutiveAdds, @@ -78,7 +79,6 @@ function preset(context, _opts = {}) { optionsMap.booleans, optionsMap.undefinedToVoid, optionsMap.regexpConstructors, - optionsMap.builtIns, optionsMap.removeConsole, optionsMap.removeDebugger, From 3686b0d719e106cd8e70c431bf58ad8b7a76b1a7 Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Thu, 16 Feb 2017 22:19:42 +0100 Subject: [PATCH 09/10] update snapshots --- .../__snapshots__/minify-builtins.js.snap | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap b/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap index d31224a1a..3f2643d0f 100644 --- a/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap +++ b/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap @@ -36,20 +36,33 @@ foo(x);", exports[`minify-builtins should minify standard built in methods 1`] = ` Object { - "_source": "Math.max(a, b) + Math.max(b, a)", + "_source": "Math.max(a, b) + Math.max(b, a); +function c() { + let a = 10; + const d = Number.isNaN(a); + return d && Number.isFinite(a); +}", "expected": "var _Mathmax = Math.max; -_Mathmax(a, b) + _Mathmax(b, a);", +_Mathmax(a, b) + _Mathmax(b, a); +function c() { + let a = 10; + const d = false; + return d && true; +}", } `; exports[`minify-builtins should minify standard built in properties 1`] = ` Object { - "_source": "function a () { - return Math.PI + Math.PI + "_source": "Number.NAN + Number.NAN; +function a () { + return Math.PI + Math.PI + Number.EPSILON + Number.NAN; }", "expected": "var _MathPI = Math.PI; +var _NumberNAN = Number.NAN; +_NumberNAN + _NumberNAN; function a() { - return _MathPI + _MathPI; + return _MathPI + _MathPI + Number.EPSILON + _NumberNAN; }", } `; From 56154cdbdb8c80f970a3ea955a222a1e59968c0f Mon Sep 17 00:00:00 2001 From: Vignesh Shanmugam Date: Thu, 16 Feb 2017 22:27:23 +0100 Subject: [PATCH 10/10] add some tests and use indexOf --- .../__snapshots__/minify-builtins.js.snap | 8 +++++--- .../__tests__/minify-builtins.js | 3 ++- .../babel-plugin-minify-builtins/src/index.js | 4 ++-- .../__snapshots__/options-tests.js.snap | 20 +++++++++---------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap b/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap index 3f2643d0f..8a69fb0ed 100644 --- a/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap +++ b/packages/babel-plugin-minify-builtins/__tests__/__snapshots__/minify-builtins.js.snap @@ -67,10 +67,12 @@ function a() { } `; -exports[`minify-builtins should not evaluate if its has side effecty arguments 1`] = ` +exports[`minify-builtins should not evaluate if its side effecty 1`] = ` Object { - "_source": "Math.max(foo(), 1);", - "expected": "Math.max(foo(), 1);", + "_source": "Math.max(foo(), 1); +Math.random();", + "expected": "Math.max(foo(), 1); +Math.random();", } `; diff --git a/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js b/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js index 6aabb079b..d18fcd4e1 100644 --- a/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js +++ b/packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js @@ -68,9 +68,10 @@ describe("minify-builtins", () => { expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); - it("should not evaluate if its has side effecty arguments", () => { + it("should not evaluate if its side effecty", () => { const source = unpad(` Math.max(foo(), 1); + Math.random(); `); expect({_source: source, expected: transform(source)}).toMatchSnapshot(); }); diff --git a/packages/babel-plugin-minify-builtins/src/index.js b/packages/babel-plugin-minify-builtins/src/index.js index 970869d10..4f0921400 100644 --- a/packages/babel-plugin-minify-builtins/src/index.js +++ b/packages/babel-plugin-minify-builtins/src/index.js @@ -112,8 +112,8 @@ module.exports = function({ types: t }) { const { object, property } = memberExpr.node; if (t.isIdentifier(object) && t.isIdentifier(property) - && VALID_CALLEES.includes(object.name) - && !INVALID_METHODS.includes(property.name)) { + && VALID_CALLEES.indexOf(object.name) >= 0 + && INVALID_METHODS.indexOf(property.name) < 0) { return true; } return false; diff --git a/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap b/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap index 32c04cc7e..7f58a6ae9 100644 --- a/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap +++ b/packages/babel-preset-babili/__tests__/__snapshots__/options-tests.js.snap @@ -11,6 +11,7 @@ Object { "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -18,7 +19,6 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -42,6 +42,7 @@ Object { "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -49,7 +50,6 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -85,6 +85,7 @@ Object { "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -92,7 +93,6 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -138,6 +138,7 @@ Object { "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -145,7 +146,6 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -191,6 +191,7 @@ Object { "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -198,7 +199,6 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -220,6 +220,7 @@ Object { "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -227,7 +228,6 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -263,6 +263,7 @@ Object { "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -270,7 +271,6 @@ Object { "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ], } @@ -289,6 +289,7 @@ Array [ "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -296,7 +297,6 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ] `; @@ -314,6 +314,7 @@ Array [ "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -321,7 +322,6 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ] `; @@ -339,6 +339,7 @@ Array [ "babel-plugin-minify-numeric-literals", "babel-plugin-minify-replace", "babel-plugin-minify-simplify", + "babel-plugin-minify-builtins", "babel-plugin-transform-inline-consecutive-adds", "babel-plugin-transform-member-expression-literals", "babel-plugin-transform-property-literals", @@ -346,7 +347,6 @@ Array [ "babel-plugin-transform-minify-booleans", "babel-plugin-transform-undefined-to-void", "babel-plugin-transform-regexp-constructors", - "babel-plugin-minify-builtins", "babel-plugin-transform-remove-undefined", ] `;