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

推薦する

Mybatis での動的 SQL ステートメント分析

この記事は主にMybatisでの動的SQL文の解析について紹介します。この記事のサンプルコードは非常...

Vue の img の src 画像アドレスの動的スプライシングの問題について

Vue での img の動的スプライシングを見てみましょう。src 画像アドレス、具体的な内容は次の...

1 行のコードでさまざまな IE 互換性の問題を解決します (IE6-IE10)

x-ua-compatible は、IE ブラウザがページを解析およびコンパイルするためのモデルを...

HTTPプロトコルにおけるステータスコードの意味

暫定的な応答を示し、要求者に操作の続行を要求するステータス コード。コードの説明100 (続行) リ...

中国における中国語ドメイン名の人気は新たなクライマックスを迎えた

<br />外交部などの中央政府機関、各レベルの地方政府、その他の国家機関や部門が率先し...

Dockerイメージのインポートとエクスポートの実装

GitLabのDocker使用法gitlab ドッカー起動コマンド docker run -d -p...

Nginx Webサーバーのサンプルコードの設定方法の詳細な説明

概要今日は主に、NGINX を Web サーバーとして設定する方法を共有します。内容は次のとおりです...

入力ファイルの制御と美化について

一部のWebサイトでアップロードする場合、「参照」ボタンをクリックすると、[ファイルの選択]ダイアロ...

JavaScript を使用せずに HTML の a タグを無効にするには、純粋な CSS を使用します。

実際、この問題は、HTML の select タグを初めて学んだときにすでに発生していました。今日に...

要素 UI に基づいてクエリ コンポーネントを段階的にカプセル化する方法

目次関数基本的なクエリ関数クエリ条件の初期化ページのレンダリングクエリと表示の最適化をさらに強化プル...

jsはポップアップウィンドウをクリックすることでポップアップログインボックスを実装します

この記事では、ポップアップウィンドウをクリックしたときにポップアップログインボックスを実現するための...

Docker Nginxコンテナの制作と展開の実装方法

クイックスタート1. Docker Hubでnginxイメージを見つけるdocker 検索 ngin...

Linux で FTP イメージ サーバーをインストールして展開する方法

Linux で FTP サーバーを設定するためのチュートリアルを参照してください https://w...

CentOS7 で yum を使用して PostgreSQL と PostGIS をインストールする方法

1. yumソースを更新するCentOS7 のデフォルトの yum リポジトリの PostgreSQ...

MySQL の自動インクリメント主キーが連続していないのはなぜですか?

目次1. はじめに2. 自己増分ストレージの説明3つの自己付加価値修正メカニズム4. 自己評価を修正...