16

I'm trying to create a production build of my React project, but it picks the wrong configuration.

In the development version I'm using HMR (Hot Module Replacement). This is configured in .babelrc, under env > development > plugins. When adding an extra node env > production it seems to be ignored. It's still using the development configuration with HMR, which causes an error:

Uncaught Error: locals[0] does not appear to be a module object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using env section in Babel configuration. See the example in README: https://github.com/gaearon/react-transform-hmr

Of course I've checked that information, but everything seems right. When I removed the HMR plugin from .babelrc's development config, it works, proving it is indeed using the development config instead of production. Here's my files:

package.json

{
  "name": "myproject",
  "main": "index.js",
  "scripts": {
    "serve": "cross-env NODE_ENV=development webpack-dev-server --content-base bin/ --devtool eval --progress --colors --hot --inline",
    "deploy": "cross-env NODE_ENV=production BABEL_ENV=production webpack -p --config webpack.production.config.js"
  }
  //dependencies omitted in this example
}

.babelrc

{
    "presets": ["react", "es2015", "stage-0"],
    "plugins": [
        ["transform-decorators-legacy"]
    ],
    "env": {
        "development": {
            "plugins": [
                ["react-transform", {
                    "transforms": [{
                        "transform": "react-transform-hmr",
                        "imports": ["react"],
                        "locals": ["module"]
                    }]
                }]
            ]
        },
        "production": {
            "plugins": []
        }
    }
}

As you can see in package.json > scripts > deploy, I'm even explicitly setting the BABEL_ENV to 'production'.

Why is this happening? How do I make sure the production build ignores the HMR plugins?

By the way, searching often leads to issue #5 on the React-transform-HMR Github page, which is a long thread without a clear solution.

Edit 2016.03.30: Adding the Babel part of my webpack config on request. Edit 2016.04.06: Adding whole webpack file on request.

webpack.production.config.js

require('es6-promise').polyfill();
var path = require('path');

module.exports = {
    entry: './main.jsx',
    context: __dirname + path.sep + 'src',
    output: {
        path: path.resolve(__dirname, './bin'),
        filename: 'index.js'
    },
    devServer: {
        port: 3333
    },
    module: {
        loaders: [
            {
                test: /\.js(x?)$/,
                exclude: /node_modules/,
                loader: 'babel',
                query: {
                    presets: ['react', 'es2015', 'stage-0'],
                    plugins: [['transform-decorators-legacy']]
                }
            },
            {
                test: /\.css$/,
                loader: "style!css"
            },
            {
                test: /\.scss$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'style-loader!css-loader!sass-loader?sourceMap'
            }
        ]
    }
};
Micros
  • 5,966
  • 2
  • 28
  • 34

4 Answers4

8

The only thing that worked for me, is that I wrote -

process.env.NODE_ENV = 'production';

at the beginning of my webpack.config.prod.js file.

alexunder
  • 2,075
  • 3
  • 16
  • 29
5

It seems that no matter what Babel keeps using the development section of the env value specified in .babelrc. What solved the problem for me, was to use name other than 'development' and set that as the value of BABEL_ENV.

"env": {
    "dev": {
        "plugins": [
        ]
    },
    "production": {
    }
}

I use separate conf for development. In plugins I have:

new webpack.DefinePlugin({
  'process.env': {
    'NODE_ENV': JSON.stringify('development'),
    'BABEL_ENV': JSON.stringify('dev')
  }
}),
Mati
  • 1,378
  • 15
  • 20
0

& in shell means that it will run in the background, so maybe your variable declaration is not caught by the build stuff that happens at the same time. The good thing is that you can just prepend the command with the variable declarations.

You could simplify the commands like this:

"serve": "NODE_ENV=development webpack-dev-server --content-base bin/ --devtool eval --progress --colors --hot --inline",
"deploy": "NODE_ENV=production BABEL_ENV=production webpack -p --config webpack.production.config.js"
Mijamo
  • 3,436
  • 1
  • 21
  • 21
  • Thanks @Mijamo. We had already removed SET and the &-signs and added cross-env for windows-compatibility. (I've modified the question to reflect this) However, the problem persists, so the `&` was not causing the problem... – Micros Mar 30 '16 at 15:29
0

You can just use the babel-preset-react-hmre.

.babelrc

{
    "presets": ["react", "es2015", "stage-0"],
    "plugins": [
        "transform-decorators-legacy"
    ],
    "env": {
        "development": {
            "presets": ["react-hmre"]
        }
    }
}

webpack

    {
        test: /\.js(x?)$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
            presets: ['es2015', 'react', 'stage-0'],
            plugins: ['transform-decorators-legacy'],
            env: {
              development: {
                presets: ['react-hmre']
              }
            }
        }
    }
andykenward
  • 924
  • 7
  • 17
  • Though that seems to stop that error, Babel is still using the env.development part of my configuration and ignoring my env.production. So I'm not getting a successfully built js-file. Any ideas on that? – Micros Apr 06 '16 at 09:36
  • @Micros i need to see your complete webpack file. Or better the repo if possible – andykenward Apr 06 '16 at 09:39
  • Ok, I modified the question with the full webpack config file. – Micros Apr 06 '16 at 09:47
  • ok I have made a quick [Gist](https://gist.github.com/andykenward/995e0dfc17d2d913757e592e04fec5f2) of what kind of setup i use. When I get a chance will make a working repo to see if it works. – andykenward Apr 06 '16 at 10:58
  • @Micros Any news? I'm facing a similar problem, setting NODE_ENV everywhere, can't think of anything else to try.... Could you please post your solution here? Thanks. – alexunder Jul 13 '16 at 09:15
  • Hi @alexunder, yes, in the end there was no way to get the compiler to respect the .babelrc config. So I stopped using that file and made two webpack.configs. One for debug, one for production. The babel configuration is set in the webpack files, eliminating the whole problem. Let me know if that works for you. I'll add this answer soon. – Micros Jul 14 '16 at 11:53
  • @Micros Hi, yep, you can see my answer below, did the same thing eventually :) – alexunder Jul 14 '16 at 12:16