web-dev-qa-db-fra.com

Pourquoi la version de production de l’application React (avec Webpack et Babel) utilise-t-elle une erreur de développement avec HMR, ce qui provoque des erreurs?

J'essaie de créer une version de production de mon projet React, mais il sélectionne la mauvaise configuration.

Dans la version de développement, j'utilise HMR (Hot Module Replacement). Ceci est configuré dans .babelrc, sous env > development > plugins. Lors de l'ajout d'un noeud env > production supplémentaire, il semble être ignoré. Il utilise toujours la configuration de développement avec HMR, ce qui provoque une erreur:

Erreur non capturée: les sections locales [0] ne semblent pas être un objet module avec l'API de remplacement de module actif activée. Vous devez désactiver react-transform-hmr en production en utilisant la section env dans la configuration de Babel. Voir l'exemple dans le fichier README: https://github.com/gaearon/react-transform-hmr

Bien sûr, j'ai vérifié cette information, mais tout semble bien aller. Lorsque j'ai supprimé le plug-in HMR de la configuration de développement de .babelrc, cela fonctionne, prouvant qu'il utilise bien la configuration de développement au lieu de la production. Voici mes fichiers:

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": []
        }
    }
}

Comme vous pouvez le voir dans package.json > scripts > deploy, je mets même explicitement le BABEL_ENV sur 'production'.

Pourquoi cela arrive-t-il? Comment puis-je m'assurer que la version de production ignore les plug-ins HMR?

En passant, les recherches mènent souvent à numéro 5 de la page React-transform-HMR Github , qui est un long fil conducteur sans solution claire.

Édition 2016.03.30: Ajout de la partie Babel de ma configuration de pack Web sur demande. Édition 2016.04.06: Ajout du fichier webpack complet sur demande.

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'
            }
        ]
    }
};
15
Micros

La seule chose qui a fonctionné pour moi, c'est que j'ai écrit - 

process.env.NODE_ENV = 'production';

au début de mon fichier webpack.config.prod.js.

9
alexunder

Il semble que, peu importe ce que Babel continue d'utiliser, la section development de la valeur env spécifiée dans .babelrc. Ce qui a résolu le problème pour moi, a été d'utiliser un nom autre que "développement" et de le définir comme valeur de BABEL_ENV.

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

J'utilise conf séparé pour le développement. Dans les plugins j'ai:

new webpack.DefinePlugin({
  'process.env': {
    'NODE_ENV': JSON.stringify('development'),
    'BABEL_ENV': JSON.stringify('dev')
  }
}),
2
Mati

& dans Shell signifie qu'il s'exécutera en arrière-plan. Votre déclaration de variable n'est donc peut-être pas capturée par le processus de construction qui se produit en même temps. La bonne chose est que vous pouvez simplement ajouter à la commande les déclarations de variables.

Vous pouvez simplifier les commandes comme ceci:

"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"
0
Mijamo

Vous pouvez simplement utiliser le 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']
              }
            }
        }
    }
0
andykenward