バニラJSX


こんにちは!この記事では、タイプスクリプトとViteバンドルのプロジェクトでJSXを使用できる方法を説明します.この材料はあなたのためです.
  • ⚛️ しかし、それがJSXを扱う方法についてのアイデアを持っていない
  • 🕵️‍♂️ フロントエンドの基礎に興味がある
  • 🤓 バニラ・タイプを愛するオタク
  • なぜ?もちろん、楽しみのために!バニラJSXのアイデアは、過度のエンジニアリングなしで本当のプロジェクトに適していません.ほとんどの場合、JSXサポートをスケーリングすると、新しいフロントエンドフレームワークの作成が引き起こされます.だから、オープンGitHub repo 新しいブラウザのタブで、自分で快適に.我々は前方にJSXに深いダイビングを持っている!

    何がそうですか?


    JSXはJSの上の統語的な拡張です.それはECMAScript規格ではありませんBabel and React JSXをプレーンJavaScriptにトランスポートする.クラシックJSXの例を見てみましょう.
    const profile = (
      <div>
        <img src="avatar.png" className="profile" />
        <h3>{[user.firstName, user.lastName].join(" ")}</h3>
      </div>
    );
    
    アフター@babel/plugin-transform-react-jsx 実行すると、コードはブラウザで理解できるようになります.
    const profile = React.createElement(
      "div",
      null,
      React.createElement("img", { src: "avatar.png", className: "profile" }),
      React.createElement("h3", null, [user.firstName, user.lastName].join(" "))
    );
    
    ご覧の通り、BabelはJSXをきちんと変換しましたReact.createElement 関数.これは、ラッパータグ、そのプロパティ(または、上記の場合の属性)を含みますnull ) と子要素は、順番に同じ関数で作成されます.
    反応、Vue、および固体フレームワークは、JSXを自分で扱うが、彼らは異なってそれを行う.これはcreateElement 関数.ちなみにJSXプラグマという.私はそれについて学んだとき、私はすぐに自分のプラグマを作成することを決めた.

    JSXパース


    pragmaの作成に飛び込む前に、JSXを解析する方法を学ぶ必要があります.古いブラウザのサポートなしで小さな現代のプロジェクトのために、我々はBabelを必要としません、しかし、VITEまたはtypescriptは十分です.両方を使います.

    Vite 最新のフロントエンドアプリケーションバンドルです.webpackと比較して、それはソースコードを提供しますnative ESM . プロジェクトをブートストラップするには、コマンドを実行するだけです.
    npm create vite@latest
    
    VITEとタイプスクリプトはデフォルトで、.jsx または.tsx ファイル.構文解析の結果をReact.createElement 関数.ただし、カスタム関数を置換する場合は、tsconfig.json .
    {
      "compilerOptions": {
        "jsx": "preserve",
        "jsxFactory": "h",
        "jsxFragmentFactory": "Fragment"
      }
    }
    
    あなたがtypescriptなしでアプリケーションを書いているならばvite.config.js .
    import { defineConfig } from 'vite';
    export default defineConfig({
      esbuild: {
        jsxFactory: 'h',
        jsxFragment: 'Fragment'
      }
    });
    
    これらの設定はパーサにh ( HyperScript ,ハイパーテキスト+ JavaScript )という意味で、JSXではroot要素とFragment 複数のルートJSX用.

    JSXプラグマ


    パーサを処理するh 機能を実装することができますsrc/pragma.ts .
    // Tag can be string or a function if we parse the functional component 
    type Tag = string | ((props: any, children: any[]) => JSX.Element);
    
    // Attributes of the element – object or null
    type Props = Record<string, string> | null;
    
    // Element children – return value from the h()
    type Children = (Node | string)[];
    
    export const h = (tag: Tag, props: Props, ...children: Children) => {
      // If tag is a component, call it
      if (typeof tag === 'function') {
        return tag({ ... props }, children);
      }
      // Create HTML-element with given attributes
      const el = document.createElement(tag);
      if (props) {
        Object.entries(props).forEach(([key, val]) => {
          if (key === 'className') {
            el.classList.add(...(val as string || '').trim().split(' '));
            return;
          }
          el.setAttribute(key, val);
        });
      }
    
      // Append child elements into the parent
      children.forEach((child) => {
        el.append(child);
      });
    
      return el;
    };
    
    まさにcreateElement , the h 関数は、h 子要素の上の関数.
    すべての.jsx ファイルはh 関数は、トランスポート後のコードスコープにあります.例えば、これは簡単なJSX使用です.
    import { h } from '../pragma';
    import { LikeComponent } from './like';
    export const App = (
      <main className="hello">
        <h1>
          Hello JSX!
        </h1>
        <LikeComponent big />
      </main>
    );
    
    今すぐにしなければならないのは、トランスポートされたコードをHTMLに追加することです.
    import { App } from './components/app';
    const app = document.querySelector<HTMLDivElement>('#app')!
    app.append(App);
    
    それだ!我々は、Webサイト上でそれを表示するための正しいDOMを作成するJSXを分析するtypescriptでアプリを作成してきました!

    実用


    私が初めに言ったように、この考えは本当のプロジェクトでの使用のために意味されません.それは文字通りJanxをランタイムライブラリを使用せずに解析するのが簡単であることを示します.
    JSXプラグマの概念はスケールが難しい.ロジックを機能的なコンポーネントに追加したい場合は、変数とイベントリスナーでケースを処理する必要がありますthe concept of reactivity .

    結論


    JSXプラグマのような標準的な概念は、バニラJSだけでフレームワークなしで簡単に扱うことができることがわかりました!畝
    私はあなたがあなたの手を得ることができるすべての技術を実験することを奨励し、それらにできるだけ深く行く.グッドラック!