は開発者の間でますます人気が高まっていますが、コミュニティは ( ほど) 大きくないため、問題を解決するには独自のカスタム プラグインを作成する必要がある場合があります。この記事では、 用のプラグインを作成する方法について説明し、私自身のプラグインについて詳しく説明します。 Vite Webpack Vite Vite でのプラグインの仕組み プラグインを作成するには、Vite が開発サーバー (コマンド ) とバンドル (コマンド ) に異なるビルド システムを使用することを理解しておくことが重要です。 vite vite build 開発サーバーの場合、最新のブラウザでサポートされているネイティブ ES モジュールを備えた を使用します。コードを 1 つのファイルにバンドルする必要がなく、高速な HRM (ホット モジュール交換) が可能です。 esbuild バンドルには、柔軟で大規模なエコシステムがあるため、 が使用されます。これにより、さまざまな出力形式で高度に最適化された本番バンドルを作成できます。 rollup.js Vite のプラグイン インターフェイスは Rollup に基づいていますが、開発サーバーと連携するための追加のオプションとフックが付いています。 基本的なプラグインの作成 プラグインを作成するときは、それを にインライン化できます。新しいパッケージを作成する必要はありません。プラグインがプロジェクトで役立つことがわかったら、それをコミュニティと共有し、Vite エコシステムに貢献することを検討してください。 vite.config.js また、rollup.js にはより大きなコミュニティとエコシステムがあるため、rollup.js 用のプラグインを作成することを検討すると、Vite でも同様に機能します。したがって、プラグイン機能がバンドルに対してのみ機能する場合は、Vite の代わりに rollup.js プラグインを使用でき、ユーザーは Vite プロジェクトでロールアップ プラグインを問題なく使用できます。 rollup 用のプラグインを作成すると、rollup.js のみを使用するより多くのユーザーをカバーできます。プラグインが開発サーバーに影響を与える場合は、Vite プラグインを使用します。 で直接プラグインの作成を開始しましょう。 vite.config.ts // vite.config.ts import { defineConfig, Plugin } from 'vite'; function myPlugin(): Plugin { return { name: 'my-plugin', configResolved(config) { console.log(config); }, }; } export default defineConfig({ plugins: [ myPlugin(), ], }); この例では、開発サーバーとバンドルの両方の段階でコンソールで Vite 設定が解決されるとすぐに Vite 設定を出力する というプラグインを作成しました。 dev サーバー モードでのみ構成を出力したい場合は、バンドルに と を追加する必要があります。 myPlugin apply: 'serve' apply: 'build' // vite.config.ts import { defineConfig, Plugin } from 'vite'; function myPlugin(): Plugin { return { name: 'my-plugin', apply: 'serve', configResolved(config) { console.log(config); }, }; } export default defineConfig({ plugins: [ myPlugin(), ], }); また、プラグインの配列を返すこともできます。これは、開発サーバーとバンドルの機能を分離するのに役立ちます。 // vite.config.ts import { defineConfig, Plugin } from 'vite'; function myPlugin(): Plugin[] { return [ { name: 'my-plugin:serve', apply: 'serve', configResolved(config) { console.log('dev server:', config); }, }, { name: 'my-plugin:build', apply: 'build', configResolved(config) { console.log('bundle:', config); }, }, ]; } export default defineConfig({ plugins: [ myPlugin(), ], }); ほぼそれだけです。 Vite 設定に小さなプラグインを簡単に追加できます。プラグインが大きくなりすぎる場合は、別のファイルに移動するか、パッケージを作成することを好みます。 もっと複雑なものが必要な場合は、Vite のドキュメントで調べることができる便利なフックがたくさんあります。ただし、例として、以下に私自身のプラグインを分解してみましょう。 実際のプラグインを分解する そこで、アイコン ファイルに基づいて SVG スプライトを作成するプラグイン を用意しました。 vite-plugin-svg-spritemap 目標は、 フォルダー内のすべてのアイコン 取得し、その内容を SVG スプライトと呼ばれる単一の ファイルに収集することです。バンドル段階から始めましょう。 src/icons .svg .svg import { Plugin, ResolvedConfig } from 'vite'; import path from 'path'; import fs from 'fs-extra'; function myPlugin(): Plugin { let config: ResolvedConfig; return { name: 'my-plugin:build', apply: 'build', async configResolved(_config) { config = _config; }, writeBundle() { const sprite = getSpriteContent({ pattern: 'src/icons/*.svg' }); const filePath = path.resolve(config.root, config.build.outDir, 'sprite.svg'); fs.ensureFileSync(filePath); fs.writeFileSync(filePath, sprite); }, }; } フック 使用すると、次のフックで使用することが解決されたときに構成を取得できます。 configResolved バンドル プロセスの完了後に フックが呼び出されます。ここで、 ファイルを作成します。 writeBundle sprite.svg 関数は、 パターンに基づいて、準備された SVG スプライトの文字列を返します。これについてはこれ以上深くは説明しません。 をチェックしてください。 getSpriteContent src/icons/*.svg SVG スプライト生成のプロセス全体を説明した私の他の記事 次に、 で SVG スプライト コンテンツを配置する への絶対パスを作成し、 でファイルが存在することを確認 (または作成) し、そこに SVG スプライト コンテンツを書き込みます。 。 path.resolve() sprite.svg fs.ensureFileSync ここで、最も興味深い部分である開発サーバーの段階について説明します。ここでは 使用できず、開発サーバーの実行中はファイルをホストできないため、サーバーミドルウェアを使用して へのリクエストをキャッチする必要があります。 writeBundle sprite.svg import { Plugin, ResolvedConfig } from 'vite'; function myPlugin(): Plugin { let config: ResolvedConfig; return { name: `my-plugin:serve`, apply: 'serve', async configResolved(_config) { config = _config; }, configureServer(server) { // (1) return () => { server.middlewares.use(async (req, res, next) => { // (2) if (req.url !== '/sprite.svg') { return next(); // (3) } const sprite = getSpriteContent({ pattern, prefix, svgo, currentColor }); res.writeHead(200, { // (4) 'Content-Type': 'image/svg+xml, charset=utf-8', 'Cache-Control': 'no-cache', }); res.end(sprite); }); }; }, }; } は開発サーバーを構成するためのフックです。 Vite の内部ミドルウェアがインストールされる前にトリガーされます。私の場合、内部ミドルウェアの後にカスタムミドルウェアを追加する必要があるため、関数を返します。 configureServer 開発サーバーへのすべてのリクエストをキャッチするカスタム ミドルウェアを追加するには、 を使用します。ファイルの動作をエミュレートできるように、URL リクエストを検出するために必要です。 server.middlewares.use() [localhost:3000/sprite.svg](http://localhost:3000/sprite.svg) リクエスト URL が ではない場合 - 次のミドルウェアにスキップします (つまり、チェーン内の次のハンドラーに制御を渡します)。 /sprite.svg ファイルのコンテンツを準備するには、 の結果を変数 に入れ、設定されたヘッダー (コンテンツ タイプと 200 HTTP ステータス) を含む応答として送信します。 getSpriteContent sprite その結果、ファイルの動作をシミュレートしました。 ただし、 内のファイルが変更、削除、または追加された場合は、サーバーを再起動して、 を介して新しいスプライト コンテンツを生成する必要があります。このために、ファイル監視ライブラリ - を使用します。 chokidar ハンドラーをコードに追加しましょう。 src/icons getSpriteContent chokidar import { Plugin, ResolvedConfig } from 'vite'; import chokidar from 'chokidar'; function myPlugin(): Plugin { let config: ResolvedConfig; let watcher: chokidar.FSWatcher; // Defined variable for chokidar instance. return { name: `my-plugin:serve`, apply: 'serve', async configResolved(_config) { config = _config; }, configureServer(server) { function reloadPage() { // Function that sends a signal to reload the server. server.ws.send({ type: 'full-reload', path: '*' }); } watcher = chokidar .watch('src/icons/*.svg', { // Watch src/icons/*.svg cwd: config.root, // Define project root path ignoreInitial: true, // Don't trigger chokidar on instantiation. }) .on('add', reloadPage) // Add listeners to add, modify, delete. .on('change', reloadPage) .on('unlink', reloadPage); return () => { server.middlewares.use(async (req, res, next) => { if (req.url !== '/sprite.svg') { return next(); } const sprite = getSpriteContent({ pattern, prefix, svgo, currentColor }); res.writeHead(200, { 'Content-Type': 'image/svg+xml, charset=utf-8', 'Cache-Control': 'no-cache', }); res.end(sprite); }); }; }, }; } ご覧のとおり、プラグイン作成の API はそれほど複雑ではありません。 Vite または Rollup から自分のタスクに合ったフックを見つけるだけです。この例では、Rollup.js の (前述したように、バンドルの生成に使用されます) を使用し、Rollup.js にはネイティブの開発サーバー サポートがないため、Vite の 使用しています。 writeBundle configureServer の場合は非常に単純で、SVG スプライトのコンテンツを取得してファイルに入れました。開発サーバーの場合、なぜ同じことができないのか混乱しました。他の作者のプラグインも調べてみましたが、どれもほぼ同じことを行います。 writeBundle そこで、 を使用し、 引数を介して、 リクエストをインターセプトすることで開発サーバーへのすべてのリクエストをトリガーするミドルウェアを追加します。 configureServer server sprite.svg Vite フックの使用 前に述べたように、より便利なプラグインを作成するには、フックを調べる必要があります。それらについてはドキュメントで詳しく説明されています。 https://vitejs.dev/guide/api-plugin#universal-hooks https://vitejs.dev/guide/api-plugin#vite-specific-hooks プラグインに名前を付ける方法 命名に関しては、Vite にはプラグインに関するいくつかの規則があるため、終了する前に確認しておくことをお勧めします。いくつかの重要なポイントを次に示します。 Vite プラグインには、 プレフィックスが付いた一意の名前が必要です。 vite-plugin- キーワードを package.json に含めます。 vite-plugin プラグインのドキュメントに、Vite 専用プラグインである理由を説明するセクションを含めます (Vite 固有のプラグイン フックを使用するなど)。 プラグインが特定のフレームワークでのみ動作する場合は、その名前をプレフィックスの一部として含めます ( 、 、 )。 vite-plugin-vue- vite-plugin-react- vite-plugin-svelte- プラグインを公開して共有する方法 プラグインを NPM で公開することに決めた場合は、知識と専門知識を共有することが IT コミュニティの基本原則であり、集団的な成長を促進するため、これをお勧めします。パッケージを公開および保守する方法については、私のガイドを参照してください → 。 NPM パッケージを作成する最も簡単な方法 また、プラグインを vite のコミュニティ リスト ( に送信することを強くお勧めします。そこでは多くの人が最適なプラグインを探しており、Vite エコシステムに貢献する絶好の機会となるでしょう。プラグインを送信するプロセスは簡単です。条件を満たしていることを確認してプル リクエストを作成するだけです。用語のリストは ご覧いただけます。 awesome-vite) ここで 全体として、(ロールアップではなく) Vite に特化し、オープンソースであり、適切なドキュメントが必要です。プラグインを頑張ってください!