Webpack production mode - NODE_ENV undefined
Asked Answered
A

3

15

I want to make production build of my app using webpack:

"scripts": {
    "build": "webpack --mode production",
  },

In my webpack.config.js I have this line what I am using in whole config:

const isDevelopment = process.env.NODE_ENV !== 'production';

Usage example:
{
  test: /\.s(a|c)ss$/,
    exclude: /\.module.(s(a|c)ss)$/,
    loader: [
      isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader,
                    'css-loader',
                    {
                        loader: 'sass-loader',
                        options: {
                            sourceMap: isDevelopment
      }
    }
  ]
}

but process.env.NODE_ENV is always undefined.

I am on Windows 10

Am I doing something wrong?

Anamariaanamnesis answered 9/7, 2019 at 21:59 Comment(1)
Take a look at this threadAircool
A
8

Way I found is to use argv.mode variable inside export like so:

module.exports = (env, argv) => {
    const isDevelopment = argv.mode !== 'production';
    return {
      // Config...
    }
}
Anamariaanamnesis answered 9/7, 2019 at 22:9 Comment(0)
O
6

You could also manually set it like this "build": "set NODE_ENV=production webpack --mode production" (windows only)

or use cross-env Run scripts that set and use environment variables across platforms

https://www.npmjs.com/package/cross-env

"build": "cross-env NODE_ENV=production

Overton answered 9/7, 2019 at 22:30 Comment(1)
Yea but it is OS dependentClose
A
4

I also use three functions and work on the windows 10.

function devProdOption(dev, prod, argv) {
  return argv.mode === 'development' ? dev : prod;
}

function prodPlugin(plugin, argv) {
  return argv.mode === 'production' ? plugin : () => { };
}

function devPlugin(plugin, argv) {
  return argv.mode === 'development' ? plugin : () => { };
}

And in the webpack it looks like this.

plugins: [
  prodPlugin (
    new CleanWebpackPlugin ({
      verbose: true
  }), argv)
 ]

or

devtool: devProdOption('source-map', 'none', argv),

Below the entire webpack code

const webpack = require("webpack");
const path = require('path');
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const SWPrecacheWebpackPlugin = require("sw-precache-webpack-plugin");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const HtmlWebpackInlineSourcePlugin = require("html-webpack-inline-source-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

const PUBLIC_PATH = 'http://somesite.com/';
const OUTPUT_DIR = 'dist';

const entry = {
    'index': './sources/js/containers/index/index.js',
    'about': './sources/js/containers/about/about.js',
    'contact': './sources/js/containers/contact/contact.js',
};

const optimization = {
    splitChunks: {
        cacheGroups: {
            vendor: {
                test: /node_modules/,
                chunks: "all",
                name: "vendor",
                priority: 10,
                enforce: true
            }
        }
    },
    minimizer: [
        new UglifyJsPlugin({
            uglifyOptions: {
                output: {
                    comments: false
                }
            }
        })
    ]
};


module.exports = (env, argv) => {

    const type =
        argv.mode === 'production' ? {
            pathToDist: '../dist',
            mode: 'production',
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeScriptTypeAttributes: true,
                removeStyleLinkTypeAttributes: true,
                minifyCSS: true
            }
        } : {
                pathToDist: 'dist',
                mode: 'development',
                minify: false
            };

    const entryHtmlPlugins = Object.keys(entry).map(entryName => {
        return new HtmlWebPackPlugin({
            filename: `${entryName}.html`,
            template: `sources/${entryName}.html`,
            chunks: [entryName],
            minify: type.minify,
            mode: type.mode,
            // inlineSource: '.(js|css)$',
        })
    });

    const output = {
        path: path.resolve(__dirname, './dist'),
        filename: 'vendor/js/[name].[chunkhash].bundle.js'
    };

    return {
        devtool: devProdOption('source-map', 'none', argv),
        entry: entry,
        output: output,
        module: {
            rules: [
                {
                    // JS
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: {
                        loader: 'babel-loader'
                    }
                },
                {
                    // HTML
                    test: /\.html$/,
                    use: [
                        {
                            loader: "html-loader",
                            options: {
                                minimize: argv.mode === 'development' ? false : true
                            }
                        }
                    ]
                },
                {   // CSS SASS SCSS
                    test: /\.(css|sass|scss)$/,
                    use: [
                        argv.mode === 'development' ? 'style-loader' : MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                importLoaders: 2,
                                sourceMap: true
                            }
                        },
                        {
                            loader: 'postcss-loader',
                            options: {
                                sourceMap: true,
                                config: {
                                    path: './config/',
                                },
                            },
                        },
                        {
                            loader: 'sass-loader',
                            options: {
                                sourceMap: true
                            }
                        },
                        {
                            loader: 'sass-resources-loader',
                            options: {
                                resources: ['./sources/scss/main.scss']
                            },
                        }
                    ]
                },
                {
                    // IMAGES
                    test: /\.(jpe?g|png|gif|svg)$/i,
                    loader: "file-loader",
                    options: {
                        useRelativePath: true,
                        name: '[name].[ext]',
                    }
                },
            ]
        },
        optimization: argv.mode === 'production' ? optimization : {},
        plugins: [
            prodPlugin(
                new CleanWebpackPlugin({
                    verbose: true
                }), argv
            ),
            prodPlugin(
                new MiniCssExtractPlugin({
                    filename: "vendor/css/[name].[hash].css"
                }), argv
            ),
            prodPlugin(
                new SWPrecacheWebpackPlugin({
                    cacheId: 'gt',
                    dontCacheBustUrlsMatching: /\.\w{8}\./,
                    filename: 'sw.js',
                    minify: false,
                    navigateFallback: PUBLIC_PATH + 'index.html',
                    stripPrefix: OUTPUT_DIR,
                    staticFileGlobs: [
                        `${OUTPUT_DIR}/assets/manifest.json`,
                        `${OUTPUT_DIR}/favicon.ico`,
                        `${OUTPUT_DIR}/vendor/js/*.js`,
                        `${OUTPUT_DIR}/vendor/css/*.css`
                    ],
                }),
                argv
            ),
            prodPlugin(
                new CopyWebpackPlugin([
                    { from: 'sources/assets/', to: 'assets/' }
                ]), argv
            ),
            new webpack.DefinePlugin({
                PRODUCTION: JSON.stringify(true)
            }),
        ]
            .concat(entryHtmlPlugins)
        // .concat(prodPlugin(
        //     new ScriptExtHtmlWebpackPlugin({
        //         defaultAttribute: 'async'
        //     }), argv
        // ))
        // .concat(prodPlugin(
        //     new HtmlWebpackInlineSourcePlugin(), argv
        // ))
        // .concat(prodPlugin(
        //     new BundleAnalyzerPlugin({
        //         openAnalyzer: true,
        //     }), argv
        // ))
    }
};


function devProdOption(dev, prod, argv) {
    return argv.mode === 'development' ? dev : prod;
}

function prodPlugin(plugin, argv) {
    return argv.mode === 'production' ? plugin : () => { };
}

function devPlugin(plugin, argv) {
    return argv.mode === 'development' ? plugin : () => { };
}
Aircool answered 9/7, 2019 at 22:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.