Skip to content

Commit

Permalink
Ensure --watch mode exits correctly when stdin is closed. (#3493)
Browse files Browse the repository at this point in the history
* Ensure --watch mode exits correctly when stdin is closed.

This is necessary when rollup is used as the front end for an Elixir
Phoenix application. In dev mode, the phoenix watchers run the rollup
command as a child process and the underlying erlang port mechanism
assumes that the child process closes when the parent stdin is
closed. Without this fix the old zombie processes never close and
accumulate as you stop and start in development mode.

This was discussed and fixed in 2017 in the original rollup-watcher
repository:

  * rollup/rollup-watch#30 (comment)
  * https://github.com/rollup/rollup-watch/pull/57/files

It appears to then have been removed as a side effect of another change

  * rollup/rollup#2410

Finally, was requested back in a PR that never got merged because of
some doubt around the need to hide it behind a CLI flag

  * https://github.com/rollup/rollup/pull/2653/files

For reference, webpack implements this hidden behind the --watch-stdin
CLI flag.

* Add a test that times out without this change

Co-authored-by: Lukas Taegert-Atkinson <[email protected]>
  • Loading branch information
jakesgordon and lukastaegert authored Apr 12, 2020
1 parent b463308 commit 57bb54e
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 1 deletion.
2 changes: 1 addition & 1 deletion cli/run/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export default async function watch(command: any) {

onExit(close);
process.on('uncaughtException' as any, close);
// only listen to stdin if it is a pipe
if (!process.stdin.isTTY) {
process.stdin.on('end', close);
process.stdin.resume();
}

if (configFile) {
Expand Down
4 changes: 4 additions & 0 deletions test/cli/samples/watch/close-stdin/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
command: 'node wrapper.js main.js --watch --format es --file _actual/out.js',
description: 'closes the watcher when stdin closes'
};
3 changes: 3 additions & 0 deletions test/cli/samples/watch/close-stdin/_expected/out.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var main = 42;

export default main;
1 change: 1 addition & 0 deletions test/cli/samples/watch/close-stdin/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 42;
26 changes: 26 additions & 0 deletions test/cli/samples/watch/close-stdin/wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/usr/bin/env node

const stream = require('stream');
const fs = require('fs');
const path = require('path');

delete process.stdin;
process.stdin = new stream.Readable({
encoding: 'utf8',
read() {
return null;
}
});

const outputDir = path.resolve(__dirname, '_actual');
fs.mkdirSync(outputDir);
const outputFile = path.resolve(outputDir, 'out.js');
fs.writeFileSync(outputFile, 'NOT WRITTEN');

const watcher = fs.watch(outputFile, () => {
watcher.close();
// This closes stdin
process.stdin.push(null);
});

require('../../../../../dist/bin/rollup');

0 comments on commit 57bb54e

Please sign in to comment.