Skip to content

Commit 1c07112

Browse files
committed
Merge remote-tracking branch 'upstream'
2 parents 5638335 + ca9eb34 commit 1c07112

File tree

16 files changed

+215
-14
lines changed

16 files changed

+215
-14
lines changed

lib/index.js

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ function optimizeJs (jsString, opts) {
4141
return false
4242
}
4343

44+
function isNumeric (str) {
45+
return /^[0-9]+$/.test(str)
46+
}
47+
4448
function isCallExpression (node) {
4549
return node && node.type === 'CallExpression'
4650
}
@@ -49,37 +53,62 @@ function optimizeJs (jsString, opts) {
4953
return node && node.type === 'ArrayExpression'
5054
}
5155

56+
function isElementOfArray (node) {
57+
return isArrayExpression(node.parent()) &&
58+
node.parent().elements.indexOf(node) !== -1
59+
}
60+
5261
// returns true iff node is an argument to a function call expression.
5362
function isArgumentToFunctionCall (node) {
5463
return isCallExpression(node.parent()) &&
5564
node.parent().arguments.length &&
5665
node.parent().arguments.indexOf(node) !== -1
5766
}
5867

59-
// returns true iff node is an element of an array literal which is in turn
60-
// an argument to a function call expression.
61-
function isElementOfArrayArgumentToFunctionCall (node) {
62-
return isArrayExpression(node.parent()) &&
63-
node.parent().elements.indexOf(node) !== -1 &&
64-
isArgumentToFunctionCall(node.parent())
68+
function isValueOfObjectLiteralWithNumericName (node) {
69+
return node &&
70+
node.parent() &&
71+
node.parent().type === 'Property' &&
72+
node.parent().key &&
73+
node.parent().key.type === 'Literal' &&
74+
node.parent().key.raw &&
75+
isNumeric(node.parent().key.raw) &&
76+
node.parent().value === node &&
77+
node.parent().parent() &&
78+
node.parent().parent().type === 'ObjectExpression'
6579
}
6680

6781
// returns true iff node is an IIFE.
6882
function isIIFE (node) {
69-
return isCallExpression(node.parent()) &&
83+
return node &&
84+
node.type === 'FunctionExpression' &&
85+
isCallExpression(node.parent()) &&
7086
node.parent().callee === node
7187
}
7288

89+
// returns true iff this is an IIFE call expression
90+
function isIIFECall (node) {
91+
return node &&
92+
isCallExpression(node) &&
93+
node.callee &&
94+
node.callee.type === 'FunctionExpression'
95+
}
96+
7397
// tries to divine if this function is a webpack module wrapper.
7498
// returns true iff node is an element of an array literal which is in turn
7599
// an argument to a function call expression, and that function call
76100
// expression is an IIFE.
77101
function isProbablyWebpackModule (node) {
78-
return isElementOfArrayArgumentToFunctionCall(node) &&
79-
node.parent() && // array literal
80-
node.parent().parent() && // CallExpression
81-
node.parent().parent().callee && // function that is being called
82-
node.parent().parent().callee.type === 'FunctionExpression'
102+
return isElementOfArray(node) &&
103+
isArgumentToFunctionCall(node.parent()) &&
104+
isIIFECall(node.parent().parent())
105+
}
106+
107+
function isProbablyBrowserifyModule (node) {
108+
return isElementOfArray(node) &&
109+
isValueOfObjectLiteralWithNumericName(node.parent()) &&
110+
isArgumentToFunctionCall(node.parent().parent().parent()) &&
111+
isIIFECall(node.parent().parent().parent().parent())
83112
}
84113

85114
if (node.type === 'FunctionExpression') {
@@ -88,7 +117,9 @@ function optimizeJs (jsString, opts) {
88117
var postChar = jsString.charAt(node.end)
89118
var postPostChar = jsString.charAt(node.end + 1)
90119

91-
if (isArgumentToFunctionCall(node) || isProbablyWebpackModule(node)) {
120+
if (isArgumentToFunctionCall(node) ||
121+
isProbablyWebpackModule(node) ||
122+
isProbablyBrowserifyModule(node)) {
92123
// function passed in to another function, either as an argument, or as an element
93124
// of an array argument. these are almost _always_ executed, e.g. webpack bundles,
94125
// UMD bundles, Browserify bundles, Node-style errbacks, Promise then()s and catch()s, etc.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Optimize initial JavaScript execution/parsing by wrapping eager functions",
55
"main": "lib/index.js",
66
"scripts": {
7-
"test": "standard && mocha test/test.js",
7+
"test": "standard && mocha --timeout 60000 test/test.js",
88
"benchmark": "npm run build-benchmark && hs -p 9090 benchmarks",
99
"build-benchmark": "sh bin/build-benchmark.sh",
1010
"publish-benchmark": "sh bin/publish-benchmark.sh",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2+
var mod = require(2)
3+
console.log('hello browserify')
4+
5+
},{"2":2}],2:[function(require,module,exports){
6+
console.log('hello browserify module')
7+
8+
},{}]},{},[1]);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,(function(e){var n=t[o][1][e];return s(n?n:e)}),l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[(function(require,module,exports){
2+
var mod = require(2)
3+
console.log('hello browserify')
4+
5+
}),{"2":2}],2:[(function(require,module,exports){
6+
console.log('hello browserify module')
7+
8+
}),{}]},{},[1]);

test/cases/browserify-basic/input.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2+
var mod = require('./module')
3+
console.log('hello browserify')
4+
5+
},{"./module":2}],2:[function(require,module,exports){
6+
console.log('hello browserify module')
7+
8+
},{}]},{},[1]);

test/cases/browserify-basic/output.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,(function(e){var n=t[o][1][e];return s(n?n:e)}),l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[(function(require,module,exports){
2+
var mod = require('./module')
3+
console.log('hello browserify')
4+
5+
}),{"./module":2}],2:[(function(require,module,exports){
6+
console.log('hello browserify module')
7+
8+
}),{}]},{},[1]);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// a browserify-style object literal that isn't a parameter shouldn't be optimized.
2+
var a = {
3+
1:[
4+
function(o,r,t){
5+
console.log("browserify style!");
6+
},
7+
{}
8+
]
9+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// a browserify-style object literal that isn't a parameter shouldn't be optimized.
2+
var a = {
3+
1:[
4+
function(o,r,t){
5+
console.log("browserify style!");
6+
},
7+
{}
8+
]
9+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
!function(o){
2+
return o[0]();
3+
}(
4+
{
5+
1:[
6+
function(o,r,t){
7+
console.log("browserify style!");
8+
},
9+
{}
10+
],
11+
2:[
12+
function(o,r,t){
13+
console.log("browserify style!");
14+
},
15+
{}
16+
],
17+
3:[
18+
function(o,r,t){
19+
console.log("browserify style!");
20+
},
21+
{}
22+
]
23+
}
24+
);
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
!(function(o){
2+
return o[0]();
3+
})(
4+
{
5+
1:[
6+
(function(o,r,t){
7+
console.log("browserify style!");
8+
}),
9+
{}
10+
],
11+
2:[
12+
(function(o,r,t){
13+
console.log("browserify style!");
14+
}),
15+
{}
16+
],
17+
3:[
18+
(function(o,r,t){
19+
console.log("browserify style!");
20+
}),
21+
{}
22+
]
23+
}
24+
);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
foo(
2+
{
3+
1:[
4+
function(o,r,t){
5+
console.log("browserify style!");
6+
},
7+
{}
8+
]
9+
}
10+
);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
foo(
2+
{
3+
1:[
4+
function(o,r,t){
5+
console.log("browserify style!");
6+
},
7+
{}
8+
]
9+
}
10+
);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
!function(o){
2+
return o[0]();
3+
}(
4+
{
5+
1:[
6+
function(o,r,t){
7+
console.log("browserify style!");
8+
},
9+
{}
10+
]
11+
}
12+
);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
!(function(o){
2+
return o[0]();
3+
})(
4+
{
5+
1:[
6+
(function(o,r,t){
7+
console.log("browserify style!");
8+
}),
9+
{}
10+
]
11+
}
12+
);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// a browserify-style function call that has non-numeric object indices shouldn't
2+
// be optimized.
3+
!function(o){
4+
return o[0]();
5+
}(
6+
{
7+
a:[
8+
function(o,r,t){
9+
console.log("browserify style!");
10+
},
11+
{}
12+
]
13+
}
14+
);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// a browserify-style function call that has non-numeric object indices shouldn't
2+
// be optimized.
3+
!(function(o){
4+
return o[0]();
5+
})(
6+
{
7+
a:[
8+
function(o,r,t){
9+
console.log("browserify style!");
10+
},
11+
{}
12+
]
13+
}
14+
);

0 commit comments

Comments
 (0)