10

I need a complete guide or a good reference material to solve the running module commands within javascript file problem.

Say that I often run:

$ npm run webpack-dev-server --progress --colors -- files

How can I run this within a javascript file and execute with

$ node ./script.js

script.js

var webpackDevServer = require('webpack-dev-server');

// need help here
var result = webpackDevServer.execute({
  progress: true,
  colors: true,
}, files);

3 Answers 3

16

Answer

I do something like this for my Webpack bundles. You can simply use child_process.spawn to execute command-line programs and handle the process in a node script.

Here's an example:

var spawn = require('child_process').spawn

// ...

// Notice how your arguments are in an array of strings
var child = spawn('./node_modules/.bin/webpack-dev-server', [
    '--progress',
    '--colors',
    '<YOUR ENTRY FILE>'
]);

child.stdout.on('data', function (data) {
    process.stdout.write(data);
});

child.stderr.on('data', function (data) {
    process.stdout.write(data);
});

child.on('exit', function (data) {
    process.stdout.write('I\'m done!');
});

You can handle all of the events you like. This is a fairly powerful module that allows you to view the process' PID (child.pid) and even kill the process whenever you choose (child.kill()).


Addendum

A neat trick is to throw everything into a Promise. Here's a simplified example of what my version of script.js would look like:

module.exports = function () {
    return new Promise(function (resolve, reject) {
        var child = spawn('./node_modules/.bin/webpack', [
            '-d'
        ]);

        child.stdout.on('data', function (data) {
            process.stdout.write(data);
        });

        child.on('error', function (data) {
            reject('Webpack errored!');
        });

        child.on('exit', function () {
            resolve('Webpack completed successfully');
        });
    });
}

Using this method, you can include your script.js in other files and make this code synchronous in your build system or whatever. The possibilities are endless!


Edit The child_process.exec also lets you execute command-line programs:

var exec = require('child_process').exec

// ...

var child = exec('webpack-dev-server --progress --colors <YOUR ENTRY FILES>',
  function(err, stdout, stderr) {
    if (err) throw err;
    else console.log(stdout);
});
Sign up to request clarification or add additional context in comments.

2 Comments

that's awesome, is there anyway i can do this without spawn?
@user2167582 Yep! You can use child_process.exec see my edit.
1

The accepted answer doesn't work on Windows and doesn't handle exit codes, so here's a fully featured and more concise version.

const spawn = require('child_process').spawn
const path = require('path')

function webpackDevServer() {
    return new Promise((resolve, reject) => {
        let child = spawn(
            path.resolve('./node_modules/.bin/webpack-dev-server'),
            [ '--progress', '--colors' ],
            { shell: true, stdio: 'inherit' }
        )
        
        child.on('error', reject)
        child.on('exit', (code) => code === 0 ? resolve() : reject(code))
    })
}

path.resolve() properly formats the path to the script, regardless of the host OS.

The last parameter to spawn() does two things. shell: true uses the shell, which appends .cmd on Windows, if necessary and stdio: 'inherit' passes through stdout and stderr, so you don't have to do it yourself.

Also, the exit code is important, especially when running linters and whatnot, so anything other than 0 gets rejected, just like in shell scripts.

Lastly, the error event occurs when the command fails to execute. When using the shell, the error is unfortunately always empty (undefined).

Comments

0

Do you need it to be webpack-dev-server? There is an equivalent webpack-dev-middleware for running within node/express:

'use strict';
let express = require('express');
let app = new express();

app.use(express.static(`${__dirname}/public`));

let webpackMiddleware = require('webpack-dev-middleware');
let webpack = require('webpack');
let webpackConfig = require('./webpack.config.js');
app.use(webpackMiddleware(webpack(webpackConfig), {}));

app.listen(3000, () => console.log(`Server running on port 3000...`));

https://github.com/webpack/webpack-dev-middleware

1 Comment

the problem im trying to solve has less to do with webpack but with a way to run npm modules within javascript files, so that i can invoke compositioned macro commands via node ./myscript.js

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.