common-shakeify
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -7,2 +7,5 @@ # common-shakeify change log | ||
## 1.1.0 | ||
* Entirely remove side-effect-free unused modules when they declare `sideEffects: false` in `package.json`. ([#31](https://github.com/browserify/common-shakeify/pull/31)) | ||
## 1.0.0 | ||
@@ -9,0 +12,0 @@ * Expose `opts.ecmaVersion` with a default value of 10. Previously the internal value was 9. ([#39](https://github.com/browserify/common-shakeify/pull/39)) |
90
index.js
'use strict' | ||
const relative = require('path').relative | ||
const path = require('path') | ||
const Analyzer = require('@goto-bus-stop/common-shake').Analyzer | ||
const evaluateConst = require('@goto-bus-stop/common-shake').evaluateConst | ||
const transformAst = require('transform-ast') | ||
@@ -18,5 +19,5 @@ const wrapComment = require('wrap-comment') | ||
verbose: false, | ||
onExportDelete (path, name) { | ||
onExportDelete (source, name) { | ||
if (opts.verbose || opts.v) { | ||
console.warn('common-shake: removed', `\`${name}\``, 'in', relative(basedir, path)) | ||
console.warn('common-shake: removed', `\`${name}\``, 'in', path.relative(basedir, source)) | ||
} | ||
@@ -31,3 +32,3 @@ }, | ||
const source = reason.source || resource.resource | ||
console.warn('common-shake: bailed out: ', reason.reason, 'in', `${relative(basedir, source)}:${loc.line}:${loc.column}`) | ||
console.warn('common-shake: bailed out: ', reason.reason, 'in', `${path.relative(basedir, source)}:${loc.line}:${loc.column}`) | ||
}) | ||
@@ -40,3 +41,3 @@ } | ||
const loc = reason.loc.start | ||
console.warn('common-shake: GLOBAL BAILOUT:', reason.reason, 'in', `${relative(basedir, reason.source)}:${loc.line}:${loc.column}`) | ||
console.warn('common-shake: GLOBAL BAILOUT:', reason.reason, 'in', `${path.relative(basedir, reason.source)}:${loc.line}:${loc.column}`) | ||
}) | ||
@@ -53,7 +54,25 @@ } | ||
function addHooks () { | ||
b.pipeline.get('label').unshift(createStream(opts)) | ||
const packages = new Map() | ||
const aliases = new Map() | ||
b._mdeps.on('package', (pkg) => { | ||
packages.set(pkg.__dirname, pkg) | ||
}) | ||
b._mdeps.on('file', (file, id) => { | ||
aliases.set(id, file) | ||
}) | ||
b.pipeline.get('label').unshift(createStream(opts, { | ||
getSideEffects(name) { | ||
const file = aliases.get(name) || name | ||
let pkg | ||
let dir = file | ||
while (!pkg && (dir = path.dirname(dir))) { | ||
pkg = packages.get(dir) | ||
} | ||
return pkg && pkg.sideEffects === false ? false : true | ||
} | ||
})) | ||
} | ||
} | ||
function createStream (opts) { | ||
function createStream (opts, api) { | ||
const analyzer = new Analyzer() | ||
@@ -94,3 +113,5 @@ | ||
}) | ||
analyzer.run(ast, index) | ||
analyzer.run(ast, index, { | ||
sideEffects: api.getSideEffects(row.file) | ||
}) | ||
@@ -133,3 +154,2 @@ const deps = opts.fullPaths ? row.deps : row.indexDeps | ||
if (row.dedupe) { | ||
this.push(row) | ||
return | ||
@@ -140,6 +160,9 @@ } | ||
opts.onModuleBailout(module, module.bailouts) | ||
this.push(row) | ||
return | ||
} | ||
if (module.getInfo().removeImport) { | ||
return | ||
} | ||
module.getDeclarations().forEach((decl) => { | ||
@@ -153,11 +176,2 @@ if (!isUsed(decl.name)) { | ||
const transformed = string.toString() | ||
if (opts.sourceMap) { | ||
row.source = transformed + '\n' + convertSourceMap.fromObject(string.map).toComment() | ||
} else { | ||
row.source = transformed | ||
} | ||
this.push(row) | ||
// Check if a name was used in this module, or | ||
@@ -179,2 +193,40 @@ // in any of this module's deduped versions. | ||
rows.forEach((row, index) => { | ||
const module = analyzer.getModule(index) | ||
if (module && module.getInfo().removeImport) { | ||
return | ||
} | ||
if (row.dedupe || module.bailouts) { | ||
this.push(row) | ||
return | ||
} | ||
const string = strings.get(index) | ||
Object.keys(row.indexDeps).forEach((depName) => { | ||
const depModule = analyzer.getModule(row.indexDeps[depName]) | ||
if (depModule && depModule.getInfo().removeImport) { | ||
delete row.indexDeps[depName] | ||
delete row.deps[depName] | ||
const imports = module.requireNodes.get(depName) || [] | ||
imports.forEach((node) => { | ||
// We can replace this with `undefined` because this will not be a .property. | ||
// If it was a require('mod').property, the .property would be marked as used, | ||
// and the module's import would not be removable | ||
node.edit.update(`void 0 ${wrapComment(node.getSource())}`) | ||
}) | ||
} | ||
}) | ||
const transformed = string.toString() | ||
if (opts.sourceMap) { | ||
row.source = transformed + '\n' + convertSourceMap.fromObject(string.map).toComment() | ||
} else { | ||
row.source = transformed | ||
} | ||
this.push(row) | ||
}) | ||
next() | ||
@@ -181,0 +233,0 @@ } |
{ | ||
"name": "common-shakeify", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "browserify tree shaking plugin using @indutny common-shake", | ||
@@ -30,3 +30,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"@goto-bus-stop/common-shake": "^2.2.0", | ||
"@goto-bus-stop/common-shake": "^2.3.0", | ||
"convert-source-map": "^1.5.1", | ||
@@ -33,0 +33,0 @@ "through2": "^2.0.3", |
@@ -72,2 +72,5 @@ var test = require('tape') | ||
}) | ||
test('side-effects', function (t) { | ||
runTest(t, 'side-effects') | ||
}) | ||
@@ -74,0 +77,0 @@ test('external', function (t) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
46346
71
883
2
41