Search code examples
npmgulpenvironment-variablescommand-line-argumentspackage.json

Running gulp with options supplied via environment variables does not work on Windows


I have been programming mostly on macOS hence my package.json looks like this:

[...]
"scripts": {
    "build": "NODE_TARGET=electron NODE_CONFIGURATION=development gulp",
    "watch": "NODE_TARGET=electron NODE_CONFIGURATION=development gulp watch",
    "build:web": "NODE_TARGET=web NODE_CONFIGURATION=development gulp",
    "watch:web": "NODE_TARGET=web NODE_CONFIGURATION=development gulp watch",
    "release": "NODE_TARGET=electron NODE_CONFIGURATION=production gulp",
    "release:web": "NODE_TARGET=web NODE_CONFIGURATION=production gulp",
    "clean": "gulp clean",
    "start": "electron ."
}
[...]

At first I tried supplying those parameters via command line arguments in the form of gulp --web but I did not find any library that parsed those properly. Therefore I am using environment variables before the call and access those in the gulpfile.babel.js like this:

const targetPlatform = {
    isElectron: process.env.NODE_TARGET === "electron",
    isWeb: process.env.NODE_TARGET === "web"
};

Unfortunately I did not take into consideration that Windows is not really able to handle the commands/variables supplied by the npm scripts. I'd like to know how I can make those calls portable across Windows and macOS.


Solution

  • A friend of mine suggested using cross-env which basically solves the problem that I had.

    Before using that package I just parsed the process.argv array with the following code:

    const commandLineArguments = (argumentList => {
        let parsedArguments = {}, index, option, thisOption, currentOption;
        for (index = 0; index < argumentList.length; index++) {
            thisOption = argumentList[index].trim();
            option = thisOption.replace(/^\-+/, '');
            if (option === thisOption) {
                if (currentOption) {
                    parsedArguments[currentOption] = option;
                }
                currentOption = null;
            } else {
                currentOption = option;
                parsedArguments[currentOption] = true;
            }
        }
        return parsedArguments;
    })(process.argv);
    

    Using a call like gulp --target electron --configuration development I can access those arguments like this:

    const targetPlatform = {
        isElectron: commandLineArguments.target === "electron",
        isWeb: commandLineArguments.target === "web"
    };
    // Default setting if no option was supplied
    if (!targetPlatform.isElectron && !targetPlatform.isWeb) {
        targetPlatform.isElectron = true;
    }