この記事では、Viteがブラウザのリクエストに対して何を行うかを説明します。

この記事では、Viteがブラウザのリクエストに対して何を行うかを説明します。

動作原理:

  • type="module" ブラウザでの ES モジュールのネイティブ サポート。 ブラウザが type="module" をサポートしている場合は、es6 モジュール方式で記述できます。ブラウザは、インポートする必要があるファイルに対して別の HTTP リクエストを送信し、それをサーバーに送信します。 開発段階ではパッケージングは​​必要ありません
  • 事前にパッケージ化されたサードパーティの依存関係
  • リソース要求を処理する開発サーバーを起動する

Vite の原理を図で説明します。

ブラウザは何をするのですか?

ホストファイル index.html

<script type="module" src="/src/main.js"></script>

ブラウザはホスト ファイル内のリソースを取得した後、main.js ファイルを再度要求する必要があることがわかります。 main.js のリソース要求がサーバーに再度送信されます。

メイン.js

main では、ブラウザが vue.js?v=d253a66c と App.vue?t=1637479953836 の 2 つのファイルに対してリソース要求を再度開始していることがわかります。

サーバーはApp.vue内のコンテンツをコンパイルし、ブラウザに返します。下の図に示すように、ロゴ画像とテキストは_hoisted_の静的ノードにコンパイルされます。

リクエスト ヘッダーから、sfc ファイルがブラウザーで認識できる js ファイルになっていることもわかります (app.vue ファイルには、js にコンパイルされるスクリプト コンテンツが含まれている必要があります)。ブラウザの場合、実行されるのは js コードの一部です。

その他のベアモジュール

Vue 依存関係に他の依存関係がある場合、ブラウザは対応するリソースを取得するために再度リソース要求を開始します。

事前包装について学ぶ

サードパーティの依存関係 (ベア モジュール) を読み込むために、vite はそれらを事前にパッケージ化し、node_modules/.vite の下に配置します。プロジェクトを開始するときは、このパスからファイルを直接ダウンロードします。

上図から、ベアモジュールが導入されるとパスが変化することがわかります。

サーバーは何をしますか?

要約すると、サーバーは特殊なサフィックスを持つファイルを処理し、表示のためにフロントエンドに返します。

vite の devServe をシミュレートし、koa ミドルウェアを使用してローカル サービスを開始できます。

//依存関係を導入する const Koa = require('koa')
const アプリ = 新しい Koa()
定数 fs = require('fs')
定数パス = require('path')
const コンパイラ Sfc = require('@vue/compiler-sfc')
const コンパイラ Dom = require('@vue/compiler-dom')

app.use(async (ctx) => {
 const { url, クエリ } = ctx.request
 //リクエストリソースを処理するためのすべてのコードをここに記述します})
app.listen(3001, () => {
  console.log('dyVite スタート!!')
})

ホームページ index.html をリクエストする

 (url === '/')の場合{
    const p = path.join(__dirname, './index.html') // 絶対パス // ホームページ ctx.type = 'text/html'
    ctx.body = fs.readFileSync(p, 'utf8')
  }

上の画像を見ると、ホスト ファイルが正常に要求されたことがわかります。ブラウザが main.js ファイルに対する別のリクエストをサーバーに送信するだけです。このとき、main.js ファイルも判断して処理する必要があります。

.js で終わるファイルをリクエストする

上記の状況に対処した後、うーん。 。 。メインにはまだ多くのリソース要求があることがわかりました。

基本的なjsファイル

メインファイル:

コンソール.log(1)

処理メイン:

そうでない場合 (url.endsWith('.js')) {
   // js リクエストに応答する const p = path.join(__dirname, url)
   ctx.type = 'テキスト/javascript'
   ctx.body = rewriteImport(fs.readFileSync(p, 'utf8')) // 依存関数の処理}

メインの依存関係を処理する

メインには出力が 1 つしかないと思いますか?あまりにもナイーブだ。これは処理できますか?

メインファイル:

'vue' から {createApp, h} をインポートします。
createApp({ render: () => h('div', 'hello dyVite!') }).mount('#app')

うーん。 。 。それはできるはずです!

main にインポートされたアドレスを相対アドレスに変換できます。

ベアモジュールパスに /@modules/ を追加します。次に、/@modules/ 内のファイル (ベア モジュール ファイル) を識別します。

// 読み取り可能なファイル アドレスを相対アドレスに変換します // 通常の置換では、インポートを相対アドレスに書き換えます // import { createApp } from 'vue' => import { createApp } from '/@modules/vue'
関数 rewriteImport(コンテンツ) {
  戻り値 content.replace(/ from ['|"](.*)['|"]/g, function (s0, s1) {
    // s0 は文字列に一致し、s1 はコンテンツをグループ化します // 相対パスかどうか if (s1.startsWith('./') || s1.startsWith('/') || s1.startsWith('../')) {
      // 直接 return s0 に戻る
    } それ以外 {
      `from '/@modules/${s1}'` を返します
    }
  })
}

サードパーティの依存関係の場合、vite は事前にパッケージ化されたリクエストを使用して、独自の server/node_modules/.vite/ の下にある内部リソースを要求します。

これを少し簡略化して、依存関係名を使用してクライアント上の node_modules から対応するリソースを取得することもできます。

  そうでない場合 (url.startsWith('/@modules/')) {
    // ベアモジュールの読み込み const moduleName = url.replace('/@modules/', '')
    const pre![1637477009328](imgs/1637477009328.png)![1637477009368](imgs/1637477009368.png) のアドレス const module = require(prefix + '/package.json').module
    const filePath = path.join(prefix, module) // ロードするファイルのアドレスを取得します // 関連する依存関係を読み取ります const ret = fs.readFileSync(filePath, 'utf8')
    ctx.type = 'テキスト/javascript'
    ctx.body = rewriteImport(ret) //依存関係の中に依存関係がある可能性があるため、再帰が必要です}

メインでレンダリングすると、次のエラーが報告されます。

ロードするファイルはすべてサーバーで実行されるライブラリです。内部でノード環境用のコードが生成される場合もあるため、環境変数を判断する必要があります。開発中の場合は、いくつかの警告メッセージが出力されますが、フロントエンドでは警告メッセージは表示されません。したがって、これをモックして、ブラウザに現在の環境を伝える必要があります。

プロセス環境変数を HTML に追加します。

  <スクリプト>
   window.process = { env: { NODE_ENV: 'dev' } }
  </スクリプト>

この時点でメイン ファイルが読み込まれます。

しかし、これは私たちの目標達成には程遠いものです!

必要なのは、vue ファイルをコンパイルできるサーバーです。

.vue ファイルの処理

main.js ファイル:

'vue' から {createApp, h} をインポートします。
'./App.vue' からアプリをインポートします。
createApp(App).mount('#app')

vue ファイルでは、モジュール形式でロードされます。

vue ファイルを処理するときは、.vue の後に続くパラメータを処理する必要があります。

ここでは、簡略化して、テンプレートと sfc のケースのみを考慮します。

そうでない場合 (url.indexOf('.vue') > -1) {
    // vue ファイル App.vue?vue&type=style&index=0&lang.css を処理する
    // vue コンテンツを読み取る const p = path.join(__dirname, url.split('?')[0])
    // コンパイラSfcはsfcを解析してastを取得します
    const ret = コンパイラSfc.parse(fs.readFileSync(p, 'utf8'))
    // App.vue?type=テンプレート
    // リクエストにquery.typeがない場合、それはsfcであることを意味します
    if (!クエリ.type) {
      // 内部スクリプトを処理する
      定数scriptContent = ret.descriptor.script.content
      // デフォルトのエクスポート構成オブジェクトを定数に変換する const script = scriptContent.replace(
        'エクスポートデフォルト'、
        'const __script = ',
      )
      ctx.type = 'テキスト/javascript'
      ctx.body = `
  ${rewriteImport(スクリプト)}
  // テンプレート解析はリソースの別のリクエストに変換されます import {render as __render} from '${url}?type=template'
  __script.render = __render
  デフォルトの__scriptをエクスポートする
`
    } そうでない場合 (query.type === 'テンプレート') {
      const tpl = ret.descriptor.template.content
      // レンダリングモジュールを含めてコンパイル const render =compilerDom.compile(tpl, { mode: 'module' }).code
      ctx.type = 'テキスト/javascript'
      ctx.body = rewriteImport(レンダリング)
    }
  }

画像パスの処理

クライアントから直接読み取ります。

 そうでない場合 (url.endsWith('.png')) {
   ctx.body = fs.readFileSync('src' + url)
  }

要約する

Vite がブラウザ リクエストに対して何を行うかについては、これでこの記事は終了です。Vite ブラウザ リクエストの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Viteはプロジェクトを構築し、マイクロフロントエンドをサポートします
  • Vite+ElectronでVUE3デスクトップアプリケーションを素早く構築
  • 古い Vue プロジェクトに Vite サポートを追加する方法
  • Vite2.0の落とし穴
  • Vue3.0+vite2は動的非同期コンポーネントの遅延読み込みを実装します
  • プロジェクトを素早く構築するためのvite+vue3.0+ts+element-plusの実装
  • vite+vue3+element-plus プロジェクトをビルドする手順
  • Viteの原理を学ぶ

<<:  MySQL データベース データのロード 複数の用途

>>:  img タグの src 属性値が空の場合の 2 つのリクエストの問題 (IE 以外のブラウザ)

推薦する

CentOS での Docker の詳細なインストール チュートリアル

DockerにはCEとEEがあり、CE版はコミュニティ版(無料)、EE版はセキュリティを重視したエン...

よく使われる HTML 形式のタグ_Powernode Java Academy

1. タイトルHTML では、<h1></h1> から <h6>...

HTML、CSS、JSコメントの標準的な使用法の概要

必要なコメントを追加することは、責任感と道徳心のあるフロントエンド開発者が持つべき良い習慣であり、コ...

MySQL 外部キー制約の例の説明

MySQL の外部キー制約は、2 つのテーブル間のリンクを確立するために使用されます。 1 つのテー...

Vue 円形パーセンテージ プログレスバー コンポーネントの機能の実装

必要な方はどなたでも参考にしてください。試してみて問題が見つかった場合は、メッセージを残してお知らせ...

Vueでシングルサインオンを実装する方法のまとめ

最近プロジェクトが中断され、RageFrame の研究は一時的に終了しました。この記事では、シングル...

JavaScriptを使って動的にテーブルを生成するケースの詳しい説明

目次序文実装のアイデア実装コード成果を達成する序文これは、テーブルを動的に追加する例です。[追加] ...

JavaScriptオブジェクトをマージするさまざまな方法の詳細な説明

目次オブジェクトをマージするさまざまな方法(インターフェースを通じてデータを取得し、それをローカル ...

Vueはv-modelを使用してel-paginationコンポーネントのプロセス全体をカプセル化します。

v-model を使用してページング情報オブジェクトをバインドします。ページング情報オブジェクトに...

Vue3 の参照と参照の詳細

エディターは、Vue3のデータの関連する問題も共有します。次のような例を見てみましょう。 Vue.c...

2時間のDocker入門チュートリアル

目次1.0 はじめに2.0 Dockerのインストール3.0基本的なDockerコマンド4.0 Do...

LinuxシステムにTomcatをインストールし、サービスの起動とシャットダウンを構成する

Linuxシステムでサービスの起動とシャットダウンを構成する1. コマンドcd /etc/init....

Avue でカスタム検索バーを実装し、検索イベントをクリアする実践

目次1. 検索バーの内容をカスタマイズする2. 検索ボタンをカスタマイズする検索バーをカスタマイズし...

MySQLクエリが遅い理由

目次1. 遅いところはどこですか? 2. 不要なデータをクエリしましたか? 1. 不要なレコードをク...

MySQL グラフィカル管理ツール Navicat のインストール手順

目次序文1. 全員にインストールパッケージを用意する2. Navicatをインストールし、Navic...