Comment activer / désactiver le `` mode développement '' de ReactJS?

120

J'ai commencé à utiliser la fonction de validation des accessoires de ReactJS , qui, comme le disent les documents, ne fonctionne qu'en `` mode développement '' pour des raisons de performances.

React semble valider les propriétés d'un composant particulier que j'ai annoté, mais je ne me souviens pas avoir explicitement activé le «mode développement».

J'ai essayé de chercher comment déclencher / activer le mode de développement, mais je n'ai pas eu de chance.

gdso
la source
excellente explication succincte de process.envpour les utilisateurs de Webpack: stackoverflow.com/questions/37311972/…
ptim

Réponses:

129

L'autre réponse suppose que vous utilisez des fichiers externes pré-construits de react, et bien que cela soit correct, ce n'est pas ainsi que la plupart des gens vont ou devraient consommer React en tant que package. De plus, à ce stade, la plupart des bibliothèques et packages React reposent également sur la même convention pour désactiver les assistants de temps de développement pendant la production. Le simple fait d'utiliser la réaction minifiée laissera également toutes ces optimisations potentielles sur la table.

En fin de compte, la magie se résume à l'incorporation de références à React dans process.env.NODE_ENVtoute la base de code; ceux-ci agissent comme une bascule de fonctionnalité.

if (process.env.NODE_ENV !== "production")
  // do propType checks

Ce qui précède est le modèle le plus courant, et d'autres bibliothèques le suivent également. Donc, pour "désactiver" ces vérifications, nous devons basculerNODE_ENV vers"production"

La bonne façon de désactiver le "mode dev" est d'utiliser le bundler de votre choix.

Webpack

Utilisez le DefinePlugindans votre configuration Webpack comme ceci:

new webpack.DefinePlugin({
  "process.env.NODE_ENV": JSON.stringify("production")
})

Naviguer

Utilisez la transformation Envify et exécutez votre étape de génération browserify avec NODE_ENV=production( "set NODE_ENV=production"sous Windows)

Résultat

Cela produira des bundles de sortie dont toutes les instances de seront process.env.NODE_ENVremplacées par la chaîne littérale:"production"

Prime

Lors de la réduction du code transformé, vous pouvez profiter de "Dead Code Elimination". DCE est lorsque le minificateur est assez intelligent pour se rendre compte que: "production" !== "production"est toujours faux et supprimera donc tout code dans le bloc if vous économisant des octets.

panique monastique
la source
1
La documentation sur
React
1
Avez-vous vraiment besoin de JSON.stringify ('production') là-bas? Ou est-ce que la «production» suffit?
Vlad Nicula
4
@VladNicula il doit être '"production"'ie. guillemets doubles, stringify fait ça pour vous
monastic-panic
1
Vous pouvez également l'utiliser JSON.stringify(process.env.NODE_ENV)pour qu'il puisse être basculé via NODE_ENV=production webpack ...sur la ligne de commande. Bonus de code explicite ajouté =)
Henry Blyth
2
Je viens de découvrir que cette DefinePluginutilisation peut être remplacée parnew webpack.EnvironmentPlugin(['NODE_ENV'])
Henry Blyth
50

Oui, ce n'est pas vraiment bien documenté, mais sur la page de téléchargement de ReactJS, il parle des modes de développement et de production:

Nous proposons deux versions de React: une version non compressée pour le développement et une version minifiée pour la production. La version de développement inclut des avertissements supplémentaires sur les erreurs courantes, tandis que la version de production inclut des optimisations de performances supplémentaires et supprime tous les messages d'erreur.

Fondamentalement, la version non réduite de React est le mode "développement", et la version réduite de React est le mode "production".

Pour être en mode "production", il suffit d'inclure la version minifiée react-0.9.0.min.js

Edward M Smith
la source
2
Si votre bundler se réduit, je ne pense pas qu'il supprimera le débogage. Vous devez inclure la version minifiée de React dans votre version de production - celle incluse dans la distribution React - c'est en fait un code différent de la version non minifiée, d'après ce que je comprends.
Edward M Smith
17
Si vous construisez npmdirectement à partir du package react, utilisez quelque chose comme envify pour définir NODE_ENV = 'production'les mêmes vérifications. @EdwardMSmith Faites-moi savoir où vous auriez voulu voir cette information et je peux l'ajouter (ou vous pouvez simplement soumettre un PR)!
Sophie Alpert
2
@BenAlpert - Je dirais une page sous Guides ou Astuces décrivant le déploiement de la production. Je vais jeter un œil et voir ce que je peux trouver. Je n'ai pas réellement fait de déploiement de production, il peut donc avoir besoin de quelques révisions. Je vais soumettre un PR.
Edward M Smith
1
Je voulais juste ajouter à ce sujet que la version addon ne semble pas avoir le mode développement activé, même la version non réduite.
KallDrexx
8
Je ne pense pas que ce soit la meilleure réponse car certaines personnes construisent leur réaction avec browserify et une réponse utilisant NODE_ENVdevrait être présente en haut.
Bjorn
16

J'ai posté ceci ailleurs mais, franchement, ici serait un meilleur endroit.

En supposant que vous installez React 15.0.1 avec npm, import react from 'react'ou react = require('react')que vous exécuterez ./mode_modules/react/lib/React.jsla source brute de React.

La documentation React vous suggère d'utiliser ./mode_modules/react/dist/react.jspour le développement et react.min.jspour la production.

Si vous minimisez /lib/React.jsou /dist/react.jspour la production, React affichera un message d'avertissement indiquant que vous avez minifié le code de non-production:

Warning: It looks like you're using a minified copy of the development build of React. When deploying React apps to production, make sure to use the production build which skips development warnings and is faster. See fb.me/react-minification for more details.

react-dom, redux, react-redux se comportent de la même manière. Redux affiche un message d'avertissement. Je pense que react-dom aussi.

Vous êtes donc clairement encouragé à utiliser la version de production de /dist.

Cependant, si vous réduisez les /distversions, UglifyJsPlugin de webpack se plaindra.

WARNING in ../~/react/dist/react.js Critical dependencies: 4:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results. @ ../~/react/dist/react.js 4:478-4851

Vous ne pouvez pas éviter ce message car UglifyJsPlugin ne peut exclure que des blocs Webpack, pas des fichiers individuels.

J'utilise /distmoi-même les versions de développement et de production .

  • Webpack a moins de travail à faire et se termine un peu plus tôt. (YRMV)
  • Les documents React disent qu'il /dist/react.min.jsest optimisé pour la production. Je n'ai lu aucune preuve que 'process.env': { NODE_ENV: JSON.stringify(IS_PRODUCTION ? 'production' : 'development') }plus uglify fait un aussi bon travail que «/ dist / react.min.js». Je n'ai lu aucune preuve que vous obtenez le même code résultant.
  • Je reçois 1 message d'avertissement de uglify au lieu de 3 de l'écosystème react / redux.

Vous pouvez faire en sorte que webpack utilise les /distversions avec:

resolve: {
    alias: {
      'react$': path.join(__dirname, 'node_modules', 'react','dist',
        (IS_PRODUCTION ? 'react.min.js' : 'react.js')),
      'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist',
        (IS_PRODUCTION ? 'react-dom.min.js' : 'react-dom.js')),
      'redux$': path.join(__dirname, 'node_modules', 'redux','dist',
        (IS_PRODUCTION ? 'redux.min.js' : 'redux.js')),
      'react-redux$': path.join(__dirname, 'node_modules', 'react-redux','dist',
        (IS_PRODUCTION ? 'react-redux.min.js' : 'react-redux.js'))
    }
  }
JohnSz
la source
1
Si vous exécutez à partir du webpack cli: const IS_PRODUCTION = process.argv.indexOf ('- p')! == -1;
Greg
2
Ce n'est pas la solution recommandée (source: je travaille sur React). Les solutions correctes sont documentées ici: reactjs.org/docs/… . S'ils ne fonctionnent pas pour vous, déposez un problème dans le dépôt React et nous essaierons de vous aider.
Dan Abramov
4

Pour la construction basée sur webpack, j'avais l'habitude de configurer webpack.config.js séparé pour DEV et PROD. Pour Prod, résolvez l'alias comme ci-dessous

     alias: {
        'react$': path.join(__dirname, 'node_modules', 'react','dist','react.min.js'),
        'react-dom$': path.join(__dirname, 'node_modules', 'react-dom','dist','react-dom.min.js')
    }

Vous pouvez trouver celui qui fonctionne à partir d' ici

Senthil
la source
1
Ce n'est pas la solution recommandée (source: je travaille sur React). Les solutions correctes sont documentées ici: reactjs.org/docs/… . S'ils ne fonctionnent pas pour vous, déposez un problème dans le référentiel React et nous essaierons de vous aider.
Dan Abramov
1

Si vous travaillez à partir de quelque chose comme ce tutoriel ReactJS.NET / Webpack , vous ne pouvez pas utiliser process.env pour activer / désactiver le mode de développement React pour autant que je sache. Cet exemple renvoie directement à react.js (voir Index.cshtml ), il vous suffit donc de choisir .min.js ou la variante non minifiée en modifiant l'URL.

Je ne sais pas pourquoi c'est le cas, car le webpack.config.js de l'exemple a un commentaire qui semble impliquer externals: { react: 'React' }qu'il ferait le travail, mais continue et inclut réagir directement dans la page.

Roman Starkov
la source
Si je l'ai bien deviné, vous dites que si vous regroupez et minifiez à l'aide de ReactJS.Net, cela ne bénéficiera pas de la minification du fichier de développement react.js. Pour cela, tout en utilisant les contrôles #IF DEBUG, il faut modifier explicitement l'URL du fichier de production de react.js fourni à partir de la page de téléchargement Facebook. Similaire au cas avec react-dom et Redux. Ai-je raison?
Faisal Mq
@FaisalMushtaq Cela en fait partie; selon la façon dont vous incluez react.js, vous devrez peut-être basculer explicitement vers la version minifiée. Mais ce que je voulais vraiment dire, c'est qu'il est possible de configurer React de telle sorte que la manière «officielle» d'activer le mode développement ne fonctionnera pas.
Roman Starkov
0

Pour les utilisateurs de Webpack v4 uniquement :

Spécifier mode: productionet mode: developmentdans votre configuration Webpack définira process.env.NODE_ENVà l'aide du DefinePlugin par défaut. Aucun code supplémentaire nécessaire!

webpack.prod.js (extrait de la documentation)

const merge = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
  mode: 'production',
});

Et dans notre JS:

console.log(process.env.NODE_ENV) // --> 'development' or 'production'

Webpack Docs: https://webpack.js.org/guides/production/#specify-the-mode

Joe
la source
0

J'utilise un processus de construction manuel qui passe par Webpack, donc c'était un processus en deux étapes pour moi:

  1. Définissez la variable d'environnement de package.json à l'aide du package cross-env:

    "scripts": { "build-dev": "cross-env NODE_ENV=development webpack --config webpack.config.js", "build-prod": "cross-env NODE_ENV=production webpack --config webpack.config.js" }

  2. Modifiez le fichier webpack.config.js pour utiliser la variable d'environnement (qui est transmise à React pour déterminer si nous sommes en mode développement ou production), et désactivez la minimisation du bundle produit si nous sommes en mode développement afin que nous puissions voir le les noms réels de nos composants. Nous devons utiliser la propriété d' optimisation de webpack dans notre fichier webpack.config.js pour cela:

    optimization: { nodeEnv: process.env.NODE_ENV, minimize: process.env.NODE_ENV === 'production' }

webpack v4.41.5, React v16.9.19, cross-env v7.0.0, nœud v10.16.14

John Galt
la source