1 | 'use strict';
|
2 |
|
3 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
4 |
|
5 | var estreeWalker = require('estree-walker');
|
6 | var MagicString = _interopDefault(require('magic-string'));
|
7 | var rollupPluginutils = require('rollup-pluginutils');
|
8 |
|
9 |
|
10 |
|
11 | const whitespace = /\s/;
|
12 |
|
13 | function getName(node) {
|
14 | if (node.type === 'Identifier') return node.name;
|
15 | if (node.type === 'ThisExpression') return 'this';
|
16 | if (node.type === 'Super') return 'super';
|
17 |
|
18 | return null;
|
19 | }
|
20 |
|
21 | function flatten(node) {
|
22 | const parts = [];
|
23 |
|
24 | while (node.type === 'MemberExpression') {
|
25 | if (node.computed) return null;
|
26 |
|
27 | parts.unshift(node.property.name);
|
28 | node = node.object;
|
29 | }
|
30 |
|
31 | const name = getName(node);
|
32 |
|
33 | if (!name) return null;
|
34 |
|
35 | parts.unshift(name);
|
36 | return parts.join('.');
|
37 | }
|
38 |
|
39 | function strip(options = {}) {
|
40 | const include = options.include || '**/*.js';
|
41 | const { exclude } = options;
|
42 | const filter = rollupPluginutils.createFilter(include, exclude);
|
43 | const sourceMap = options.sourceMap !== false;
|
44 |
|
45 | const removeDebuggerStatements = options.debugger !== false;
|
46 | const functions = (options.functions || ['console.*', 'assert.*']).map((keypath) =>
|
47 | keypath.replace(/\./g, '\\.').replace(/\*/g, '\\w+')
|
48 | );
|
49 |
|
50 | const labels = options.labels || [];
|
51 |
|
52 | const firstpass = new RegExp(`\\b(?:${functions.join('|')}|debugger)\\b`);
|
53 | const pattern = new RegExp(`^(?:${functions.join('|')})$`);
|
54 |
|
55 | return {
|
56 | name: 'strip',
|
57 |
|
58 | transform(code, id) {
|
59 | if (!filter(id)) return null;
|
60 | if (functions.length > 0 && !firstpass.test(code)) return null;
|
61 |
|
62 | let ast;
|
63 |
|
64 | try {
|
65 | ast = this.parse(code);
|
66 | } catch (err) {
|
67 | err.message += ` in ${id}`;
|
68 | throw err;
|
69 | }
|
70 |
|
71 | const magicString = new MagicString(code);
|
72 | let edited = false;
|
73 |
|
74 | function remove(start, end) {
|
75 | while (whitespace.test(code[start - 1])) start -= 1;
|
76 | magicString.remove(start, end);
|
77 | }
|
78 |
|
79 | function isBlock(node) {
|
80 | return node && (node.type === 'BlockStatement' || node.type === 'Program');
|
81 | }
|
82 |
|
83 | function removeExpression(node) {
|
84 | const { parent } = node;
|
85 |
|
86 | if (parent.type === 'ExpressionStatement') {
|
87 | removeStatement(parent);
|
88 | } else {
|
89 | magicString.overwrite(node.start, node.end, 'void 0');
|
90 | }
|
91 |
|
92 | edited = true;
|
93 | }
|
94 |
|
95 | function removeStatement(node) {
|
96 | const { parent } = node;
|
97 |
|
98 | if (isBlock(parent)) {
|
99 | remove(node.start, node.end);
|
100 | } else {
|
101 | magicString.overwrite(node.start, node.end, 'void 0;');
|
102 | }
|
103 |
|
104 | edited = true;
|
105 | }
|
106 |
|
107 | estreeWalker.walk(ast, {
|
108 | enter(node, parent) {
|
109 | Object.defineProperty(node, 'parent', {
|
110 | value: parent,
|
111 | enumerable: false,
|
112 | configurable: true
|
113 | });
|
114 |
|
115 | if (sourceMap) {
|
116 | magicString.addSourcemapLocation(node.start);
|
117 | magicString.addSourcemapLocation(node.end);
|
118 | }
|
119 |
|
120 | if (removeDebuggerStatements && node.type === 'DebuggerStatement') {
|
121 | removeStatement(node);
|
122 | } else if (node.type === 'LabeledStatement') {
|
123 | if (node.label && labels.includes(node.label.name)) {
|
124 | removeStatement(node);
|
125 | }
|
126 | } else if (node.type === 'CallExpression') {
|
127 | const keypath = flatten(node.callee);
|
128 | if (keypath && pattern.test(keypath)) {
|
129 | removeExpression(node);
|
130 | this.skip();
|
131 | }
|
132 | }
|
133 | }
|
134 | });
|
135 |
|
136 | if (!edited) return null;
|
137 |
|
138 | code = magicString.toString();
|
139 | const map = sourceMap ? magicString.generateMap() : null;
|
140 |
|
141 | return { code, map };
|
142 | }
|
143 | };
|
144 | }
|
145 |
|
146 | module.exports = strip;
|