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

推薦する

Windows 64 ビット版の MySQL 8.0.15 インストール チュートリアル

まず公式サイトにアクセスしてダウンロードし、MySQLダウンロードをクリックします。 ダウンロードし...

Vue でのキープアライブコンポーネントの使用例

問題の説明(キープアライブとは何か)キープアライブ 名前の通り、アクティブな状態を維持します。誰が活...

CSS で div 凹角スタイルを実装するサンプル コード

通常の開発では、凸型の丸い角、つまり border-radius 属性を使用するのが一般的です。凹角...

Linux curl フォームのログインまたは送信と Cookie の使用に関する詳細な説明

序文この記事では主に、curl を介してフォーム送信ログインを実装する方法について説明します。単一の...

CSS を使用して同じ親タグの左側と右側に 2 つのボタンを配置する方法

この記事では、主に同じ親タグの左側と右側にある 2 つのボタンの CSS レイアウト方法を紹介し、皆...

純粋なCSS3で実装されたネオンライト効果

達成される効果は次のとおりです。 マウスがボタン内に移動すると、ネオンライトのような効果が生成され、...

Nodejs での WeChat アプレット メッセージ プッシュの実装

サブスクリプションメッセージテンプレートを選択または作成するWeChat アプレットにログインし、「...

包括的なウェブサイト評価ソリューション

<br />「XXXのウェブサイトを見てみませんか?」といった質問をされることもあります...

Tomcat をサービスとして登録する際に注意すべき点のまとめ

Tomcat をサービスとして登録する場合の注意点は次のとおりです。 インターフェースを開いたら、以...

HTML 言語百科事典

123WordPress.com-HTML noscriptオブジェクトolオプションPパラントプレ...

Linux でのデータベースのスケジュールバックアップの実装スクリプト

目次シナリオ: サーバーデータベースを毎日定期的にバックアップする必要がある1. まずバックアップス...

CSSは親コンテナのdivをimg画像で埋め、コンテナのサイズに適応します。

ページに複数の画像を導入すると、画像のサイズがばらつくことがあります。しかし、それらを一貫したサイズ...

HTML タグ マーキーはさまざまなスクロール効果を実現します (JS 制御なし)

ページの自動スクロール効果は JavaScript で実現できますが、今日偶然、JS 制御なしでさま...

Linuxのバージョン情報を復号化する方法

Linux バージョンに関する情報を表示および解釈するのは、見た目よりも少し複雑です。単純なバージョ...

Dockerコンテナシェルスクリプトの実行ステータスを監視する方法

シナリオ会社のプロジェクトはDockerでデプロイされています。原因不明ですが、コンテナが時々停止し...