This repository has been archived by the owner on Aug 4, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
index.js
101 lines (79 loc) · 2.49 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { extname } from 'path';
import acorn from 'acorn';
import { walk } from 'estree-walker';
import MagicString from 'magic-string';
import { createFilter } from 'rollup-pluginutils';
const whitespace = /\s/;
function flatten ( node ) {
let name;
let parts = [];
while ( node.type === 'MemberExpression' ) {
if ( node.computed ) return null;
parts.unshift( node.property.name );
node = node.object;
}
if ( node.type !== 'Identifier' ) return null;
name = node.name;
parts.unshift( name );
return { name, keypath: parts.join( '.' ) };
}
export default function strip ( options = {} ) {
const filter = createFilter( options.include, options.exclude );
const sourceMap = options.sourceMap !== false;
const removeDebuggerStatements = options.debugger !== false;
const functions = ( options.functions || [ 'console.*', 'assert.*' ] )
.map( keypath => keypath.replace( /\./g, '\\.' ).replace( /\*/g, '\\w+' ) );
const firstpass = new RegExp( `\\b(?:${functions.join( '|' )}|debugger)\\b` );
const pattern = new RegExp( `^(?:${functions.join( '|' )})$` );
return {
transform ( code, id ) {
if ( !filter( id ) ) return null;
if ( extname( id ) !== '.js' ) return null;
if ( !firstpass.test( code ) ) return null;
let ast;
try {
ast = acorn.parse( code, {
ecmaVersion: 6,
sourceType: 'module'
});
} catch ( err ) {
err.message += ` in ${id}`;
throw err;
}
const magicString = new MagicString( code );
let edited = false;
function remove ( start, end ) {
while ( whitespace.test( code[ start - 1 ] ) ) start -= 1;
magicString.remove( start, end );
}
walk( ast, {
enter ( node, parent ) {
if ( sourceMap ) {
magicString.addSourcemapLocation( node.start );
magicString.addSourcemapLocation( node.end );
}
if ( removeDebuggerStatements && node.type === 'DebuggerStatement' ) {
remove( node.start, node.end );
edited = true;
}
else if ( node.type === 'CallExpression' ) {
const { keypath } = flatten( node.callee );
if ( keypath && pattern.test( keypath ) ) {
if ( parent.type === 'ExpressionStatement' ) {
remove( parent.start, parent.end );
} else {
magicString.overwrite( node.start, node.end, 'void 0' );
}
edited = true;
this.skip();
}
}
}
});
if ( !edited ) return null;
code = magicString.toString();
const map = sourceMap ? magicString.generateMap() : null;
return { code, map };
}
};
}