-
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Convert to Babel plugin and add TypeScript types (#24)
- Loading branch information
Showing
6 changed files
with
104 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import {PluginObj, types} from '@babel/core'; | ||
|
||
/** | ||
Strip `console`, `alert`, and `debugger` statements from JavaScript code. | ||
@param babel - Babel instance. Passed automatically when using Babel. | ||
@example | ||
``` | ||
import {transformSync} from '@babel/core'; | ||
import stripDebug from 'strip-debug'; | ||
transformSync('function foo(){console.log("foo");alert("foo");debugger;}', { | ||
plugins: [stripDebug] | ||
}).code; | ||
//=> 'function foo() { void 0;void 0; }' | ||
``` | ||
*/ | ||
export default function stripDebugPlugin(babel: {readonly types: typeof types}): PluginObj; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,29 @@ | ||
'use strict'; | ||
const rocambole = require('rocambole'); | ||
const stripDebugger = require('rocambole-strip-debugger'); | ||
const stripConsole = require('rocambole-strip-console'); | ||
const stripAlert = require('rocambole-strip-alert'); | ||
const espree = require('espree'); | ||
const stripFunctionNameList = [ | ||
'alert', | ||
'window.alert', | ||
'console.log', | ||
'window.console.log' | ||
]; | ||
|
||
rocambole.parseFn = espree.parse; | ||
rocambole.parseContext = espree; | ||
rocambole.parseOptions = { | ||
range: true, | ||
tokens: true, | ||
comment: true, | ||
ecmaVersion: 2019, | ||
ecmaFeatures: { | ||
jsx: true, | ||
globalReturn: false, | ||
impliedStrict: false | ||
} | ||
}; | ||
export default function stripDebugPlugin({types}) { | ||
return { | ||
visitor: { | ||
DebuggerStatement(path) { | ||
path.remove(); | ||
}, | ||
CallExpression(path) { | ||
const isMatched = stripFunctionNameList.some(functionName => { | ||
const calleePath = path.get('callee'); | ||
if (calleePath.matchesPattern(functionName)) { | ||
return !calleePath.node.computed; | ||
} | ||
|
||
module.exports = source => rocambole.moonwalk(source, node => { | ||
stripDebugger(node); | ||
stripConsole(node); | ||
stripAlert(node); | ||
}); | ||
return calleePath.node.name === functionName; | ||
}); | ||
if (isMatched) { | ||
path.replaceWith(types.unaryExpression('void', types.numericLiteral(0))); | ||
} | ||
} | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,8 @@ | |
"email": "[email protected]", | ||
"url": "https://sindresorhus.com" | ||
}, | ||
"type": "module", | ||
"exports": "./index.js", | ||
"engines": { | ||
"node": ">=12" | ||
}, | ||
|
@@ -32,17 +34,14 @@ | |
"js", | ||
"javascript", | ||
"ast", | ||
"esprima" | ||
"babel-plugin" | ||
], | ||
"dependencies": { | ||
"espree": "^7.3.1", | ||
"rocambole": "^0.7.0", | ||
"rocambole-strip-alert": "^1.0.0", | ||
"rocambole-strip-console": "^2.0.0", | ||
"rocambole-strip-debugger": "^1.0.1" | ||
"@types/babel__core": "^7.1.14" | ||
}, | ||
"devDependencies": { | ||
"ava": "^2.4.0", | ||
"@babel/core": "^7.14.3", | ||
"ava": "^3.15.0", | ||
"xo": "^0.38.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,56 @@ | ||
import {transformAsync} from '@babel/core'; | ||
import test from 'ava'; | ||
import stripDebug from './index.js'; | ||
import stripDebugPlugin from './index.js'; | ||
|
||
test('strip debugger statement', t => { | ||
t.is(stripDebug('function test(){debugger;}').toString(), 'function test(){}'); | ||
t.is(stripDebug('"use strict";debugger;foo()').toString(), '"use strict";foo()'); | ||
async function stripDebug(source) { | ||
const {code} = await transformAsync(source, { | ||
plugins: [stripDebugPlugin] | ||
}); | ||
return code; | ||
} | ||
|
||
test('strip debugger statement', async t => { | ||
t.is(await stripDebug('function test(){debugger;}'), 'function test() {}'); | ||
t.is(await stripDebug('"use strict";debugger;foo()'), '"use strict";\n\nfoo();'); | ||
}); | ||
|
||
test('strip console statement', t => { | ||
t.is(stripDebug('function test(){console.log("foo");}').toString(), 'function test(){void 0;}'); | ||
t.is(stripDebug('function test(){window.console.log("foo");}').toString(), 'function test(){void 0;}'); | ||
t.is(stripDebug('var test = () => console.log("foo");').toString(), 'var test = () => void 0;'); | ||
t.is(stripDebug('"use strict";console.log("foo");foo()').toString(), '"use strict";void 0;foo()'); | ||
t.is(stripDebug('if(console){console.log("foo", "bar");}').toString(), 'if(console){void 0;}'); | ||
t.is(stripDebug('foo && console.log("foo");').toString(), 'foo && void 0;'); | ||
t.is(stripDebug('if (foo) console.log("foo")\nnextLine();').toString(), 'if (foo) void 0\nnextLine();'); | ||
t.is(stripDebug('function test(){console.log(...colors);}').toString(), 'function test(){void 0;}'); | ||
test('strip console statement', async t => { | ||
t.is(await stripDebug('function test(){console.log("foo");}'), 'function test() {\n void 0;\n}'); | ||
t.is(await stripDebug('function test(){window.console.log("foo");}'), 'function test() {\n void 0;\n}'); | ||
t.is(await stripDebug('var test = () => console.log("foo");'), 'var test = () => void 0;'); | ||
t.is(await stripDebug('"use strict";console.log("foo");foo()'), '"use strict";\n\nvoid 0;\nfoo();'); | ||
t.is(await stripDebug('if(console){console.log("foo", "bar");}'), 'if (console) {\n void 0;\n}'); | ||
t.is(await stripDebug('foo && console.log("foo");'), 'foo && void 0;'); | ||
t.is(await stripDebug('if (foo) console.log("foo")\nnextLine();'), 'if (foo) void 0;\nnextLine();'); | ||
t.is(await stripDebug('function test(){console.log(...colors);}'), 'function test() {\n void 0;\n}'); | ||
}); | ||
|
||
test('strip alert statement', t => { | ||
t.is(stripDebug('function test(){alert("foo");}').toString(), 'function test(){void 0;}'); | ||
t.is(stripDebug('function test(){window.alert("foo");}').toString(), 'function test(){void 0;}'); | ||
t.is(stripDebug('var test = () => alert("foo");').toString(), 'var test = () => void 0;'); | ||
t.is(stripDebug('"use strict";alert("foo");foo()').toString(), '"use strict";void 0;foo()'); | ||
t.is(stripDebug('if(alert){alert("foo", "bar");}').toString(), 'if(alert){void 0;}'); | ||
t.is(stripDebug('foo && alert("foo");').toString(), 'foo && void 0;'); | ||
t.is(stripDebug('if (foo) alert("foo")\nnextLine();').toString(), 'if (foo) void 0\nnextLine();'); | ||
test('strip alert statement', async t => { | ||
t.is(await stripDebug('function test(){alert("foo");}'), 'function test() {\n void 0;\n}'); | ||
t.is(await stripDebug('function test(){window.alert("foo");}'), 'function test() {\n void 0;\n}'); | ||
t.is(await stripDebug('var test = () => alert("foo");'), 'var test = () => void 0;'); | ||
t.is(await stripDebug('"use strict";alert("foo");foo()'), '"use strict";\n\nvoid 0;\nfoo();'); | ||
t.is(await stripDebug('if(alert){alert("foo", "bar");}'), 'if (alert) {\n void 0;\n}'); | ||
t.is(await stripDebug('foo && alert("foo");'), 'foo && void 0;'); | ||
t.is(await stripDebug('if (foo) alert("foo")\nnextLine();'), 'if (foo) void 0;\nnextLine();'); | ||
}); | ||
|
||
test('never strip away non-debugging code', t => { | ||
const fixture = 'var test = {\n getReadSections: function(){\n var readSections = window.localStorage.getItestripDebug(\'storyReadSections\') || \'[]\';\n return JSON.parse(readSections);\n }\n};'; | ||
t.is(stripDebug(fixture).toString(), fixture); | ||
test('never strip away non-debugging code', async t => { | ||
const fixture = `var test = { | ||
getReadSections: function () { | ||
var readSections = window.localStorage.getItestripDebug('storyReadSections') || '[]'; | ||
return JSON.parse(readSections); | ||
} | ||
};`; | ||
t.is(await stripDebug(fixture), fixture); | ||
}); | ||
|
||
test('shouldn\'t leak memory', t => { | ||
t.notThrows(() => { | ||
stripDebug('var obj = null; try { obj = \'something\'; } catch (e) { console.warn(\'NOPE!\'); }').toString(); | ||
}); | ||
test('shouldn\'t leak memory', async t => { | ||
await t.notThrowsAsync(() => | ||
stripDebug('var obj = null; try { obj = \'something\'; } catch (e) { console.warn(\'NOPE!\'); }') | ||
); | ||
}); | ||
|
||
test('supports async functions', t => { | ||
t.is(stripDebug('async function test(){debugger; await foo();}').toString(), 'async function test(){ await foo();}'); | ||
test('supports async functions', async t => { | ||
t.is(await stripDebug('async function test(){debugger; await foo();}'), 'async function test() {\n await foo();\n}'); | ||
}); |