Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

webpack-dev-server cannot be killed when spawned with child_process #2168

Closed
1 of 2 tasks
AaronBeaudoin opened this issue Aug 1, 2019 · 25 comments
Closed
1 of 2 tasks

Comments

@AaronBeaudoin
Copy link

AaronBeaudoin commented Aug 1, 2019

  • Operating System: Windows 10.0.17134 Build 17134
  • Node Version: 8.11.1
  • NPM Version: 5.6.0
  • webpack Version: 4.39.0
  • webpack-dev-server Version: 3.7.2
  • Browser: Not Applicable
  • This is a bug
  • This is a modification request

Expected Behavior

webpack-dev-server should be killed with childProcess.kill() after spawning it with require("child_process").spawn().

Actual Behavior

webpack-dev-server is orphaned instead of being killed in the above scenario.

Steps to Reproduce

Create a folder with the following package.json:

{
  "name": "webpack-dev-server-process-exit-bug-test",
  "dependencies": {
    "webpack": "^4.39.0",
    "webpack-cli": "^3.3.6",
    "webpack-dev-server": "^3.7.2"
  }
}

Add a test.js file:

const { spawn: spawnProcess } = require("child_process");

let devServerProcess = spawnProcess(
  ".\\node_modules\\.bin\\webpack-dev-server", [],
  { shell: true, stdio: "inherit" });

setTimeout(_ => {
  devServerProcess.kill();
  console.log("Trying to kill webpack-dev-server...");
}, 5000);

Add a src.js file to satisfy the webpack zero-config defaults:

console.log("test");

Run npm i then node test.js and check the running processes on your system. The webpack-dev-server node has not been killed as expected.

Note

This issue still occurs when the stdio option is not supplied to the spawn function.

@AaronBeaudoin AaronBeaudoin changed the title webpack-dev-server is orphaned instead of killed when spawned with child_process webpack-dev-server cannot be killed when spawned with child_process Aug 1, 2019
@alexander-akait
Copy link
Member

alexander-akait commented Aug 1, 2019

I think duplicate #1479, we can't kill process when webpack do compilation right now, also it is unsafe for cache

@alexander-akait
Copy link
Member

Here explain #1479 (comment)

@AaronBeaudoin
Copy link
Author

If I comment out the setTimeout call in my code above and instead just use [ctrl]+[c] manually after about 5 seconds then all processes seem to be killed properly. According to the issue you referenced, shouldn't this problem still be occurring is such a scenario?

@alexander-akait
Copy link
Member

@AaronBeaudoin try to use 10 seconds or more

@AaronBeaudoin
Copy link
Author

AaronBeaudoin commented Aug 1, 2019

If the point is to ensure that compiling has completed before trying to kill the process then it's irrelevant. I get the Compiled successfully. message after about a second or two. Therefore the process is definitely not getting killed in the middle of compilation.

@AaronBeaudoin
Copy link
Author

Also it seems that using the fork function instead of the spawn function solves the issue as well:

const { fork: forkProcess } = require("child_process");

let devServerProcess = forkProcess(
  ".\\node_modules\\webpack-dev-server\\bin\\webpack-dev-server.js", []);

setTimeout(_ => {
  devServerProcess.kill();
  console.log("Trying to kill webpack-dev-server...");
}, 5000);

@alexander-akait
Copy link
Member

@AaronBeaudoin thanks for investigation, we look on this in near future, anyway feel free to debug and send a PR with fix

@AaronBeaudoin
Copy link
Author

In case it helps, it seems that when spawning processes with spawn and the shell option is set to true, an invisible cmd.exe window is created with the process running inside of it. I found that when calling childProcess.kill() the cmd.exe window is properly killed; it's just the webpack-dev-server process that was inside of it which is left still running.

@alexander-akait
Copy link
Member

@AaronBeaudoin maybe it is only on windows, can you sty this on linux?

@xiaoyouyu
Copy link

Is there a solution?

@xiaoyouyu
Copy link

var exec = require('child_process').execSync; exec(’webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --useLocalIp‘, { stdio: 'inherit' })

image

@evilebottnawi
Please, How to kill this process?

@alexander-akait
Copy link
Member

@xiaoyouyu better use execa and use something like this:

setTimeout(() => {
	subprocess.kill('SIGTERM', {
		forceKillAfterTimeout: 2000
	});
}, 1000);

@ifedyukin
Copy link

In my case I've solved same issue by next steps:

Firstly added Windows-specific code to emit SIGINT process event.

const rl = require('readline');

if (/^win/.test(process.platform)) {
  rl.createInterface({
      input: process.stdin,
      output: process.stdout
  }).on('SIGINT', () => process.emit('SIGINT'));
}

Secondly added specific code to kill process on different OS.

const { execSync } = require('child_process');

function killChildProcess(childProcess) {
    if (/^win/.test(process.platform)) {
        execSync(`taskkill /pid ${childProcess.pid} /f /t`);
    } else {
        process.kill(childProcess.pid);
    }
};

@xiaoyouyu
Copy link

In my case I've solved same issue by next steps:

Firstly added Windows-specific code to emit SIGINT process event.

const rl = require('readline');

if (/^win/.test(process.platform)) {
  rl.createInterface({
      input: process.stdin,
      output: process.stdout
  }).on('SIGINT', () => process.emit('SIGINT'));
}

Secondly added specific code to kill process on different OS.

const { execSync } = require('child_process');

function killChildProcess(childProcess) {
    if (/^win/.test(process.platform)) {
        execSync(`taskkill /pid ${childProcess.pid} /f /t`);
    } else {
        process.kill(childProcess.pid);
    }
};

How to get the childProcess

@xiaoyouyu
Copy link

@xiaoyouyu better use execa and use something like this:

setTimeout(() => {
	subprocess.kill('SIGTERM', {
		forceKillAfterTimeout: 2000
	});
}, 1000);

@ifedyukin 干的漂亮

const execa = require('execa');    
await execa('webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --useLocalIp', { stdio: 'inherit' });

@ifedyukin
Copy link

ifedyukin commented Nov 20, 2019

@xiaoyouyu I started WDS using spawn and it returns ChildProcess object that contains pid field.

@alexander-akait
Copy link
Member

/cc @hiroppy we have same problems with webpack-cli, investigate

@tkctly
Copy link

tkctly commented Nov 16, 2020

I found a description for an option with this document #devserverstdin---cli-only.
But when I use --stdin, it throw an Error: ValidationError: webpack Dev Server Invalid Options
The code about this option was already used at there

if (argv.stdin) {
process.stdin.on('end', () => {
// eslint-disable-next-line no-process-exit
process.exit(0);
});
process.stdin.resume();
}

But in options.json I can't found the schema with stdin.
I add the stdin schema in the options.json.
ummmm,Seems to work……
But why?The documents tall me, you can use it. But the fact is that it cannot be used.
This confused me. 🤔

@snitin315
Copy link
Member

@Jfreey please tell the version of wepack, webpack-cli & webpack-dev-server.

@tkctly
Copy link

tkctly commented Nov 17, 2020

@Jfreey please tell the version of wepack, webpack-cli & webpack-dev-server.

@snitin315 Please check

This is the package.json from the demo project:

{
  "name": "dev_server_stdin_bug",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "webpack": "^5.4.0",
    "webpack-cli": "^4.2.0",
    "webpack-dev-server": "^3.11.0"
  }
}

I add the property to options.json in my local source code :

    "stdin":{
      "type": "boolean"
    },

The code is below this line:

"stats": {
"anyOf": [
{
"type": "object"
},
{
"type": "boolean"
},
{
"enum": [
"none",
"errors-only",
"errors-warnings",
"minimal",
"normal",
"verbose"
]
}
]
},

Well then, It can work...

@alexander-akait
Copy link
Member

I think we can close it - no activity, if you faced with this problem again feel free to open a new issue

@nsunga
Copy link

nsunga commented Jul 20, 2023

@AaronBeaudoin were u able to solve this?

When running wds through child_process.spawn(), im able to reproduce:

this message just hangs [webpack-dev-server] Gracefully shutting down. To force exit, press ^C again. Please wait...

But when I run wds through command line ie. node node_modules/webpack-dev-server/bin/webpack-dev-server.js ..., I still get the message but importantly, the process gets killed

@matthiasgeihs
Copy link

matthiasgeihs commented Dec 19, 2023

Having the same issue (on MacOS).

const appProcess = spawn("npm", ["run", "serve"]); // runs "webpack serve"
...
appProcess.kill(); // returns true, but "webpack" still running

@alexander-akait

@alexander-akait
Copy link
Member

@matthiasgeihs Can you open a new issue with the reproducible example, thank you

@matthiasgeihs
Copy link

@alexander-akait created #5026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants