Passing the NODE_ENV value using Webpack via DefinePlugin

13,136

Solution 1

The problem is because you are using cross-env in a wrong way. It only changes env variables for its context, so when you use '&&' to run webpack it is already gone and webpack see nothing.

So you MUST write

"scripts": {
    "build": "rimraf dist && cross-env NODE_ENV=production webpack",
    "dev": "cross-env NODE_ENV=development node webpack-dev-server.js"
},

note that you have wrote right for "build" script.

Another question is about that If you want do references to "process.env.PRODUCTION" inside your code base you should write:

   new webpack.DefinePlugin({
        "process.env.PRODUCTION": JSON.stringify(PRODUCTION),
        "proccess.env.DEVELOPMENT": JSON.stringify(DEVELOPMENT),
    });

Solution 2

The DefinePlugin expects strings so you need to JSON.stringify() any values passed into it.

new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(PRODUCTION),
    DEVELOPMENT: JSON.stringify(DEVELOPMENT)
})
Share:
13,136
Mihai
Author by

Mihai

PhD student at Tilburg University. Passionate about R and simulation designs. Working with network models in psychopathology. Enjoying web development & squash.

Updated on June 07, 2022

Comments

  • Mihai
    Mihai almost 2 years

    I am trying to inject the NODE_ENV value into my code using webpack via DefinePlugin. I checked, more or less, an identical question, but still can't get it to work.

    Specifically, here's my setup.

    In package.json:

    "scripts": {
        "build": "rimraf dist && cross-env NODE_ENV=production webpack",
        "dev": "cross-env NODE_ENV=development && node webpack-dev-server.js"
    },
    

    In webpack.config.js:

    "use strict";
    
    /* requiring the modules */
    const webpack = require("webpack");
    const path = require("path");
    
    /* defining the source and distribution paths */
    const DIST_DIR = path.resolve(__dirname, "dist");
    const SRC_DIR = path.resolve(__dirname, "src");
    
    const DEVELOPMENT = process.env.NODE_ENV === "development";
    const PRODUCTION = process.env.NODE_ENV === "production";
    // const PRODUCTION = !!process.argv.find((element) => element === '--production');
    // const DEVELOPMENT = !!process.argv.find((element) => element === '--development');
    
    
    /* defining the entries*/
    const productionEntries = {
        home: SRC_DIR + "/_home.js",
        about: SRC_DIR + "/_about.js",
    };
    const developmentEntries = Object.assign({}, productionEntries, {webpackDevServer: ["webpack/hot/dev-server", "webpack-dev-server/client?http://localhost:8080"]});
    const entries = PRODUCTION ? productionEntries : developmentEntries;
    
    
    /* defining the output */
    const output = {
        filename: "[name].js",
        path: DIST_DIR,
        publicPath: "/dist/",
        pathinfo: true,
        library: "MyLibraryName"
    };
    
    
    /* defining the plugins */
    const plugins = PRODUCTION
        ? [
            new webpack.optimize.OccurrenceOrderPlugin(),
            new webpack.optimize.AggressiveMergingPlugin(),
            new webpack.optimize.UglifyJsPlugin({comments: false}),
        ]
        :  [
            new webpack.HotModuleReplacementPlugin(),
        ];
    
    plugins.push(
        new webpack.optimize.CommonsChunkPlugin({name: "vendor.bundle", minChunks: 2}),
        new webpack.DefinePlugin({
            PRODUCTION: PRODUCTION,
            DEVELOPMENT: DEVELOPMENT,
        })
    );
    
    
    /* defining the modules -> rules -> loaders */
    const modules = {
        rules:
            [
                {
                    test: /\.(js|jsx)$/,
                    include: SRC_DIR,
                    exclude: /node_modules/,
                    loader: "babel-loader",
                    options:
                        {
                            presets: ["react", ["es2015", {modules: false}], "stage-2"]
                        }
                }
            ]
    };
    
    
    
    /* building the webpack config object */
    const config = {
        entry: entries,
        output: output,
        module: modules,
        plugins: plugins,
        devtool: "source-map",
        target: "web",
        stats: "verbose"
    };
    
    /* exporting the webpack config */
    module.exports = config;
    

    And, finally, in _about.js I have the following:

    // output after using: npm run dev
    console.log(process.env.NODE_ENV); // prints undefined
    console.log(PRODUCTION); // prints false
    console.log(DEVELOPMENT); // prints false
    
    if (module.hot) {
        module.hot.accept();
    }
    

    The problem:

    • since npm run dev runs successfully (i.e., the server starts and the plugins and entries are adequtlly selected), I don't understand why the output for console.log(DEVELOPMENT) is false, and why console.log(process.env.NODE_ENV) prints undefined.
    • in the conditional checks performed inside the webpack.config.js, the NODE_ENV value is picked properly, otherwise the the plugins, entries, and the development server wouldn't work. However, I can't pass that value down to _about.js using DefinePlugin.
    • I also tried EnvironmentPlugin, same result.

    My question: Can you, please, help me understand where things break?


    Edit 1:

    I tried the following without any improvements:

    new webpack.DefinePlugin({
        PRODUCTION: JSON.stringify(PRODUCTION),
        DEVELOPMENT: JSON.stringify(DEVELOPMENT)
    })
    

    I am running node.js on Windows 10.


    Edit 2:

    Tried:

    const DEVELOPMENT = process.env.NODE_ENV === "development";
    const PRODUCTION = process.env.NODE_ENV === "production";
    
    // with this inside plugins:
    new webpack.DefinePlugin({
        "process.env.PRODUCTION": JSON.stringify(PRODUCTION),
        "process.env.DEVELOPMENT": JSON.stringify(DEVELOPMENT)
    })
    

    and (using npm run dev) I get the following output:

    console.log(process.env.PRODUCTION); // false
    console.log(process.env.DEVELOPMENT); // false
    console.log(process.env.NODE_ENV); // undefined
    console.log(PRODUCTION); // Uncaught ReferenceError: PRODUCTION is not defined
    console.log(DEVELOPMENT); // Uncaught ReferenceError: DEVELOPMENT is not defined
    

    No improvements unfortunately.


    Edit 3:

    My devDependencies are:

    "devDependencies": {
        "babel-core": "^6.21.0",
        "babel-loader": "^6.2.10",
        "babel-preset-es2015": "^6.18.0",
        "babel-preset-react": "^6.16.0",
        "babel-preset-stage-2": "^6.18.0",
        "cross-env": "^3.1.4",
        "rimraf": "^2.5.4",
        "webpack": "^2.2.0-rc.4",
        "webpack-dev-server": "^2.2.0-rc.0"
    }
    

    Edit 4: (solved)

    @Cleiton spotted the issue. It had to do with the how the npm scripts are constructed using cross-env. See the complete answer below.

  • Mihai
    Mihai over 7 years
    Thanks, @Soviut. I've already tried it, but no improvements. I will edit my question to incorporate your answer.
  • Mihai
    Mihai over 7 years
    Thanks @Cleiton. I am trying right now. Will provide feedback in a couple of minutes.
  • Mihai
    Mihai over 7 years
    I tried your answer and, in _about.js, the output for console.log(process.env.PRODUCTION) and console.log(process.env.DEVELOPMENT) is false. The console.log(PRODUCTION) or console.log(DEVELOPMENT) outputs Uncaught ReferenceError: PRODUCTION is not defined.
  • Mihai
    Mihai over 7 years
    Thanks @Cleiton. Can't wait to check it out!
  • Mihai
    Mihai over 7 years
    Brilliant! Thanks @Cleiton. It works! I can't believe what the issue was. You made my day! I will mark your post as the accepted answer as soon as it allows me.
  • Rafael Moreno
    Rafael Moreno about 6 years
    For future searches, this is from webpack's documentation