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 usingenv
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'
}
]
}
};
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.
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')
}
}),
&
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"
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']
}
}
}
}
来源:https://stackoverflow.com/questions/36153628/why-does-production-build-of-react-app-with-webpack-and-babel-use-wrong-develo