Skip to content

Commit

Permalink
Implement minify-builtins plugin (#410)
Browse files Browse the repository at this point in the history
* Implement transform-built-ins plugin

* fix tests and add to preset

* optimize away expressions when necessary

* single pass visitor and update snapshots

* Update readme

* fix computed properties and depot if impure

* rename plugin and use builts from babel

* add some tests and fix replacement

* update snapshots

* add some tests and use indexOf
  • Loading branch information
vigneshshanmugam authored and boopathi committed Feb 16, 2017
1 parent e836e60 commit 7f66b97
Show file tree
Hide file tree
Showing 10 changed files with 413 additions and 1 deletion.
4 changes: 4 additions & 0 deletions packages/babel-plugin-minify-builtins/.npmignore
@@ -0,0 +1,4 @@
src
__tests__
node_modules
*.log
51 changes: 51 additions & 0 deletions packages/babel-plugin-minify-builtins/README.md
@@ -0,0 +1,51 @@
# babel-plugin-minify-builtins

Minify Standard built-in Objects

## Example

**In**

```javascript
Math.floor(a) + Math.floor(b)
```

**Out**

```javascript
var _Mathfloor = Math.floor;

_Mathfloor(a) + _Mathfloor(b);
```

## Installation

```sh
npm install babel-plugin-minify-builtins
```

## Usage

### Via `.babelrc` (Recommended)

**.babelrc**

```json
{
"plugins": ["minify-builtins"]
}
```

### Via CLI

```sh
babel --plugins minify-builtins script.js
```

### Via Node API

```javascript
require("babel-core").transform("code", {
plugins: ["minify-builtins"]
});
```
@@ -0,0 +1,100 @@
exports[`minify-builtins should collect and minify 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[`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;
let x = Math.floor(Math.max(a, b));
foo(x);",
"expected": "const a = 5;
let b = 1.8;
let x = 5;
foo(x);",
}
`;

exports[`minify-builtins should minify standard built in methods 1`] = `
Object {
"_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);
function c() {
let a = 10;
const d = false;
return d && true;
}",
}
`;

exports[`minify-builtins should minify standard built in properties 1`] = `
Object {
"_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 + Number.EPSILON + _NumberNAN;
}",
}
`;

exports[`minify-builtins should not evaluate if its side effecty 1`] = `
Object {
"_source": "Math.max(foo(), 1);
Math.random();",
"expected": "Math.max(foo(), 1);
Math.random();",
}
`;

exports[`minify-builtins should not minify for computed properties 1`] = `
Object {
"_source": "let max = \"floor\";
Math[max](1.5);",
"expected": "let max = \"floor\";
Math[max](1.5);",
}
`;

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);
}
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);",
}
`;
87 changes: 87 additions & 0 deletions packages/babel-plugin-minify-builtins/__tests__/minify-builtins.js
@@ -0,0 +1,87 @@
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("minify-builtins", () => {
it("should minify standard built in methods", () => {
const source = unpad(`
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();
});

it("should minify standard built in properties", () => {
const source = unpad(`
Number.NAN + Number.NAN;
function a () {
return Math.PI + Math.PI + Number.EPSILON + Number.NAN;
}
`);
expect({_source: source, expected: transform(source)}).toMatchSnapshot();
});

it("should take no of occurences in to account", () => {
const source = unpad(`
function a() {
return Math.floor(a) + Math.floor(b) + Math.min(a, b);
}
Math.floor(a) + Math.max(a, b);
`);
expect({_source: source, expected: transform(source)}).toMatchSnapshot();
});

it("should collect and minify no matter any depth", () => {
const source = unpad(`
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);
}
}
`);
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);
let b = 1.8;
let x = Math.floor(Math.max(a, b));
foo(x);
`);
expect({_source: source, expected: transform(source)}).toMatchSnapshot();
});

it("should not evaluate if its side effecty", () => {
const source = unpad(`
Math.max(foo(), 1);
Math.random();
`);
expect({_source: source, expected: transform(source)}).toMatchSnapshot();
});

it("should not minify for computed properties", () => {
const source = unpad(`
let max = "floor";
Math[max](1.5);
`);
expect({_source: source, expected: transform(source)}).toMatchSnapshot();
});

});
19 changes: 19 additions & 0 deletions packages/babel-plugin-minify-builtins/package.json
@@ -0,0 +1,19 @@
{
"name": "babel-plugin-minify-builtins",
"version": "0.0.1",
"description": "Minify Standard built-in Objects",
"homepage": "https://github.com/babel/babili#readme",
"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": [
"babel-plugin",
"transform-built-ins"
],
"author": "Vignesh Shanmugam <vignesh.shanmugam22@gmail.com> (https://vigneshh.in)",
"license": "MIT",
"dependencies": {
"babel-helper-evaluate-path": "^0.0.3"
},
"devDependencies": {}
}

0 comments on commit 7f66b97

Please sign in to comment.