Abandonner create-react-app et créer votre propre modèle pour les applications React

L'auteur de l'article, dont nous publions aujourd'hui la traduction, invite les développeurs React à s'éloigner de l'utilisation create-react-app(CRA) et à créer leur propre modèle pour les applications React. Ici, nous allons parler des avantages et des inconvénients de l'ARC, ainsi qu'une solution qui peut être remplacée sera proposée create-react-app.







Qu'est-ce que l'ARC?



Create React App est une suite d'outils créés et maintenus par les développeurs de Facebook. L'ARC permet de créer rapidement des applications React basées sur des modèles. Avec CRA, une base de projet React est créée avec une seule commande.



Forces de l'ARC



  • CRA vous permet de créer une base pour un projet React avec une seule commande:



    npx create-react-app my-app
    
  • L'utilisation d'un ARC évite au développeur la nécessité d'une étude approfondie des outils auxiliaires. Le développeur peut se concentrer sur React et ne pas s'inquiéter de la configuration de Webpack, Babel et d'autres mécanismes utilitaires.
  • Lors de l'application de l'ARC, le développeur n'a besoin que d'une seule dépendance pertinente pour la construction du projet. C'est ça react-scripts. Cette dépendance inclut toutes les autres dépendances d'assembly, par conséquent, il s'avère que, par exemple, une commande suffit pour installer et mettre à jour les dépendances:



    npm install react-scripts@latest
    


CRA



  • CRA . eject, CRA- . customize-cra react-app-rewired, .
  • CRA . React- , React- . CRA « », , react-scripts — , React-. , , , react-scripts — , , «» (Babel) (Webpack), React- . , , , .
  • L'ARC, me semble-t-il, est surchargée de possibilités qui, dans certains projets, pourraient bien se révéler non réclamées. Par exemple, les talons d'application créés avec l'ARC prennent en charge SASS. Autrement dit, si votre projet utilise du CSS normal ou Less, la prise en charge de SASS sera complètement inutile. Voici , si vous êtes intéressé, le fichier de package.jsondemande de l' ARC après la commande eject. Ce fichier "déroulait" les dépendances précédemment présentées react-scripts.


Une alternative à l'ARC consiste à développer votre propre modèle pour créer rapidement des projets React de base.



Alternative à l'ARC



En développant une alternative à CRA, nous allons lui donner la possibilité de créer rapidement des projets React de base en utilisant une seule commande. Cela répète l'une des fonctionnalités utiles create-react-app. Et nous, bien sûr, ne transférerons pas les inconvénients de l'ARC à notre système, en installant indépendamment les dépendances et en mettant en place le projet. Notre projet n'inclura pas deux autres fonctionnalités utiles de l'ARC (évitant au développeur de devoir étudier les mécanismes auxiliaires et le schéma «une dépendance»), car ils comportent également des inconvénients (masquant les mécanismes internes des sous-systèmes auxiliaires au développeur et la complexité de la personnalisation de leurs propres configurations de construction de projet) ...



Voici le référentiel qui contient tout le code dont nous parlerons dans cet article.



Commençons par initialiser le projet avec des outils npmet initialiser son référentiel git:



npm init
git init


Créons un fichier avec le .gitignorecontenu suivant:



node_modules
build


Cela nous permettra de ne pas inclure dans le référentiel les dossiers dont les noms sont présents dans le fichier.



Réfléchissons maintenant aux dépendances de base dont nous avons besoin pour créer et exécuter une application React.



Bibliothèques React et React-dom



Voici les seules dépendances d'exécution dont nous avons besoin:



npm install react react-dom --save


Transpilateur (Babel)



Le transpilateur Babel convertit le code conforme ECMAScript 2015+ en code qui fonctionnera dans les navigateurs nouveaux et hérités. Babel, grâce à l'utilisation de préréglages, est également utilisé pour traiter le code JSX:



npm install @babel/core @babel/preset-env @babel/preset-react --save-dev


Voici à quoi ressemble une configuration Babel simple pour que vos applications React soient opérationnelles. Cette configuration peut être ajoutée à un fichier .babelrcou à package.json:



{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ]
}


Babel prend en charge de nombreux préréglages et plugins . Ils peuvent être ajoutés au projet au fur et à mesure des besoins.



Bandler (Webpack)



Le bundler Webpack est responsable de la construction du projet, formant un seul fichier d'application (bundle) basé sur le code du projet et le code de ses dépendances. Lors de l'utilisation de techniques d'optimisation de projet telles que le fractionnement de code, un ensemble d'applications peut inclure plusieurs fichiers.



npm install webpack webpack-cli webpack-dev-server babel-loader css-loader style-loader html-webpack-plugin --save-dev


Une configuration Webpack simple pour créer des packages d'application React ressemble à ce qui suit:



const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');

module.exports = {
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js',
  },
  resolve: {
    modules: [path.join(__dirname, 'src'), 'node_modules'],
    alias: {
      react: path.join(__dirname, 'node_modules', 'react'),
    },
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: './src/index.html',
    }),
  ],
};


Divers bootloaders peuvent être ajoutés ici, en fonction des besoins d'une application particulière . Si ce sujet vous intéresse, jetez un œil à mon matériel , où je parle des configurations Webpack que vous pouvez utiliser pour préparer les applications React à utiliser en production.



Ce sont toutes les dépendances dont nous avons besoin. Ajoutons maintenant un fichier HTML modèle et un composant React stub au projet.



Créez un dossier dans le répertoire du projet srcet ajoutez-y un fichier index.html:



<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>React Boilerplate</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>


Créez un composant React dans le même dossier HelloWorld:



import React from 'react';

const HelloWorld = () => {
  return (
      <h3>Hello World</h3>
  );
};

export default HelloWorld;


Ajoutez le fichier dans le même dossier index.js:



import React from 'react';
import { render } from 'react-dom';

import HelloWorld from './HelloWorld';

render(<HelloWorld />, document.getElementById('root'));


Et enfin, ajoutez aux package.jsondescriptions des scripts pour lancer ( start) et construire ( build) le projet:



"scripts": {
    "start": "webpack-dev-server --mode=development --open --hot",
    "build": "webpack --mode=production"
  }


C'est tout. Nous avons maintenant une application React stub fonctionnelle à notre disposition. Vous pouvez le vérifier en exécutant les commandes npm startet npm run build.



Équipons maintenant notre système de la possibilité de préparer un modèle de projet avec une seule commande. Autrement dit, nous recréerons l'une des forces de l'ARC. Nous allons utiliser un fichier JS exécutable qui sera appelé lorsque vous entrez la commande appropriée sur la ligne de commande. Par exemple, une commande comme celle-ci pourrait ressembler à ceci:



reactjs-boilerplate new-project


Pour implémenter cette idée, nous allons utiliser la section bin du fichier package.json.



Tout d'abord, installez le package fs-extra :



npm i fs-extra


Créons maintenant un fichier exécutable JS start.js, qui sera situé dans binnotre dossier de projet. Mettons le code suivant dans ce fichier:



#!/usr/bin/env node
const fs = require("fs-extra");
const path = require("path");
const https = require("https");
const { exec } = require("child_process");

const packageJson = require("../package.json");

const scripts = `"start": "webpack-dev-server --mode=development --open --hot",
"build": "webpack --mode=production"`;

const babel = `"babel": ${JSON.stringify(packageJson.babel)}`;

const getDeps = (deps) =>
  Object.entries(deps)
    .map((dep) => `${dep[0]}@${dep[1]}`)
    .toString()
    .replace(/,/g, " ")
    .replace(/^/g, "")
    //  ,     ,    
    .replace(/fs-extra[^\s]+/g, "");

console.log("Initializing project..");

//     npm-
exec(
  `mkdir ${process.argv[2]} && cd ${process.argv[2]} && npm init -f`,
  (initErr, initStdout, initStderr) => {
    if (initErr) {
      console.error(`Everything was fine, then it wasn't:
    ${initErr}`);
      return;
    }
    const packageJSON = `${process.argv[2]}/package.json`;
    //  ,   
    fs.readFile(packageJSON, (err, file) => {
      if (err) throw err;
      const data = file
        .toString()
        .replace(
          '"test": "echo \\"Error: no test specified\\" && exit 1"',
          scripts
        )
        .replace('"keywords": []', babel);
      fs.writeFile(packageJSON, data, (err2) => err2 || true);
    });

    const filesToCopy = ["webpack.config.js"];

    for (let i = 0; i < filesToCopy.length; i += 1) {
      fs.createReadStream(path.join(__dirname, `../${filesToCopy[i]}`)).pipe(
        fs.createWriteStream(`${process.argv[2]}/${filesToCopy[i]}`)
      );
    }
    // npm,   ,   .gitignore,        ;    .     GitHub-  raw- .gitignore
    https.get(
      "https://raw.githubusercontent.com/Nikhil-Kumaran/reactjs-boilerplate/master/.gitignore",
      (res) => {
        res.setEncoding("utf8");
        let body = "";
        res.on("data", (data) => {
          body += data;
        });
        res.on("end", () => {
          fs.writeFile(
            `${process.argv[2]}/.gitignore`,
            body,
            { encoding: "utf-8" },
            (err) => {
              if (err) throw err;
            }
          );
        });
      }
    );

    console.log("npm init -- done\n");

    //  
    console.log("Installing deps -- it might take a few minutes..");
    const devDeps = getDeps(packageJson.devDependencies);
    const deps = getDeps(packageJson.dependencies);
    exec(
      `cd ${process.argv[2]} && git init && node -v && npm -v && npm i -D ${devDeps} && npm i -S ${deps}`,
      (npmErr, npmStdout, npmStderr) => {
        if (npmErr) {
          console.error(`Some error while installing dependencies
      ${npmErr}`);
          return;
        }
        console.log(npmStdout);
        console.log("Dependencies installed");

        console.log("Copying additional files..");
        //     
        fs.copy(path.join(__dirname, "../src"), `${process.argv[2]}/src`)
          .then(() =>
            console.log(
              `All done!\n\nYour project is now ready\n\nUse the below command to run the app.\n\ncd ${process.argv[2]}\nnpm start`
            )
          )
          .catch((err) => console.error(err));
      }
    );
  }
);


Maintenant, lions cet exécutable JS avec la commande de package.json:



"bin": {
    "your-boilerplate-name": "./bin/start.js"
  }


Créons un lien local pour le package:



npm link


Maintenant, après avoir exécuté cette commande, si nous exécutons une commande de la forme dans le terminal your-boilerplate-name my-app, notre fichier exécutable sera appelé start.js. Il va créer un nouveau dossier avec un nom my-app, copiez les fichiers package.json, webpack.config.jset .gitignore, ainsi que le dossier src, et installer les dépendances du nouveau projet my-app.



Merveilleux. Maintenant, tout s'exécute sur votre ordinateur et vous permet de créer des projets React de base avec leur propre configuration de construction avec une seule commande.



Vous pouvez continuer et publier votre modèle dans le registre npm . Pour ce faire, vous devez d'abord soumettre le projet au référentiel GitHub. Suivez ensuite ces instructions.



Toutes nos félicitations! Nous venons de créer une alternative en quelques minutes create-react-app. Notre solution n'est pas surchargée de fonctionnalités inutiles (des dépendances peuvent être ajoutées aux projets en fonction de celle-ci au fur et à mesure des besoins). En l'utilisant, vous pouvez facilement ajuster la configuration de construction du projet en fonction de vos besoins.



Bien entendu, notre solution est minimaliste. Les projets créés sur sa base ne peuvent pas être considérés comme prêts à être utilisés en production. Afin de les préparer au travail réel, nous devons équiper notre modèle de certains paramètres Webpack chargés d' optimiser les versions de projet.



J'ai préparé le modèle reactjs-passe-partoutvous permettant de créer des projets prêts pour la production. Il utilise la configuration de construction appropriée, le linting et les crochets chargés de vérifier le projet avant de créer des commits. Essayez ce modèle. Si vous avez des idées pour l'améliorer, ou si vous décidez de contribuer à son développement, joignez-vous aux travaux.



Résultat



Voici ce dont nous avons parlé dans cet article:



  • Nous avons trié les avantages et les inconvénients create-react-app.
  • Nous avons implémenté dans notre projet une fonctionnalité CRA utile pour créer des applications React vierges avec une seule commande. Et nous avons éliminé les lacunes de l'ARC.
  • Nous avons équipé notre projet des configurations Webpack et Babel minimales requises pour créer et exécuter des applications React.
  • Nous avons créé un composant React HelloWorld.js, fourni la possibilité de construire un projet et de l'exécuter à l'aide du serveur de développement.
  • Nous avons créé un fichier JS exécutable et l'avons lié à la commande appropriée à l'aide de la section binfichier package.json.
  • Nous avons utilisé l'équipe npm linkpour créer un lien local pour notre projet et pouvoir en créer de nouveaux projets de base avec une seule équipe.


J'espère que ce matériel vous aidera à développer des projets basés sur React.



Utilisez-vous create-react-app lors de la création de nouveaux projets React?






All Articles