create-react-appを捨てて、Reactアプリ用の独自のテンプレートを作成する

本日公開する記事の著者は、React開発者に、使用をやめてcreate-react-app(CRA)、Reactアプリケーション用の独自のテンプレートを作成するように勧めています。ここでは、CRAの長所と短所について説明し、を置き換えることができるソリューションを提案しますcreate-react-app







CRAとは何ですか?



Create React Appは、Facebookの開発者によって構築および保守されている一連のツールです。CRAは、テンプレート化されたReactアプリケーションをすばやく作成するためのものです。CRAを使用すると、Reactプロジェクトベースが1つのコマンドで作成されます。



CRAの強み



  • CRAを使用すると、次の1つのコマンドでReactプロジェクトのベースを作成できます。



    npx create-react-app my-app
    
  • CRAを使用すると、開発者は補助ツールを詳細に調査する必要がなくなります。開発者はReactに集中でき、Webpack、Babel、およびその他のユーティリティメカニズムの設定について心配する必要はありません。
  • CRAを適用する場合、開発者はプロジェクトの構築に関連する1つの依存関係のみを必要とします。これはreact-scriptsです。この依存関係には、他のすべてのアセンブリ依存関係が含まれます。その結果、たとえば、依存関係をインストールおよび更新するには、1つのコマンドで十分であることがわかります。



    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- . , , , .
  • CRAは、私には思えますが、一部のプロジェクトでは、請求されていないことが判明する可能性のある機会でいっぱいになっています。たとえば、CRAで作成されたアプリケーションスタブはSASSをサポートします。つまり、プロジェクトで通常のCSS以下を使用している場合、SASSのサポートは完全に不要になります。ここに、興味があればpackage.json、コマンドの後のCRAアプリケーションファイルがありますejectこのファイルは、以前に提示された依存関係を「展開」しましたreact-scripts


CRAの代わりに、基本的なReactプロジェクトをすばやく作成するための独自のテンプレートを開発することもできます。



CRAの代替



CRAに代わるものを開発する際に、1つのコマンドを使用して基本的なReactプロジェクトをすばやく作成する機能をCRAに装備します。これは、便利な機能の1つを繰り返しますcreate-react-app。もちろん、CRAの欠点をシステムに転送することはなく、依存関係を個別にインストールしてプロジェクトを設定します。私たちのプロジェクトには、他の2つの便利なCRA機能(補助メカニズムと「1つの依存関係」スキームを研究する必要性を開発者から排除する)は含まれません。これらには欠点もあるためです(補助サブシステムの内部メカニズムを開発者から隠すことと、独自のプロジェクトビルド構成のカスタマイズの複雑さ)。 ..。



ここで私たちは、この記事で議論することを、すべてのコードが含まれているリポジトリ。



ツールを使用してプロジェクトをnpm初期化し、そのgitリポジトリを初期化することから始めましょう



npm init
git init


.gitignore次の内容の ファイルを作成しましょう



node_modules
build


これにより、ファイルに名前が含まれているフォルダーをリポジトリに含めないようにすることができます。



次に、Reactアプリケーションを構築して実行するために必要な基本的な依存関係について考えてみましょう。



Reactおよびreact-domライブラリ



必要なランタイム依存関係は次のとおりです。



npm install react react-dom --save


トランスパイラー(バベル)



Babelトランスパイラーは、ECMAScript 2015+準拠のコードを、新しいブラウザーと従来のブラウザーの両方で機能するコードに変換します。Babelは、プリセットを使用しているため、JSXコードの処理にも使用されます。



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


これは、Reactアプリケーションを稼働させるための単純なBabel構成のように見えます。この構成は、ファイル.babelrcまたは以下に追加できますpackage.json



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


Babelは多くのプリセットプラグインをサポートしていますそれらは、必要に応じてプロジェクトに追加できます。



バンドラー(ウェブパック)



Webpackバンドラーは、プロジェクトのビルドを担当し、プロジェクトコードとその依存関係のコードに基づいて単一のアプリケーションファイル(バンドル)を形成します。コード分​​割などのプロジェクト最適化手法を使用する場合、アプリケーションバンドルに複数のファイルを含めることができます。



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


Reactアプリパッケージを構築するための単純なWebpack構成は次のようになります。



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',
    }),
  ],
};


特定のアプリケーションのニーズに応じて、さまざまなブートローダーをここに追加できますこのトピックに興味がある場合は、私の記事をご覧ください。ここでは、本番環境で使用するReactアプリケーションを準備するために使用できるWebpack構成について説明しています。



これらはすべて、必要な依存関係です。次に、テンプレートHTMLファイルとスタブReactコンポーネントをプロジェクトに追加しましょう。



プロジェクトディレクトリにフォルダを作成し、srcそれにファイルを追加しますindex.html



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


同じフォルダにReactコンポーネントを作成しますHelloWorld



import React from 'react';

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

export default HelloWorld;


同じフォルダにファイルを追加しますindex.js



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

import HelloWorld from './HelloWorld';

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


そして最後に、プロジェクトpackage.jsonを起動(start)およびビルド(build)するためのスクリプト説明に追加します。



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


それで全部です。これで、実行可能なスタブReactアプリケーションを自由に使用できるようになりました。これは、コマンドnpm startとを実行して確認できますnpm run build



それでは、1つのコマンドでプロジェクトテンプレートを準備する機能をシステムに装備しましょう。つまり、CRAの強みの1つを再現します。コマンドラインで適切なコマンドを入力すると呼び出される実行可能なJSファイルを使用します。たとえば、次のようなコマンドは次のようになります。



reactjs-boilerplate new-project


このアイデアを実装するために、ファイルのbinセクションを使用しますpackage.json



まず、fs-extraパッケージをインストールします



npm i fs-extra


次に、プロジェクトstart.jsフォルダにある実行可能なJSファイルを作成しましょうbinこのファイルに次のコードを入れましょう:



#!/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));
      }
    );
  }
);


それでは、このJS実行可能ファイルを次のコマンドにリンクしましょうpackage.json



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


パッケージのローカルリンクを作成しましょう。



npm link


さて、このコマンドを実行した後、端末でこの形式のコマンドを実行するyour-boilerplate-name my-appと、実行可能ファイルはと呼ばれstart.jsます。これは、名前の新しいフォルダが作成されますmy-app、ファイルをコピーしpackage.jsonwebpack.config.jsそして.gitignore、だけでなく、フォルダsrc、および新しいプロジェクトの依存関係をインストールmy-app



素晴らしい。これですべてがコンピューター上で実行され、1つのコマンドで独自のビルド構成を使用して基本的なReactプロジェクトを作成できます。



先に進んで、テンプレートをnpmレジストリに公開できます。これを行うには、最初にプロジェクトをGitHubリポジトリに送信する必要があります。次に、これらの指示に従います。



おめでとう!ほんの数分で代替案を作成しましたcreate-react-app。私たちのソリューションは、不要な機能で過負荷になることはありません(必要に応じて、それに基づいて作成されたプロジェクトに依存関係を追加できます)。これを使用すると、ニーズに合わせてプロジェクトビルド構成を簡単に調整できます。



もちろん、私たちのソリューションは最小限です。それに基づいて作成されたプロジェクトは、本番環境で使用できる状態にあるとは見なされません。実際の作業に備えて準備するには、プロジェクトビルドの最適化を担当するWebpack設定をテンプレートに装備する必要があります。reactjs-boilerplateテンプレート



を用意しました生産の準備ができたプロジェクトを作成できます。コミットを作成する前にプロジェクトをチェックするための適切なビルド構成、リンティング、およびフックを使用します。このテンプレートを試してください。それを改善するためのアイデアがある場合、またはその開発に貢献することを決定した場合は、それに参加してください。



結果



この記事で話したことは次のとおりです。



  • 長所と短所について説明しましたcreate-react-app
  • プロジェクトでは、1つのコマンドで空白のReactアプリケーションを作成するための便利なCRA機能を実装しました。そして、CRAの欠点を取り除きました。
  • Reactアプリケーションの構築と実行に必要な最小限のWebpackとBabel構成をプロジェクトに装備しました。
  • Reactコンポーネントを作成しHelloWorld.js、プロジェクトをビルドして開発サーバーを使用して実行する機能を提供しました。
  • 実行可能なJSファイルを作成し、binファイルセクションを使用して適切なコマンドにリンクしましたpackage.json
  • チームを使用npm linkしてプロジェクトのローカルリンクを作成し、単一のチームでそこから新しいベースラインプロジェクトを作成できるようにしました。


この資料が、Reactに基づくプロジェクトの開発に役立つことを願っています。



新しいReactプロジェクトを作成するときにcreate-react-appを使用しますか?






All Articles