简体   繁体   中英

How to use npm scripts within javascript

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);

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);
});

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 ).

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM