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 に変換する方法の詳細な説明

推薦する

フォームから Vue ElementUI を使用してログイン効果を実装する例

目次1. ElementUIで基本的なスタイルを構築する2. [送信]ボタンをクリックして、アカウン...

Alipay の新しいホームページのフロントエンドの実践的な概要

もちろん、ページ パフォーマンスの最適化に関する個人的な経験も含まれています。ここでいくつかの点につ...

MySQL の列から行への変換のヒント (共有)

序文:多くのビジネス テーブルでは、歴史的またはパフォーマンス上の理由により、最初のパラダイムに違反...

建国記念日が近づいています。JS を使用して、建国記念日風のアバターを生成する小さなツールを実装します。実装プロセスの詳細な説明

目次1. ページレイアウト2. 画像のアップロードと表示3. キャンバスを初期化する4. テンプレー...

MySQL 8.0 の新機能の落とし穴と解決策についての簡単な説明 (要約)

1. ユーザーを作成して承認するMySQL 8.0 では、ユーザーの作成と認証が以前とは異なります...

HTML でランダムロールコーラーを実装するためのサンプルコード

この点呼装置は簡易版であり、自動停止の必要性を考慮していないため、点呼を開始した後、停止ボタンをクリ...

Vue の nextTick について話す

データが変更されても、DOM ビューはすぐには更新されません。変更直後にノードまたはその値を取得しよ...

HTML iframe と frameset の違い_PowerNode Java Academy

導入1.<iframe> タグ: iframe は、ページ内に内部フレームを生成するイン...

プロセスごとにネットワーク帯域幅を監視する Linux ツール Nethogs のインストールと展開

概要Linux 用のオープン ソース ネットワーク監視ツールは数多くあります。たとえば、帯域幅の使用...

Reactのdiffアルゴリズムの詳細な分析

Reactのdiffアルゴリズムの理解diffアルゴリズムは、 Virtual DOMの変更された部...

CSSを使用して中央に固定された2つの列と適応型列を実現する方法

1. 絶対位置とマージンを使用するこの方法の原則は、左側と右側をドキュメントの流れから外れるように配...

ウェブページの広告デザインにおけるウェブデザインの寸法とルール

1. 800*600 未満の場合、Web ページの幅が 778 以内であれば、水平スクロール バーは...

WeChatアプレットでラッキーホイールゲームを実装する方法

ここでは主に、WeChat アプレットでラッキーホイール ゲームを開発する方法を紹介します。主に J...

ウェブサイトのパフォーマンス: 画像とCookieの最適化、モバイルアプリケーションの最適化

前のセクションでは、コンテンツ、サーバー、JavaScript、CSS など、Web サイトのパフォ...

MySQLログシステムの詳細情報共有

大規模なシステムに取り組んだことがある人なら誰でも、ログの役割を過小評価してはならないことを知ってい...