Skip to content

Commit a014c66

Browse files
feat(strip)!: support specifying both functions and labels (#471)
* FIX: Now supports specifying both functions and labels in the same config. FIX: Supports spaces around the . for functions and : for labels DOC: Updated documentation REFACTOR: Adjust tests so that the input and expected output can be seen next to each other. * restoring test fixtures * code review changes * additional tests * attempt to clean up filemodes * revert subjective style change * revert extra newline * revert extra newlines Co-authored-by: Andrew Powell <[email protected]>
1 parent 56b3725 commit a014c66

File tree

14 files changed

+327
-23
lines changed

14 files changed

+327
-23
lines changed

packages/strip/README.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,42 +51,52 @@ Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#comma
5151
### `include`
5252

5353
Type: `String | RegExp | Array[...String|RegExp]`<br>
54-
Default: `['**/*.js']`
54+
Default: `['**/*.js']`<br>
55+
Example: `include: '**/*.(mjs|js)',`<br>
5556

5657
A pattern, or array of patterns, which specify the files in the build the plugin should operate on.
5758

5859
### `exclude`
5960

6061
Type: `String | RegExp | Array[...String|RegExp]`<br>
61-
Default: `[]`
62+
Default: `[]`<br>
63+
Example: `exlude: 'tests/**/*',`<br>
6264

6365
A pattern, or array of patterns, which specify the files in the build the plugin should _ignore_.
6466

6567
### `debugger`
6668

6769
Type: `Boolean`<br>
68-
Default: `true`
70+
Default: `true`<br>
71+
Example: `debugger: false,`<br>
6972

70-
If `true`, instructs the plugin to remove debugger statements.
73+
If `true` instructs the plugin to remove debugger statements.
7174

7275
### `functions`
7376

7477
Type: `Array[...String]`<br>
75-
Default: `[ 'console.*', 'assert.*' ]`
78+
Default: `[ 'console.*', 'assert.*' ]`<br>
79+
Example: `functions: [ 'console.log', 'MyClass.Test' ],`<br>
7680

7781
Specifies the functions that the plugin will target and remove.
7882

83+
_Note: specifying functions that are used at the begining of a chain, such as 'a().b().c()', will result in '(void 0).b().c()' which will generate an error at runtime._
84+
7985
### `labels`
8086

8187
Type: `Array[...String]`<br>
82-
Default: `[]`
88+
Default: `[]`<br>
89+
Example: `labels: ['unittest'],`<br>
90+
91+
Specifies the [labeled blocks or statements](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label) that the plugin will target and remove.
8392

84-
Specifies the [labeled blocks](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label) that the plugin will target and remove.
93+
_Note: the '**:**' is implied and should not be specified in the config._
8594

8695
### `sourceMap`
8796

8897
Type: `Boolean`<br>
89-
Default: `true`
98+
Default: `true`<br>
99+
Example: `sourceMap: false,`<br>
90100

91101
If `true`, instructs the plugin to update source maps accordingly after removing configured targets from the bundle.
92102

packages/strip/src/index.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,30 @@ export default function strip(options = {}) {
3939

4040
const removeDebuggerStatements = options.debugger !== false;
4141
const functions = (options.functions || ['console.*', 'assert.*']).map((keypath) =>
42-
keypath.replace(/\./g, '\\.').replace(/\*/g, '\\w+')
42+
keypath.replace(/\*/g, '\\w+').replace(/\./g, '\\s*\\.\\s*')
4343
);
4444

4545
const labels = options.labels || [];
4646

47-
const firstpass = new RegExp(`\\b(?:${functions.join('|')}|debugger)\\b`);
48-
const pattern = new RegExp(`^(?:${functions.join('|')})$`);
47+
const labelsPatterns = labels.map((l) => `${l}\\s*:`);
48+
49+
const firstPass = [...functions, ...labelsPatterns];
50+
if (removeDebuggerStatements) {
51+
firstPass.push('debugger\\b');
52+
}
53+
54+
const reFunctions = new RegExp(`^(?:${functions.join('|')})$`);
55+
const reFirstpass = new RegExp(`\\b(?:${firstPass.join('|')})`);
56+
const firstPassFilter = firstPass.length > 0 ? (code) => reFirstpass.test(code) : () => false;
57+
const UNCHANGED = null;
4958

5059
return {
5160
name: 'strip',
5261

5362
transform(code, id) {
54-
if (!filter(id)) return null;
55-
if (functions.length > 0 && !firstpass.test(code)) return null;
63+
if (!filter(id) || !firstPassFilter(code)) {
64+
return UNCHANGED;
65+
}
5666

5767
let ast;
5868

@@ -81,7 +91,7 @@ export default function strip(options = {}) {
8191
if (parent.type === 'ExpressionStatement') {
8292
removeStatement(parent);
8393
} else {
84-
magicString.overwrite(node.start, node.end, 'void 0');
94+
magicString.overwrite(node.start, node.end, '(void 0)');
8595
}
8696

8797
edited = true;
@@ -93,7 +103,7 @@ export default function strip(options = {}) {
93103
if (isBlock(parent)) {
94104
remove(node.start, node.end);
95105
} else {
96-
magicString.overwrite(node.start, node.end, 'void 0;');
106+
magicString.overwrite(node.start, node.end, '(void 0);');
97107
}
98108

99109
edited = true;
@@ -114,21 +124,25 @@ export default function strip(options = {}) {
114124

115125
if (removeDebuggerStatements && node.type === 'DebuggerStatement') {
116126
removeStatement(node);
127+
this.skip();
117128
} else if (node.type === 'LabeledStatement') {
118129
if (node.label && labels.includes(node.label.name)) {
119130
removeStatement(node);
131+
this.skip();
120132
}
121133
} else if (node.type === 'CallExpression') {
122134
const keypath = flatten(node.callee);
123-
if (keypath && pattern.test(keypath)) {
135+
if (keypath && reFunctions.test(keypath)) {
124136
removeExpression(node);
125137
this.skip();
126138
}
127139
}
128140
}
129141
});
130142

131-
if (!edited) return null;
143+
if (!edited) {
144+
return UNCHANGED;
145+
}
132146

133147
code = magicString.toString();
134148
const map = sourceMap ? magicString.generateMap() : null;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* eslint-disable */
2+
export default function foo() {
3+
before();
4+
debugger;
5+
logging:
6+
console.log('a');
7+
console.error('b');
8+
after();
9+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* eslint-disable */
2+
before();
3+
f().t();
4+
after();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* eslint-disable */
2+
before();
3+
function f() {
4+
return {
5+
g: function () {
6+
return {
7+
hello: function () {
8+
console.log('hello');
9+
}
10+
};
11+
}
12+
};
13+
}
14+
15+
Test
16+
.
17+
f()
18+
. g() .
19+
hello();
20+
after();
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* eslint-disable */
2+
before();
3+
unittest
4+
: {
5+
test('some test', (assert) => {
6+
});
7+
}
8+
again();
9+
unittest:console.log();
10+
after();
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/* eslint-disable */
2+
before();unittest:console.log();after();
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/* eslint-disable */
2+
before();
3+
unittest
4+
: {
5+
test('some test', (assert) => {
6+
});
7+
}
8+
again();
9+
unittest:console.log();
10+
after();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/* eslint-disable */
2+
before();
3+
unittest : {
4+
test('some test', (assert) => {
5+
});
6+
}
7+
after();
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/* eslint-disable */
2+
console.log(['h', 'e', 'y'].forEach((letter) => console.warn(letter)))
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/* eslint-disable */
2+
export default function foo() {
3+
before();
4+
debugger;
5+
logging:
6+
console.log('a');
7+
console.error('b');
8+
after();
9+
}

0 commit comments

Comments
 (0)