Skip to content

Commit bb649d4

Browse files
watch: strip watch flags from NODE_OPTIONS in child process
Signed-off-by: marcopiraccini <marco.piraccini@gmail.com>
1 parent 3725bd2 commit bb649d4

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

lib/internal/main/watch_mode.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const {
77
ArrayPrototypePush,
88
ArrayPrototypePushApply,
99
ArrayPrototypeSlice,
10+
RegExpPrototypeSymbolSplit,
1011
StringPrototypeStartsWith,
1112
} = primordials;
1213

@@ -84,6 +85,32 @@ for (let i = 0; i < process.execArgv.length; i++) {
8485

8586
ArrayPrototypePushApply(argsWithoutWatchOptions, kCommand);
8687

88+
const kNodeOptions = process.env.NODE_OPTIONS;
89+
let cleanNodeOptions = kNodeOptions;
90+
if (kNodeOptions != null) {
91+
const nodeOptionsArgs = [];
92+
const parts = RegExpPrototypeSymbolSplit(/\s+/, kNodeOptions);
93+
for (let i = 0; i < parts.length; i++) {
94+
const part = parts[i];
95+
if (part === '') continue;
96+
if (part === '--watch' ||
97+
part === '--watch-preserve-output' ||
98+
StringPrototypeStartsWith(part, '--watch=') ||
99+
StringPrototypeStartsWith(part, '--watch-preserve-output=') ||
100+
StringPrototypeStartsWith(part, '--watch-path=') ||
101+
StringPrototypeStartsWith(part, '--watch-kill-signal=')) {
102+
continue;
103+
}
104+
if (part === '--watch-path' || part === '--watch-kill-signal') {
105+
// These flags take a separate value argument
106+
i++;
107+
continue;
108+
}
109+
ArrayPrototypePush(nodeOptionsArgs, part);
110+
}
111+
cleanNodeOptions = ArrayPrototypeJoin(nodeOptionsArgs, ' ');
112+
}
113+
87114
const watcher = new FilesWatcher({ debounce: 200, mode: kShouldFilterModules ? 'filter' : 'all' });
88115
ArrayPrototypeForEach(kWatchedPaths, (p) => watcher.watchPath(p));
89116

@@ -99,6 +126,7 @@ function start() {
99126
env: {
100127
...process.env,
101128
WATCH_REPORT_DEPENDENCIES: '1',
129+
NODE_OPTIONS: cleanNodeOptions,
102130
},
103131
});
104132
watcher.watchChildProcessModules(child);

test/sequential/test-watch-mode.mjs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,4 +922,37 @@ process.on('message', (message) => {
922922
await done();
923923
}
924924
});
925+
926+
it('should strip all watch flags from NODE_OPTIONS in child process', async () => {
927+
const file = createTmpFile('console.log(process.env.NODE_OPTIONS);');
928+
const nodeOptions = [
929+
'--watch', // bare boolean
930+
'--watch=true', // boolean with =value
931+
'--watch-path=./src', // string with =value
932+
'--watch-path', './test', // String with space-separated value
933+
'--watch-preserve-output', // bare boolean
934+
'--watch-preserve-output=true', // boolean with =value
935+
'--watch-kill-signal=SIGKILL', // string with =value
936+
'--watch-kill-signal', 'SIGINT', // String with space-separated value
937+
'--max-old-space-size=4096',
938+
'--no-warnings',
939+
].join(' ');
940+
const { done, restart } = runInBackground({
941+
args: ['--watch', file],
942+
options: {
943+
env: { ...process.env, NODE_OPTIONS: nodeOptions },
944+
},
945+
});
946+
947+
try {
948+
const { stdout, stderr } = await restart();
949+
950+
assert.strictEqual(stderr, '');
951+
const nodeOptionsLine = stdout.find((line) => line.includes('--max-old-space-size'));
952+
assert.ok(nodeOptionsLine);
953+
assert.strictEqual(nodeOptionsLine, '--max-old-space-size=4096 --no-warnings');
954+
} finally {
955+
await done();
956+
}
957+
});
925958
});

0 commit comments

Comments
 (0)