動作原理:
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 以外のブラウザ)
<br />ウェブサイトのアクセス速度はウェブサイトのトラフィックに直接影響を及ぼし、ウ...
ステップ 1: yum install httpd -y #httpd サービスをインストールします...
序文:この記事は、CUDA 9.0 をインストールした経験に基づいています。CUDA 9.0 は現在...
CSS フォント プロパティは、テキストのフォント ファミリ、サイズ、太字、スタイル (斜体など)...
目次vue2.x vue3.x tiny-emitterプラグインの使用Mittプラグインの使用vu...
開発の背景:最近、私はバッチ データを MySQL データベースにインポートする機能に取り組んでいま...
マイグレーションMySQL 入門MySQL はもともとオープンソースのリレーショナル データベース管...
目次必要:要点:これまでの要点に従って、コンポーネントのプロパティを確立できます。コンポーネントの基...
序文この記事は、私が最近仕事で遭遇した問題を記録したものです。アプリネイティブとフロントエンドのh5...
a.htmとb.htmの2つのファイルがあります。同じディレクトリ内のa.htmの内容は次のとおりで...
まず、Tomcatフォルダを作成します。Dockerの設定を容易にするために、ルートディレクトリに直...
目次1. クライアントとサーバー間の通信方法2. クエリキャッシュ3. クエリ最適化処理4. クエリ...
必要:通常、サイト側は、ウェブサイト上の動画や写真が盗まれるのを防ぎたいと考えています。結局のところ...
123WORDPRESS.COM HTML チュートリアル セクションに戻るには、ここをクリックして...
コンテナを作成する [root@server1 ~]# docker run -it --name ...