Reactのようなフレームワークをゼロから作成する

Reactのようなフレームワークをゼロから作成する

最近、インターネットで「Build your own React」という記事を見ました。著者は、シンプルなReact風のフレームワークをゼロから実装しました。最適化はあまり行われていませんでしたが、Concurrent ModeやFiber Reconcilerなど、Reactのコアとなるアイデアはすべて実装されていました。読んだ後、Reactの理解に非常に役立ちました。そこで、「Build your own React」に基づいてコードを分割し、独自のフレームワークプロジェクトを構築してから、チュートリアルで完了しなかった他の機能を改善したいと思います。コードはracにあります。

プロジェクト構築

技術スタックとしては、開発には TypeScript、パッケージングには Rollup を使用することにしました。これらはあまり使わない技術なので、一緒に練習します。webpack と比較すると、rollup の設定は簡単です。プロジェクトに tsconfig.json と rollup.config.js を作成し、rollup-plugin-typescript2、rollup-plugin-terser などの必要なロールアップ プラグインをインストールします。また、サンプルフォルダを用意し、小さなデモプロジェクトを作成し、tsxを使用して開発します。

jsxをサポート

TypeScript で jsx をサポートするには、tsconfig で jsx を有効にする必要があります。TypeScript には、preserve、react、react-native の 3 つのモードがあります。react に設定すると、TypeScript はコード内の jsx を React.createElement に変換します。これが、jsx を使用するときに React をスコープ内に含めなければならない理由です。

しかし、React のようなフレームワークを独自に実装したい場合は、React.createElement の名前を変更するだけです。 Build your own React では、/** @jsx Didact.createElement */ コメントを使用して、コンパイラに jsx の出力関数を Didact.createElement に変更するように指示しています。この方法は、現在のファイルに対してのみ有効です。プロジェクトで使用する場合は、ファイルごとにコメント行を追加するのが面倒になります。 tsconfig の jsxFactory 属性 (ここでは h と呼びます) を通じて指定する別の方法を使用します。React.createEmenent に加えて、特別な要素である Fragment もあります。TypeScript はデフォルトでこれを React.Fragment に変換します。jsxFragmentFactory を通じてこれを直接 Fragment に変更します。

tsconfig.json:

{
  "コンパイラオプション": {
    "ターゲット": "esnext",
    "モジュール": "commonjs",
    "モジュール解像度": "ノード",
    "jsx": "react", // jsx を有効にする
    "jsxFactory": "h", // React.createElement => h
    "jsxFragmentFactory": "Fragment", // React.Fragment => Fragment
    "ルートディレクトリ": "./src",
    "lib": ["dom", "es2015"]
  }
}

ロールアップ構成

Rollup の設定は比較的簡単です。入力と出力に加えて、いくつかのプラグインを追加できます。

定数パス = require('path')
定数typescript = require('rollup-plugin-typescript2')
const { terser } = require('rollup-plugin-terser')
const eslint = require('@rollup/plugin-eslint')

エクスポートデフォルト{
  入力: 'src/index.ts',
  出力: [
    { ファイル: 'dist/rac.umd.js'、形式: 'umd'、名前: 'rac' }
  ]、
  プラグイン: [
    簡潔(),
    エスリント({
      throwOnError: true、
      インクルード: ['src/**/*.ts']
    })、
    タイプスクリプト({
      詳細度: 0,
      tsconfig: path.resolve(__dirname, 'tsconfig.json'),
      useTsconfigDeclarationDir: true
    })
  ]
}

TypeScript での Eslint

Eslint が TypeScript をサポートできるようにするには、Eslint にいくつかの追加設定が必要です。

モジュール.エクスポート = {
  パーサー: '@typescript-eslint/parser',
  環境: {
    es6: 本当、
    ブラウザ: true
  },
  プラグイン: [
    '@typescript-eslint'
  ]、
  拡張: [
    'eslint:推奨',
  ]、
  パーサーオプション: {
    ソースタイプ: 'モジュール'
  },
  ルール:
    ...
  }
}

プロジェクト構造

Reactの新しいFiberアーキテクチャにはいくつかのコアコンセプトがあります。Build your own Reactでは、著者は次のように説明しています。

  • ステップ I: createElement 関数
  • ステップ II: レンダリング機能
  • ステップ III: 並行モード
  • ステップIV: 繊維
  • ステップ V: レンダリングとコミットのフェーズ
  • ステップ VI: 和解
  • ステップ VII: 関数コンポーネント
  • ステップ VIII: フック

これらの手順により、ミニ React が徐々に実装されます。コードの可読性と保守性を向上させるために、これらの関数は異なるファイルに分割されます。

。
├── README.md
├── examples // デモディレクトリ├── package.json
├── rollup.config.js
├── 出典
│ ├── ドム.ts
│ ├── h.ts
│ ├── hooks.ts
│ ├── index.ts
│ ├── reconciler.ts
│ ├── スケジューラ.ts
│ └── type.ts
└── tsconfig.json
  • dom.ts で DOM 関連の作業を処理する
  • h.tsはjsxFactoryとjsxFragmentFactoryの実装です
  • hooks.tsはフックの実装です
  • reconciler.tsは、調整フェーズとコミットフェーズの実装です。
  • shceduler.tsはタスクスケジューラの実装です
  • type.tsは何らかの型定義である

この時点で、プロジェクトは構築されています。プロジェクト全体の構造と一部のコード実装は、fre フレームワークに基づいています。

これで、ゼロから書いたReactライクなフレームワークのプロジェクト構築と実装に関するこの記事は終了です。Reactライクな構築に関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMを応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Amap を使用した React 実装例 (react-amap)
  • Reactの仮想DOMとdiffアルゴリズムの詳細な説明
  • ファイルのアップロードの進行状況を示す React の例
  • React で遅延読み込みを使用して最初の画面の読み込み時間を短縮する方法
  • WeChat公式アカウントでReactプロジェクトを実行する方法
  • ReactでCSSをエレガントに書く方法
  • 最も単純な ErrorBoundary コンポーネントをカプセル化して、React 例外を処理する
  • React Fiber構造の作成手順
  • React の 3 つの主要属性における Ref の使用に関する詳細な説明
  • React useEffect の理解と使用

<<:  nginxのシンプル転送リクエストのサーバーとロケーション設定の詳しい説明

>>:  Java で ffmpeg を呼び出してビデオ形式を flv に変換する方法の詳細な説明

推薦する

Dockerを使用してDjango+MySQL8開発環境をデプロイする方法の詳細な説明

しばらく前にシステムを再インストールしましたが、バックアップを取っていなかったので、コンピューター上...

Linuxでポートが開いているかどうかを確認する方法のまとめ

方法1: lsofコマンドを使用するlsof コマンドを使用して、ポートが開いているかどうかを確認で...

Xshellの一般的な問題と関連する設定の詳細な説明

この記事では、Xshell と関連する構成の一般的な問題について説明します。この記事の構成は、主に ...

Dreamweaver で Zen コーディングを使用する方法

前回の記事「Zen Coding: HTML/CSS コードを素早く記述する方法」を公開した後、一部...

MySQL レプリケーション テーブルの詳細とサンプル コード

MySQL レプリケーション テーブルの詳細な説明テーブル構造、インデックス、デフォルト値などを含む...

MySQL データ型の最適化の原則

MySQL は多くのデータ型をサポートしており、高パフォーマンスを得るには適切なデータ型を選択するこ...

JavaScript BOMの構成と一般的なイベントの詳細な説明

目次1. 部品2. BOMの構成2. ウィンドウオブジェクトの共通イベント1. ウィンドウ読み込みイ...

MySQL クエリ キャッシュのグラフィカルな説明

目次1. 原則の概要クエリキャッシュシステム変数1. クエリキャッシュを持つ2. クエリキャッシュ制...

Navicat が MySQL にリモート接続するときに発生する 10060 不明エラーを解決する方法

はじめに:今日は、サーバー上のMySQLにリモート接続したいと思います。使用するソフトウェアはNav...

Zookeeperスタンドアロン環境とクラスタ環境の構築

1. 単一マシン環境の構築# 1.1 ダウンロードZookeeper の対応するバージョンをダウンロ...

MySQLにおける正規表現の一般的な使用法

MySQL における Regexp の一般的な使用法特定の文字列を含むあいまい一致# コンテンツフィ...

Vueは製品の拡大鏡効果を実現します

この記事の例では、製品の拡大鏡効果を実現するためのVueの具体的なコードを共有しています。具体的な内...

MySQL 5.5.27 winx64 のインストールと設定方法のグラフィックチュートリアル

1. インストールパッケージMYSQLサービスダウンロードアドレス:MySQL公式サイトからダウンロ...

読み取り専用と無効の微妙な違いの詳細な説明

「読み取り専用」と「無効」はどちらも、ユーザーがフォーム フィールドの内容を変更できないようにします...

シンプルなログインページを実装するための HTML+jQuery

目次導入公開コード(バックエンドインターフェース)例 1: 最もシンプル (純粋な HTML)コード...