web-dev-qa-db-fra.com

Détecter le développement/la production de React/ReactDOM

Réaliser le développement de la génération se comporte différemment de la génération de la production, par ex. la gestion des erreurs.

Il est possible de déterminer lequel est utilisé dans l'environnement, mais uniquement dans un environnement modulaire, en raison de l'utilisation de process.env.NODE_ENV par le package React :

if (process.env.NODE_ENV === 'production') {
  module.exports = require('./cjs/react.production.min.js');
} else {
  module.exports = require('./cjs/react.development.js');
}

Le cas où process.env peut être inapplicable est React utilisé globalement comme module UMD, window.React et window.ReactDOM:

<script src="some-unknown-react-version.js"></script>

<script>
React // is it in production mode?
</script>

Les utilisations possibles sont:

  • un composant qui peut fonctionner dans des environnements modulaires et globaux (publiés en tant que UMD) et restitué différemment en production

  • extension de navigateur ou script utilisateur dans lequel le mode génération/production est détecté à partir de l'objet React ou ReactDOM

Comment le développement/la production de React peut-il être détecté avec précision au moment de l'exécution sans recourir à l'environnement?

Je recherche une solution fiable et propre applicable à React 15 et à React 16 si possible.

Il ne s'agit pas d'un duplicata de questions similaires car les réponses existantes résolvent le problème par le biais de process.env.

8
estus

Il y a une différence. En mode de développement, les éléments React ont la propriété _self définie, alors qu'en mode de production, cette propriété n'est pas définie.

Une solution consiste donc à tester cette propriété avec un code comme celui-ci:

function ReactIsInDevelomentMode(){ 
    return '_self' in React.createElement('div');
}
5
Constantin Galbenu

Votre question est claire mais vous ne précisez pas votre système de compilation. Utilisez-vous webpack ou parcel? Avez-vous Server Side Rendering ou non? exécutez-vous votre application construite avec node ou pm2? ou vous construisez simplement votre application, puis insérez le fichier fourni intégré dans votre page, créé par une autre technologie, telle que PHP ou C#?

En fait, les questions ci-dessus peuvent déterminer votre réponse, mais vous utilisez sûrement un bundle de modules. Je propose donc de résoudre un fichier config dans votre projet.

Si j’étais chez vous, j’utilise sans doute webpack, deux fichiers de configuration Webpack, un pour le développement et un pour le mode production. Je crée ensuite un dossier contenant deux fichiers avec config.dev.js et config.prod.js. Dans le webpack de développement:

~~~
module.exports = {
        ~~~
        resolve: {
            extensions: ['.js', '.jsx'],
            alias: {
                ~~~
                Config: `${srcDir}/config/config.dev.js`,
                // srcDir is a defined variable for source directory
            }
        },
        ~~~

Dans le webpack de production:

~~~
module.exports = {
        ~~~
        resolve: {
            extensions: ['.js', '.jsx'],
            alias: {
                ~~~
                Config: `${srcDir}/config/config.prod.js`,
                // srcDir is a defined variable for source directory
            }
        },
        ~~~

Et maintenant, vous pouvez mettre chaque donnée dev et prod pour vos types de construction. Par exemple, dans votre config.dev.js, vous pouvez écrire:

module.exports = {
    buildType: "dev"
};

Certes, dans votre config.prod.js peut écrire:

module.exports = {
    buildType: "prod"
};

Absolument, vous pouvez accéder aux données de configuration avec le code ci-dessous dans vos fichiers react:

import config from 'Config';

Et avec cette solution, vous pouvez comprendre le type de votre construction dans l'exécution en temps réel de votre application.

Note: Pour plus d'informations, vous pouvez voir mon support article , et si vous ne connaissez pas les lectures longues, consultez l'article repositoryAussi la version la plus récente du exemple de ma réponse repository qui contient les configs.

3
AmerllicA

Détecter la version de développement/production chez le client à l'aide d'une version umd semble être une longue étape . Si une telle exigence existe, pourquoi ne pas créer votre application avec create-react-app?

Je ne dois pas juger vos décisions, alors voici quelque chose d'utile.

Le plugin react-dev-tools fourni par facebook détecte le type de construction.

Voici la partie pertinente du plugin mentionné ci-dessus: 

https://github.com/facebook/react-devtools/blob/faa4b630a8c055d5ab4ff51536f1e92604d5c09c/backend/installGlobalHook.js#L23

J'espère que vous pourrez le rendre utile. 

1
Arun Karunagath

Il y a un petit "hack" qui peut être fait pour vérifier quelle version de React a été chargée.

L'objet React est disponible dans les variables globales et la version de production de React diffère de la version de développement par au moins une chose: elle est généralement réduite. Nous pouvons donc essayer de vérifier si nous travaillons avec une version réduite ou non. 

Pour vérifier, vous pouvez comparer le nom de la fonction au nom de la propriété de la méthode d’un objet React, par exemple:

let func = 'Component'
if (React[func].name === func) {
  // non-minified -> development build
}

Cette méthode ne consiste pas à vérifier la production et le développement, mais à vérifier la minification, et comme la production est généralement minisée, cela peut vraiment aider.

1
Dolf Barr

React fournit les versions de développement et de production des liens react.js:

Développement:

<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

Production:

<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>

la source


Et pour savoir si elle est en mode développement ou en mode production sans variable d’environnement, vous devez déclarer explicitement une variable en lui affectant son mode: (incluez le script suivant ainsi que le script rea)

<script>
var devMode = 'development';
</script>

et recherchez le devMode chaque fois que nécessaire.


Alternativement, vous pouvez vérifier son mode comme: (vous devez ajouter un identifiant dans la balise script)

var script_id = document.getElementById('script-attached-id');
console.log(script_id.getAttribute('src').includes('development'));

De cette façon, il vous suffit de mettre à jour le chemin source et de détecter le mode.


Et la dernière option, je peux penser à lire le fichier lui-même et à détecter son mode puisque réagit dans son commentaire comme:

Développement:

/** @license React v16.5.2
 * react.development.js

Production:

/** @license React v16.5.2
 * react.production.min.js

Donc, après avoir lu le fichier, vérifiez son mode en deuxième ligne. Ou vous pouvez tester react.development.js sans vérification ligne par ligne.

0

Comment se présente votre configuration de déploiement? Il n'y a pas de "bonne" façon de faire ce que vous voulez faire. Je voudrais me concentrer sur les différences entre la production/développement et créer ma propre fonction d'assistance.

EDIT: Il semble qu'il ne soit pas possible de détecter la version prod/dev de la classe React.

Deux idées:

  1. Je ne suis pas sûr de savoir comment l'application est construite, mais PropTypes devrait être un bon identificateur ENV.
  2. Si votre application React de production est réduite, vous pouvez simplement détecter si le code de réaction est réduit. (ce sera hacky mais ça devrait marcher, se concentrer sur un nombre d'espaces ou la longueur de ligne, ...)

J'ai remarqué dans les commentaires ci-dessous que vous dites que minified !== production, si vous pouvez le faire de cette façon, c'est probablement votre meilleur pari. De toute façon, vous n'avez pas besoin de minimiser le développement.

0
Michal

Certains ont évoqué le fait que la production sera toujours minimisée et que le développement ne le sera pas. Voici une solution concrète qui utilise ceci:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>

<script>
const reactInfo = {
    version: React.version,
    development: (String((new React.Children.map()).constructor).length > 100)
};
console.log(reactInfo);
</script>

<div id="content"></div>

J'ai testé cela sur une douzaine de versions de réagissent de v14 à v16. De ici vous pouvez voir que ce code n’a pas été modifié depuis sa première écriture, à l’exception d’un petit montage datant de l’année dernière (ce qui n’affecterait pas cette réponse car il y a trop peu de caractères, bien que les versions testées avant 11mo de toute façon et il y a un écart décent).

Remarque

Dev contient 200 caractères et Prod, 70. Il existe donc un rapport de 3: 1 pour un rapport de caractère Dev: Prod. J'ai choisi 100 parce que l'ajout de 90 caractères de code ajoutera 30 lignes à prod, de sorte que 100 est le meilleur emplacement avec les informations données (techniquement ~ 105 ou quelque chose comme ça). L'ajout de 90 caractères ou la suppression de 100 caractères est extrêmement improbable pour une fonction aussi simple (une fonction qui n'a été touchée qu'une fois en 5 ans avec une modification de 20 caractères). Je pense donc que cela devrait être stable.

Pour plus de stabilité, ou au moins savoir s’il se casse, vous pouvez vérifier s’il s’agit de 25 à 70 caractères, et renvoyer une erreur si ce n’est pas le cas. Cela devrait permettre d’attraper de gros changements (je donnerais cette option avec une certitude à 100% qu’il ne cachera jamais un bogue), mais vous risquez d’obtenir des faux positifs. Lequel vous voulez dépend de votre cas d'utilisation.

MODIFIER:

En examinant la minification, il s’agit d’une expression rationnelle qui en déduira si une fonction a été minifiée, afin que vous puissiez l’utiliser en toute sécurité. Il va également planter si React.Children.map n'est pas une fonction (ne se produira presque certainement jamais), que vous pouvez intercepter ou ne pas intercepter en fonction du degré de rigueur avec lequel vous souhaitez gérer le cas improbable d'une erreur (ou simplement l'ignorer, parce que, comme pourquoi auraient-ils jamais le changer). La signature de la fonction reste, même si elle est minifiée dans [native code], donc elle est plutôt à l'épreuve du futur. J'irais avec le premier pour la simplicité cependant.

const reactInfo = {
    version: React.version,
    development: !/function\s?\w?\(\w(,\w)*\)/.test(String((new React.Children.map()).constructor).split("{")[0])
};
0
Nicholas Pipitone