動作原理:
Vite の原理を図で説明します。 ブラウザは何をするのですか?ホストファイル index.html<script type="module" src="/src/main.js"></script> ブラウザはホスト ファイル内のリソースを取得した後、main.js ファイルを再度要求する必要があることがわかります。 main.js のリソース要求がサーバーに再度送信されます。 メイン.jsmain では、ブラウザが 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 のアドレス 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 をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: MySQL データベース データのロード 複数の用途
>>: img タグの src 属性値が空の場合の 2 つのリクエストの問題 (IE 以外のブラウザ)
まず公式サイトにアクセスしてダウンロードし、MySQLダウンロードをクリックします。 ダウンロードし...
問題の説明(キープアライブとは何か)キープアライブ 名前の通り、アクティブな状態を維持します。誰が活...
通常の開発では、凸型の丸い角、つまり border-radius 属性を使用するのが一般的です。凹角...
序文この記事では主に、curl を介してフォーム送信ログインを実装する方法について説明します。単一の...
この記事では、主に同じ親タグの左側と右側にある 2 つのボタンの CSS レイアウト方法を紹介し、皆...
達成される効果は次のとおりです。 マウスがボタン内に移動すると、ネオンライトのような効果が生成され、...
サブスクリプションメッセージテンプレートを選択または作成するWeChat アプレットにログインし、「...
<br />「XXXのウェブサイトを見てみませんか?」といった質問をされることもあります...
Tomcat をサービスとして登録する場合の注意点は次のとおりです。 インターフェースを開いたら、以...
123WordPress.com-HTML noscriptオブジェクトolオプションPパラントプレ...
目次シナリオ: サーバーデータベースを毎日定期的にバックアップする必要がある1. まずバックアップス...
ページに複数の画像を導入すると、画像のサイズがばらつくことがあります。しかし、それらを一貫したサイズ...
ページの自動スクロール効果は JavaScript で実現できますが、今日偶然、JS 制御なしでさま...
Linux バージョンに関する情報を表示および解釈するのは、見た目よりも少し複雑です。単純なバージョ...
シナリオ会社のプロジェクトはDockerでデプロイされています。原因不明ですが、コンテナが時々停止し...