Skip to content

Commit 59f591d

Browse files
author
substack
committed
Merge branch 'side-effects' of github.com:browserify/common-shakeify into side-effect
2 parents e5b3b9f + 075edb7 commit 59f591d

File tree

9 files changed

+101
-21
lines changed

9 files changed

+101
-21
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
node_modules/
1+
/node_modules
2+
!test/*/node_modules
23
actual.js
34
package-lock.json

index.js

Lines changed: 71 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
2-
const relative = require('path').relative
2+
const path = require('path')
33
const Analyzer = require('@goto-bus-stop/common-shake').Analyzer
4+
const evaluateConst = require('@goto-bus-stop/common-shake').evaluateConst
45
const transformAst = require('transform-ast')
56
const wrapComment = require('wrap-comment')
67
const through = require('through2')
@@ -15,9 +16,9 @@ module.exports = function commonShake (b, opts) {
1516
const seen = {}
1617
opts = Object.assign({
1718
verbose: false,
18-
onExportDelete (path, name) {
19+
onExportDelete (source, name) {
1920
if (opts.verbose || opts.v) {
20-
console.warn('common-shake: removed', `\`${name}\``, 'in', relative(basedir, path))
21+
console.warn('common-shake: removed', `\`${name}\``, 'in', path.relative(basedir, source))
2122
}
2223
},
2324
onModuleBailout (resource, reasons) {
@@ -27,15 +28,15 @@ module.exports = function commonShake (b, opts) {
2728
seen[resource.resource + reason.reason] = true
2829
const loc = reason.loc.start
2930
const source = reason.source || resource.resource
30-
console.warn('common-shake: bailed out: ', reason.reason, 'in', `${relative(basedir, source)}:${loc.line}:${loc.column}`)
31+
console.warn('common-shake: bailed out: ', reason.reason, 'in', `${path.relative(basedir, source)}:${loc.line}:${loc.column}`)
3132
})
3233
}
3334
},
3435
onGlobalBailout (reasons) {
3536
if (opts.verbose || opts.v) {
3637
reasons.forEach((reason) => {
3738
const loc = reason.loc.start
38-
console.warn('common-shake: GLOBAL BAILOUT:', reason.reason, 'in', `${relative(basedir, reason.source)}:${loc.line}:${loc.column}`)
39+
console.warn('common-shake: GLOBAL BAILOUT:', reason.reason, 'in', `${path.relative(basedir, reason.source)}:${loc.line}:${loc.column}`)
3940
})
4041
}
4142
}
@@ -47,11 +48,29 @@ module.exports = function commonShake (b, opts) {
4748
addHooks()
4849
b.on('reset', addHooks)
4950
function addHooks () {
50-
b.pipeline.get('label').unshift(createStream(opts))
51+
const packages = new Map()
52+
const aliases = new Map()
53+
b._mdeps.on('package', (pkg) => {
54+
packages.set(pkg.__dirname, pkg)
55+
})
56+
b._mdeps.on('file', (file, id) => {
57+
aliases.set(id, file)
58+
})
59+
b.pipeline.get('label').unshift(createStream(opts, {
60+
getSideEffects(name) {
61+
const file = aliases.get(name) || name
62+
let pkg
63+
let dir = file
64+
while (!pkg && (dir = path.dirname(dir))) {
65+
pkg = packages.get(dir)
66+
}
67+
return pkg && pkg.sideEffects === false ? false : true
68+
}
69+
}))
5170
}
5271
}
5372

54-
function createStream (opts) {
73+
function createStream (opts, api) {
5574
const analyzer = new Analyzer()
5675

5776
const rows = new Map()
@@ -87,7 +106,9 @@ function createStream (opts) {
87106
}, (node) => {
88107
if (node.type === 'Program') ast = node
89108
})
90-
analyzer.run(ast, index)
109+
analyzer.run(ast, index, {
110+
sideEffects: api.getSideEffects(row.file)
111+
})
91112

92113
const deps = opts.fullPaths ? row.deps : row.indexDeps
93114
Object.keys(deps).forEach((name) => {
@@ -125,13 +146,15 @@ function createStream (opts) {
125146
// If this module was a duplicate of another module,
126147
// the original module will have been rewritten already.
127148
if (row.dedupe) {
128-
this.push(row)
129149
return
130150
}
131151

132152
if (module.bailouts) {
133153
opts.onModuleBailout(module, module.bailouts)
134-
this.push(row)
154+
return
155+
}
156+
157+
if (module.getInfo().removeImport) {
135158
return
136159
}
137160

@@ -143,15 +166,6 @@ function createStream (opts) {
143166
}
144167
})
145168

146-
const transformed = string.toString()
147-
if (opts.sourceMap) {
148-
row.source = transformed + '\n' + convertSourceMap.fromObject(string.map).toComment()
149-
} else {
150-
row.source = transformed
151-
}
152-
153-
this.push(row)
154-
155169
// Check if a name was used in this module, or
156170
// in any of this module's deduped versions.
157171
function isUsed (name) {
@@ -168,6 +182,44 @@ function createStream (opts) {
168182
}
169183
})
170184

185+
rows.forEach((row, index) => {
186+
const module = analyzer.getModule(index)
187+
if (module && module.getInfo().removeImport) {
188+
return
189+
}
190+
191+
if (row.dedupe || module.bailouts) {
192+
this.push(row)
193+
return
194+
}
195+
196+
const string = strings.get(index)
197+
198+
Object.keys(row.indexDeps).forEach((depName) => {
199+
const depModule = analyzer.getModule(row.indexDeps[depName])
200+
if (depModule && depModule.getInfo().removeImport) {
201+
delete row.indexDeps[depName]
202+
delete row.deps[depName]
203+
const imports = module.requireNodes.get(depName) || []
204+
imports.forEach((node) => {
205+
// We can replace this with `undefined` because this will not be a .property.
206+
// If it was a require('mod').property, the .property would be marked as used,
207+
// and the module's import would not be removable
208+
node.edit.update(`void 0 ${wrapComment(node.getSource())}`)
209+
})
210+
}
211+
})
212+
213+
const transformed = string.toString()
214+
if (opts.sourceMap) {
215+
row.source = transformed + '\n' + convertSourceMap.fromObject(string.map).toComment()
216+
} else {
217+
row.source = transformed
218+
}
219+
220+
this.push(row)
221+
})
222+
171223
next()
172224
}
173225

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"homepage": "https://github.com/browserify/common-shakeify#readme",
2929
"dependencies": {
30-
"@goto-bus-stop/common-shake": "^2.2.0",
30+
"@goto-bus-stop/common-shake": "^2.3.0",
3131
"convert-source-map": "^1.5.1",
3232
"through2": "^2.0.3",
3333
"transform-ast": "^2.4.3",

test/side-effects/app.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
var dep = require('./dep')
2+
3+
console.log(dep.three())

test/side-effects/dep.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
var _ = require('functional')
2+
3+
exports.two = function () { return _.addOne(1) }
4+
exports.three = function () { return 3 }

test/side-effects/expected.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2+
var dep = require('./dep')
3+
4+
console.log(dep.three())
5+
6+
},{"./dep":2}],2:[function(require,module,exports){
7+
var _ = void 0 /* require('functional') */
8+
9+
/* common-shake removed: exports.two = */ void function () { return _.addOne(1) }
10+
exports.three = function () { return 3 }
11+
12+
},{}]},{},[1]);

test/side-effects/node_modules/functional/index.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/side-effects/node_modules/functional/package.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ test('exclude', function (t) {
6969
test('paren-exports', function (t) {
7070
runTest(t, 'paren-exports')
7171
})
72+
test('side-effects', function (t) {
73+
runTest(t, 'side-effects')
74+
})
7275

7376
test('external', function (t) {
7477
var b = browserify({

0 commit comments

Comments
 (0)