この記事では、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 以外のブラウザ)

推薦する

ウェブページのアクセス速度に関する主な問題と解決策

<br />ウェブサイトのアクセス速度はウェブサイトのトラフィックに直接影響を及ぼし、ウ...

Centos8 で Apache httpd2.4.37 を使用して Web サーバーをインストールする詳細な手順

ステップ 1: yum install httpd -y #httpd サービスをインストールします...

Ubuntu16.04にCUDA9.0をインストールするための詳細なチュートリアル

序文:この記事は、CUDA 9.0 をインストールした経験に基づいています。CUDA 9.0 は現在...

CSSでよく使われるフォントスタイルを設定することで様々なフォントの変更が可能(例詳細説明)

CSS フォント プロパティは、テキストのフォント ファミリ、サイズ、太字、スタイル (斜体など)...

Vue2とVue3の兄弟コンポーネント通信バスの違いと使い方

目次vue2.x vue3.x tiny-emitterプラグインの使用Mittプラグインの使用vu...

MySQL クエリの重複データ (重複データを削除し、ID が最も小さいデータのみを保持します)

開発の背景:最近、私はバッチ データを MySQL データベースにインポートする機能に取り組んでいま...

Linux に MySQL 8.0.x をインストールするための完全な手順

マイグレーションMySQL 入門MySQL はもともとオープンソースのリレーショナル データベース管...

Vue を使用して 2 つのデータ セットの違いを比較する視覚化コンポーネントの詳細な説明

目次必要:要点:これまでの要点に従って、コンポーネントのプロパティを確立できます。コンポーネントの基...

JavaScriptはスクロールバーの位置を取得し、ページをアンカーポイントまでスライドします。

序文この記事は、私が最近仕事で遭遇した問題を記録したものです。アプリネイティブとフロントエンドのh5...

HTML で #include ファイルを使用する例

a.htmとb.htmの2つのファイルがあります。同じディレクトリ内のa.htmの内容は次のとおりで...

Docker を使用して nginx で tomcat クラスターを構築する方法 (画像とテキスト付き)

まず、Tomcatフォルダを作成します。Dockerの設定を容易にするために、ルートディレクトリに直...

MySQLクエリ文の実行プロセスの詳細な説明

目次1. クライアントとサーバー間の通信方法2. クエリキャッシュ3. クエリ最適化処理4. クエリ...

Nginx でアンチホットリンクを設定するための手順を完了する

必要:通常、サイト側は、ウェブサイト上の動画や写真が盗まれるのを防ぎたいと考えています。結局のところ...

HTML マークアップ言語 - リファレンス

123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...

nginxコンテナ設定ファイルの独立した実装

コンテナを作成する [root@server1 ~]# docker run -it --name ...