Aperçu du code source
Cette section vous donne un aperçu de lâorganisation du code source de React, de ses conventions et de son implĂ©mentation.
Si vous souhaitez contribuer Ă React, nous espĂ©rons que ce guide vous aidera Ă vous sentir plus Ă lâaise pour apporter des modifications.
Nous ne recommandons pas nĂ©cessairement ces conventions dans les applications React. Nombre dâentre elles existent pour des raisons historiques et sont susceptibles dâĂ©voluer avec le temps.
Dossiers racines
AprÚs avoir cloné le dépÎt React, vous verrez quelques dossiers racines :
packages
contient des métadonnées (telles quepackage.json
) et le code source (sous-répertoiresrc
) de tous les paquets du dépÎt React. Si votre modification est liée au code, vous passerez le plus clair de votre temps dans le sous-répertoiresrc
des différents paquets.fixtures
contient quelques petites applications React de test pour les contributeurs.build
est la sortie de construction de React. Il ne figure pas dans le dĂ©pĂŽt, mais il apparaĂźtra dans votre clone de React aprĂšs que vous lâaurez construit pour la premiĂšre fois.
La documentation est hébergée dans un dépÎt distinct de React.
Il existe quelques autres dossiers racines, mais ils sont principalement utilisĂ©s par lâoutillage et vous nâaurez probablement jamais affaire Ă eux lorsque vous contribuerez.
Tests colocalisés
Nous nâavons pas de rĂ©pertoire racine pour les tests unitaires. Nous les plaçons plutĂŽt dans un rĂ©pertoire appelĂ© __tests__
situĂ© Ă cĂŽtĂ© des fichiers quâils testent.
Par exemple, un test pour setInnerHTML.js
sera placé juste à cÎté, dans __tests__/setInnerHTML-test.js
.
Avertissements et invariants
Le code source de React utilise console.error
pour afficher les avertissements :
if (__DEV__) {
console.error('Il y a un souci.');
}
Les avertissements ne sont activĂ©s que dans la phase de dĂ©veloppement. En production, ils sont complĂštement retirĂ©s du code. Si vous avez besoin dâinterdire lâexĂ©cution dâune partie de code, utilisez plutĂŽt le module invariant
:
var invariant = require('invariant');
invariant(
2 + 2 === 4,
'Vous ne passerez pas !'
);
Lâinvariant est levĂ© lorsque la condition de invariant
est false
.
Le terme « invariant » signifie simplement « cette condition est toujours vraie ». Vous pouvez voir ça comme une affirmation.
Pour les invariants, il est important dâavoir un comportement similaire en dĂ©veloppement et en production, afin quâils soient levĂ©s dans les deux cas. Les messages dâerreur sont automatiquement remplacĂ©s par des codes dâerreur en production afin dâĂ©viter toute incidence nĂ©gative sur la taille (en octets) du fichier.
Développement et production
Vous pouvez utiliser la variable pseudo-globale __DEV__
dans le code source pour délimiter les blocs de code réservés au développement.
La variable est remplacée lors de la compilation et se transforme en contrÎles process.env.NODE_ENV !== 'production'
dans les builds CommonJS.
Pour les versions autonomes, la variable devient true
dans la version non-minifiĂ©e du fichier produit, alors quâelle est complĂštement effacĂ©e, ainsi que les blocs if
quâelle contrĂŽle, dans la version minifiĂ©e.
if (__DEV__) {
// Ce code va uniquement sâappliquer pendant le dĂ©veloppement.
}
Flow
Nous avons rĂ©cemment commencĂ© Ă introduire des contrĂŽles Flow dans le code source. Les fichiers marquĂ©s avec lâannotation @flow
dans le commentaire dâen-tĂȘte de licence sont soumis Ă vĂ©rification.
Nous acceptons les pull requests qui ajoutent des annotations Flow au code existant. Les annotations Flow ressemblent Ă ceci :
ReactRef.detachRefs = function(
instance: ReactInstance,
element: ReactElement | string | number | null | false,
): void {
// ...
}
Dans la mesure du possible, le nouveau code devrait utiliser des annotations Flow.
Vous pouvez exécuter yarn flow
localement pour vérifier votre code avec Flow.
Plusieurs paquets
React est un monorepo. Son dĂ©pĂŽt contient plusieurs paquets distincts afin que leurs modifications puissent ĂȘtre coordonnĂ©es et que les problĂšmes puissent ĂȘtre signalĂ©s dans un seul et mĂȘme endroit.
Le noyau de React
Le « noyau » de React inclut toutes les API React
de niveau racine, par exemple :
React.createElement()
React.Component
React.Children
Le noyau React nâinclut que les API nĂ©cessaires Ă la dĂ©finition des composants. Il nâinclut pas lâalgorithme de rĂ©conciliation ni aucun code spĂ©cifique Ă une plate-forme. Il est utilisĂ© Ă la fois par les composants de React DOM et de React Native.
Le code pour le noyau React se trouve dans packages/react
au sein de lâarborescence source. Il est disponible sur npm via le module react
. La version autonome correspondante pour lâutilisation Ă mĂȘme le navigateur est appelĂ©e react.js
, et exporte une variable globale appelée React
.
Moteurs de rendu
React a Ă©tĂ© créé Ă lâorigine pour le DOM, mais il a ensuite Ă©tĂ© adaptĂ© pour prendre Ă©galement en charge les plates-formes natives avec React Native. Câest ainsi quâest nĂ© le concept de « moteurs de rendu » (renderers, terme que nous utiliserons sans italiques dans la suite de ce texte, NdT) au sein de React.
Les renderers gĂšrent la transformation dâune arborescence React en appels Ă la plate-forme sous-jacente.
Les renderers sont également situés dans packages/
:
- Le renderer de React DOM retranscrit les composants React dans le DOM. Il implémente les API
ReactDOM
racines et est disponible via le module npmreact-dom
. Il peut aussi ĂȘtre utilisĂ© en tant que bundle autonome dans le navigateur, lequel est nommĂ©react-dom.js
et exporte une variable globaleReactDOM
. - Le renderer de React Native retranscrit les composants React sous forme de vues natives. Il est utilisé en interne par React Native.
- Le renderer de test de React retranscrit les composants React sous forme dâarbres JSON. Il est utilisĂ© par la fonctionnalitĂ© dâinstantanĂ©s (snapshots, NdT) de Jest et est disponible via le module npm react-test-renderer.
Le seul autre moteur de rendu officiellement pris en charge est react-art
. Auparavant, il se trouvait dans un dĂ©pĂŽt GitHub sĂ©parĂ©, mais nous lâavons dĂ©placĂ© dans lâarborescence source principale pour le moment.
Remarque
Techniquement, le
react-native-renderer
est une couche trĂšs mince qui apprend Ă React Ă interagir avec lâimplĂ©mentation de React Native. Le vĂ©ritable code spĂ©cifique Ă la plate-forme, qui gĂšre les vues natives et fournit les composants, rĂ©side quant Ă lui dans le dĂ©pĂŽt React Native.
Réconciliateurs
MĂȘme des moteurs de rendu trĂšs diffĂ©rents comme React DOM et React Native doivent partager beaucoup de logique. En particulier, lâalgorithme de rĂ©conciliation doit ĂȘtre aussi similaire que possible afin que le rendu dĂ©claratif, les composants personnalisĂ©s, lâĂ©tat local, les mĂ©thodes de cycle de vie et les refs fonctionnent de maniĂšre cohĂ©rente sur toutes les plates-formes prises en charge.
Pour rĂ©soudre ce problĂšme, diffĂ©rents moteurs de rendu partagent du code entre eux. Nous appelons cette partie de React un « rĂ©conciliateur ». Lorsquâune mise Ă jour telle que setState()
est planifiée, le réconciliateur appelle render()
sur les composants de lâarborescence et les monte, les met Ă jour ou les dĂ©monte.
Les rĂ©conciliateurs ne font pas lâobjet de modules sĂ©parĂ©s, car ils ne disposent actuellement dâaucune API publique. Ils sont exclusivement utilisĂ©s par les moteurs de rendu tels que React DOM et React Native.
Réconciliateur Stack
Le rĂ©conciliateur âstackâ est lâimplĂ©mentation qui sous-tend React 15 et les versions antĂ©rieures. Nous avons depuis cessĂ© de lâutiliser, mais il reste dĂ©crit en dĂ©tail dans la prochaine page.
Réconciliateur Fiber
Le rĂ©conciliateur âfiberâ reprĂ©sente une nouvelle tentative de rĂ©soudre les problĂšmes inhĂ©rents au rĂ©conciliateur âstackâ en plus de quelques problĂšmes anciens. Câest le rĂ©conciliateur par dĂ©faut depuis React 16.
Ses objectifs principaux sont :
- la capacité à diviser un travail interruptible en segments ;
- la capacité à hiérarchiser, déplacer et réutiliser des travaux en cours ;
- la capacité à jongler entre parents et enfants pour exécuter une mise en page avec React ;
- la capacité à renvoyer plusieurs éléments depuis
render()
; - une meilleure prise en charge des pĂ©rimĂštres dâerreur.
Vous pouvez en apprendre davantage sur lâarchitecture React Fiber ici et ici. Bien quâelles soient livrĂ©es avec React 16, les fonctionnalitĂ©s asynchrones ne sont pas encore activĂ©es par dĂ©faut.
Son code source est situé dans packages/react-reconciler
.
SystĂšme dâĂ©vĂ©nements
React implĂ©mente une abstraction par-dessus les Ă©vĂ©nements natifs afin de lisser les disparitĂ©s dâun navigateur Ă lâautre. Son code source se trouve dans packages/react-dom/src/events
.
Et maintenant ?
Lisez la prochaine page pour en apprendre davantage sur lâimplĂ©mentation du rĂ©conciliateur utilisĂ© avant React 16. Nous nâavons pas encore documentĂ© les dĂ©tails internes dâimplĂ©mentation du nouveau rĂ©conciliateur.