IE11が去った後に使える機能一覧を確認するサイトを作った

IE11の考慮が不要となった場合に、特定のブラウザバージョン以降で使えるようになる機能一覧を列挙して表示するサイトを作った。

the-world-after-ie-left.vercel.app

リポジトリはこちら github.com

デフォルトでは

以降で使える機能を確認できる。

※ ちなみに雑にVercelにデプロイしてるので、レスポンスが巨大すぎるとVercel自体の制限に引っかかって死ぬことがあるので、落ちる場合は絞り込み用のブラウザバージョンをちゃんと入れてください。

IE卒業式という社内イベント

先日、IE卒業式というイベントが開催された。これ自体は公のイベントで、とてもいい内容だった。

それとはまた別で、社内でも似たようなIEサポート終了に伴うちょっとしたイベントが開催され、その中でLTをすることになった。お題としては「IE11を考慮から外すと◯◯ができるよ!」といったものをリクエストされた。

最初は単純に MDN のドキュメントからいくつかの機能を感覚でピックアップして終わろうかなと思っていたが、実際調べていくと、山のように機能があることに気付いた。

「これはそもそも機能を洗い出すこと自体に何らかの仕組みが必要では??」という考えに至り、LT用にサイトを作ってみることにした。5分の発表のために私は一体何を。

仕組み

至ってシンプルで、MDNのドキュメントのベースにもなっている mdn/browser-compat-data のデータをもとにフィルタリングして表示しているだけです。

github.com

ちなみに最初はリポジトリ内に含まれるデータのJSONファイルを全てパースして、JavaScriptで取り扱いやすいデータオブジェクトを作って、かつ型定義も自分で書いて頑張ってたが、実は mdn/browser-compat-data はそもそも npm パッケージとして公開されており、データも型も全部公開してくれていることに後で気付いて「ウワー!!!」ってなった。ちゃんとリポジトリの中を確認しましょうね、という学びを得た。

(ちなみに、意外と自分で書いた型定義は概ね正しかったようで、パッケージ提供のものに差し替えたあともすんなり型チェックがパスしてビックリした)

作ってみて

単純に機能を眺めているだけでも結構おもしろかった。

普通に知らない機能もあったし、Transpile/Polyfillを当然のように使ってたので、たとえば Array.prototype.findIndex とかは「そうか、IEってコレも使えなかったのか...」みたいな気持ちになった。

公開したままにしとくので、興味があれば見てみてください。

おわり

リモートワークスタイルチェック用サービスをつくった #リモートワークスタイルチェック

リモートワークスタイルチェック

リモートワークスタイルに関する質問に答えることで、リモートワーク比重・文化がどういった具合かを確認・共有できるサービスを作った。

remote-work-style-check.mugi.dev

こんな感じ↓の質問にぽちぽち答えるだけで良いので、すぐ終わる。簡単。

全部答えると↓のような全てをまとめたいい感じの1枚画像を表示してくれる。

もし忙しくなければチェックをやった上で、結果ページから結果をツイートして拡散してもらえるととても嬉しい。

チェック結果の画像も誰でも自由に使ってOK。

サービス内での項目は以前公開した "リモートワークスタイルチェック" の内容に沿っている。

🔗 リモートワークスタイルチェック · GitHub
🔗 "リモートワーク"の認識ズレ解消のためにリモートワークスタイルチェックを作ってみた - memo_md

チェックに答えた結果を表示するだけではあるので、サービスというと少し大げさかもしれない。

作ったモチベーション

リモートワークスタイルチェック自体は、"リモートワーク" という言葉に関しての認識の齟齬を減らしたいという気持ちがあって作った。

本当にありがたいことに、実際に一部の企業さまがこれを利用してチェック結果をブログなどで公開していただいた。嬉しい。

永和システムマネジメントさん
blog.agile.esm.co.jp

Arentさん
note.com

チェックを通じて、個人・企業の双方で「リモートワークも色々あるんだな」という気づきを一人でも多くの人に与えたいというのが根底にあるので、似たような形でより多くの人にチェック結果をアウトプットして欲しいな〜と思っている。

しかし、実際チェック項目は12個ほどあり、ちゃんと内容を読み込むと結構めんどくさいし、それをさらにアウトプットしろと言われるともっと手間ですよね、というのはわかる。

そこで、カジュアルに誰でも簡単にチェックしつつ、かつ結果を共有できる仕組みが必要だな〜と思い、このサイトを作った。

みんなのリモートワークをより良いものにするためにぜひ使ってみて。

技術的な話

特徴的なところでは次のようなものを使ってる

チェック自体はさほど難しくないReactアプリをRemix上に構築している。Remixを使わないといけない理由は皆無であり、使いたかっただけである。

OGP画像生成

結果ページやSNS共有のために利用するOGP画像については、チェック結果内容に応じて動的に生成している。

これは、画像を見た目となる要素をHTMLで構築し、それをPlaywrightから参照したうえで、要素のスクリーンショットを撮影することで生成している。Remixの一部ルーティングを画像用に用意しており、そこにアクセスするとPlaywrightが起動して結果を返すようになっている。PlaywrightではローカルのHTMLも開けるので、その際にクエリパラメータを付与し、それをスクリプトから参照することで値を切り替える。

ただ、さほど要素の多くない画像用のHTMLとはいえ、さすがにDOM構築を手でやるのは面倒。専用にビルド環境を構築しても良かったが、せっかくなので触ったことのない petite-vue で作ってみた。 petite-vue は Vue.js の超軽量サブセットで、ビルドなどを必要とせずにすぐにVue.jsの基本的な機能を導入できるものと思ってもらえればよい。

感想としては、まさにこういう用途のためのものだなという感じだった。雑に突っ込めば即Vue.jsが動くので手っ取り早い。余計なファイルも増えない。ただできることもかなり限定的なので、少しでも複雑なことをするとあっという間に破綻しそうなので、使い所は慎重に。

デザイン的なところ

TailwindCSSで気合いで構築した。

猫の画像については、DOTOWN の画像を利用させていただいた。

dotown.maeda-design-room.net

素敵なかわいいドット絵がクレジットなしで利用させていただける。神である。


そういうわけで、どの程度流行るかはわからないけど、もし暇なら試してみて貰えると嬉しい。

"リモートワーク"の認識ズレ解消のためにリモートワークスタイルチェックを作ってみた

ふと思い立って "リモートワークスタイルチェック" というものを作ってみた。

→ 🔗 リモートワークスタイルチェック · GitHub

"リモートワーク" という言葉の認識の齟齬

最近、Meetyを使ってカジュアル面談をちょいちょいやっていて、いろんな方とたくさん話をさせてもらった。その中で、自分が地方に住んでるのもあってか、リモートワークが話題に上がることが多かったのだが、人によって "リモートワーク" の認識が大きく異なっている印象を受けた。

meety.net

「雑談が減っちゃう」という意見もあれば、「静かで集中できる」という方もいた。「通勤が無くて楽」という方もいたし「たまにはオフィス行きたい」という話も聞いた。

同じような環境だとしても、人によって捉え方は大きく違ってた。

また、これは個人だけの話だけではなく、企業でも同じことが言えると思う。1年ほど前に転職活動をしたときに、さまざまな会社と話す機会があり、似たようなギャップを感じることがあった。

これは一例だが、とある「フルリモート可能です」という会社との面談の中で色々と掘り下げて聞いていった結果、実際には「いまはコロナ禍もありフルリモート可能だが、将来的に制度が変更されて出社必須になる可能性はある」ということが後から解った、といったことがあった。途中で制度が変わることはあまり想定していなかったので、認識に大きな齟齬があったことになる。

誤解を招かないように補足しておくと、"後から言いやがって〜" などとその会社のことをどうこう言うつもりはない。その会社にとっては "リモートワーク" はオプショナルな働き方のひとつでしかなかったが、自分にとっては "リモートワーク" は人生に関わる部分なのでかなり重要な要素だった、というだけなので、どちらが正しい・間違っているという話ではない。

ともあれ、これらを踏まえ、あまりにも "リモートワーク" という言葉に情報を含めすぎているなぁという印象を受けた。

リモートワークにはさまざまなスタイルがあり、企業・チームによってスタンスが大きく異なる。リモートワークに全振りしてる会社もあれば、社会情勢を鑑みて限定的に許可しているケースもある。

個人側の "リモートワーク" に求めるものも多種多様で、自分のように地方在住なので基本的にフルリモートで1年中働きたい人もいれば、普段は出社で良いが家庭事情による突発的な在宅勤務を許可してくれればOK、という人もいるはず。

ただ、これらの結果で一番怖いのが、"認識の齟齬があるまま入社してしまった" という可能性が潜んでいる点だと思う。お互いに気づかずに採用が確定してしまうと、

  • 「リモートで静かに仕事できると思ってたのに、毎日オンラインMTGだらけじゃん!」
  • 「定期的に出社必須とか聞いてないんだけど〜」
  • 「入社して1年したらリモートワークがなくなったんだけど...」

といったおぞましい結果が待ってる恐れがある。

リモートワークスタイルの確認観点がほしい

リスクを減らすためにどうしたらいいか?と考えた時に、リモートワークについて確認すべき観点がどこかに列挙されており一般化されている必要があるな〜という結論に至った。

作ってみたチェック観点

実際に用意してみたチェック観点は次の通り。

※なお内容については、自分と同じように地方から長くリモートワークを経験している Toyama.rb の @kunitoo にも意見をいただいた。感謝

比重度と文化

まず大きく "比重度""文化" の2つに大きく分けている。

比重度は、どの程度リモートワークに重きを置いて業務を回しているかを判断する。

比重が大きいほどにリモートワークを前提とする社内制度が充実したり、何か課題があった場合も全員の課題となり解決しやすくなる。代わりに、常にリモートワーク独自の問題と向き合い続ける必要も強まったり、"オフラインのほうが手っ取り早いよね" という解決策を取りにくくなる。

スタイルチェック内にも書いたが、あくまでも「比重」を見るものであり、優劣ではない。より積極的にリモートワークを導入してるから良い、そうでないから悪い、という話ではない。 企業の属性や何を重要視するかなど、価値観はそれぞれである。リモートワーク全振りになることでむしろ働きづらく感じる人もいると思う。

一方で文化のほうは、リモートワークをどのようなポリシーで導入しているかを見る。

主にコミュニケーションに関わる項目が多く、オンライン上での会話量や、時間を合わせた同期的な仕事をどの程度必要とするかなどが対象。

「ある程度は直接人と話さないとつらいです」という人はビデオ会話が多い方が良いはずだし、「静かにもくもくと自分のペースで仕事したい」という人は真逆になると思う。

比重度の項目

リモートワークの導入期間

どの程度リモートワークを導入しているか。

シンプルに、期間が長い方が組織としてリモートワークへのノウハウが蓄積されているはず。また、長期的な実施ならでは課題にも向き合う必要が出ていると思われる。

スポット的な導入というケースもありうるため、期間が継続 or 累積によって判断を分けている。継続的に導入している方が比重が高いと判断している。

リモートワークの導入ポリシー

リモートワークを一時的なものとして導入しているか、恒久的に取り扱うか。 また、内容の変更がどの程度ありうるか。

「もう会社の制度としてがっつり組み込まれているので廃止とかは絶対ないです!」という導入なのか、「社会情勢を鑑みて一時的に使えるようになってます」という導入なのかを見る。

リモートワークのマジョリティ度合い

全メンバーのうちどの程度がリモートワークに関わっているか。 リモートワークの課題が全員のものとなるか、「リモートワークのひと」の課題となるかの違いがある。

リモートワークを全員で実施してるか、一部のメンバーだけが実施しているかで大きく扱いに違いが出てくる。「会議室のマイクの音質が絶望的に悪い...」みたいなケースも、リモートワークをするメンバーが多数派であれば全員の課題になりやすい。

申請・許可の必要性

リモートワークを行うために何らかの手続きが発生するかどうか。 また、申請が必要な場合にはどの程度の頻度で申請を行う必要があるか。

高頻度で申請が必要なほどにリモートワークがオプショナルな選択肢である割合が強くなり、リモートワークを実施するために何らかのコストが発生することになる。また、申請が必要=却下の可能性も出てくる。

リモートワークの適用範囲

リモートワークが利用可能なのは誰か。

利用のために何らかの条件が設けられているかどうか。

誰でも自由に利用できるケースと、出社可能なメンバーは出社必須なケースでは大きな隔たりがある。 また、社員は利用できるが業務委託の人はダメです、みたいなケースでも、実際に仕事をする上では不都合が出てくる可能性がある。

出社義務

業務上必須とされる出社がどの程度発生するか。 「義務」としての出社のみ数える。出社が伴うイベントだとしても個々の判断で出社せずにオンライン参加が可能なケースなどは含めない。

出社の頻度。頻度が高ければ高いほど居住地などにも制約が出てくる。 また、突発的な出社が発生する可能性がある場合、それは出社待機状態と変わらないため、考慮が必要。(@imunolionさんにご意見頂きました、ありがとうございます!)

リモートワークで必要なサービス・アプリケーションの取り扱い

リモートワーク・非リモートワークで利用するサービス・アプリケーションに差異があるか。

リモートワーク向けにサービス・アプリケーションを最適化しているかどうか。 クラウド移行などが全く実施されていない場合には、日常業務で支障が出る可能性もある。また、将来的に移行する見込みがあるかどうかも大事。

情報のアクセス範囲

リモートワーク時と非リモートワーク時に、アクセス可能な情報量にどの程度差があるか。 また、差がある場合にはそれをカバーする手段が用意されているかどうか。

リモートワーク時に手に入らない情報がどの程度あるか。 すべて同条件で手に入るか、リモートワーク向けに専用で議事録を用意してあげる必要があるか、まったくアクセスできないか、など。「オフィスでしかアクセスできない...」みたいなケースが多いほど出社頻度や、非リモート側の共有コストが生じる。

その他

その他リモートワークに関する制度や特徴的な情報など

段階的なものではなく、YES/NOで判断できるようなリモートワークに関する特記事項。

役員が自ら実施しているかや、手当があるかどうか、など。

文化の項目

同期・非同期コミュニーションの割合

コミュニケーションが伴う業務において、同期・非同期のコミュニケーションはどういった割合か。

同期的(=複数人が同じ時間でのやり取り)と、非同期的(=複数人でタイムラグを許容するやり取り)なコミュニケーションの割合。

同期的な割合が高いほど、働く時間が束縛されることが多くなるが、リアルタイムな反応を得られることになるため、スムーズに進めやすいように感じるかもしれない。 逆に非同期的な割合が高いと、自分のペースで仕事を進めやすくなりやすい。ただし、相手からのレスポンスも遅れることを許容する必要があり、タイムゾーンレベルで違いがある場合には、大きい工夫が必要となる。

テキストコミュニケーションの割合

リモートワークでのコミュニケーション方法において、テキストが占める割合はどの程度か

Slack・Teamsなどのチャットツールやメールのようなテキストベースでのコミュニケーションと、Zoom・Google Meets のようなビデオ・音声会話ツールでのコミュニケーションの割合。

テキストが主体であれば、必然的に文章に会話が残るため後から記録が追いやすくなるが、会話よりも情報量が減りやすく、工夫を伴ったコミュニケーションも重要になる。ビデオ・音声の場合は、テキストにはない表情や雰囲気といった情報を得やすく、心理的な面でのフォローもしやすいが、議事に残らず失われていく情報も多くなる。

コミュニケーション頻度

リモートワーク時に、どの程度他のメンバーとコミュニケーションを取るか (テキスト・ビデオなどの手段は問いません)

コミュニケーションの活発具合。

リモートワークはオフィスワークに比べて雑談が減りがちといった課題がある。それをストレスに感じてしまう場合、コミュニケーション頻度は重要になる。

逆に、余計な雑談などを省いて仕事をしたいと感じている場合には、成果物のみでのやり取りなど最低限のコミュニケーションスタイルのほうがマッチするかもしれない。

働く時間

リモートワークで働くにあたって、どういった時間帯に仕事をするか。 これによって同期・非同期の割合が決まったり、非同期の場合もレスポンス速度が変わってくる。

働く時間がどの程度マッチするのか。

働く時間が特に定められていない場合は自由度が増すが、同期的なコミュニケーションを必要とする場合には、事前調整が必要になるといったコストが発生する。 一方でコアタイムや定時などが定まっている場合には、ある程度で束縛されることになるが、同期的なやりとりは捗りやすい。(生活リズムが整いやすい、みたいなメリットもありそう)


というわけで、リモートワークスタイルチェックを作ってみたという話でした。

リモートワークが世の中に広く普及してきたものの、こういった差分を明確に文章化されたものが見当たらなかったため、悲劇が起きる前に書いておいた方がいいかなぁと思って頑張って作ってみた。

これで完璧な内容だとは思っていないので、TwitterでもGistコメントでもいいので、意見をもらえたら反映するかもしれません。

リモートワーク、むずかしいね!

おわり

Viteのコードを読む - createServer(ViteDevServer生成まで)

前回: Viteのコードを読む - CLI経由でのコア実行の流れ - memo_md

viteパッケージ内部 / サーバー起動部分をよむ

vite dev vite serve などで起動する packages/vite/src/node/server をよむ

ファイル一覧

.
├── __tests__
├── hmr.ts
├── index.ts
├── middlewares
│   ├── base.ts
│   ├── error.ts
│   ├── indexHtml.ts
│   ├── proxy.ts
│   ├── spaFallback.ts
│   ├── static.ts
│   ├── time.ts
│   └── transform.ts
├── moduleGraph.ts
├── openBrowser.ts
├── pluginContainer.ts
├── searchRoot.ts
├── send.ts
├── sourcemap.ts
├── transformRequest.ts
└── ws.ts

CLI からの起動は ↓

const { createServer } = await import('./server')
try {
  const server = await createServer({
    root,
    base: options.base,
    mode: options.mode,
    configFile: options.config,
    logLevel: options.logLevel,
    clearScreen: options.clearScreen,
    server: cleanOptions(options)
  })

  ...

vite/packages/vite/src/node/server/index.ts # createServer が該当

createServer

コンフィグの読み込みとサーバー生成

const config = await resolveConfig(inlineConfig, 'serve', 'development')
  • inlineConfig は CLI の実行時引数などから生成したオブジェクト
  • resolveConfigResolvedConfig 型の値を返す
    • inlineConfig の configFilefalse でなければ loadConfigFromFile で読む (明示的に "使いません!!" としない限りロードする)
    • 次の順番でロードを試みる
      1. configFile でファイル指定がある場合はそれをロード
      2. vite.config.js
      3. vite.config.mjs
      4. vite.config.ts
      5. vite.config.cjs
    • ESM の場合 (package.json の type が module、または設定ファイルが .mjs.ts )は bundleConfigFile
      • esbuildでビルド
      • Pluginとして externalize-depsreplace-import-meta を適用している
      • そういうプラグインパッケージがあるわけじゃなく、ただ名前つけてるだけぽい
        • externalize-deps → 外部パッケージをマーク
        • replace-import-metaimport.meta.url, __dirname, __filename を実体に置き換え
  const httpsOptions = await resolveHttpsConfig(
    config.server.https,
    config.cacheDir
  )
  • vite/packages/vite/src/node/http.ts # resolveHttpsConfig
  • https接続用の ca,cert,key,pfx ファイルをロード
const middlewares = connect() as Connect.Server
const httpServer = middlewareMode
  ? null
  : await resolveHttpServer(serverConfig, middlewares, httpsOptions)
const ws = createWebSocketServer(httpServer, config, httpsOptions)
  • connect でサーバのMiddlewareを作成
  • server設定で middlewareMode が設定されていなければ resolveHttpServer
    • https://ja.vitejs.dev/config/#server-middlewaremode
      • index.html の配布を誰が責務を持つかの話
      • ドキュメント上では ssr or html が設定に渡せるようだが、実際は true false もいける
    • https/proxyの設定に応じて、 http or https or http2 モジュールで createServer (connectで作られたMiddlewareを渡す)
  • createWebSocketServer : HMR用のWebSocketサーバーの準備。基本的に↑で使っているサーバーをそのまま使う
    • Midlewareモードだったりserver.htr.server の設定などによってはサーバーを作る
    • 先に作ったサーバーを利用する場合は、upgrade 要求で WebSocket コネクションを確立する

createPluginContainer

  const container = await createPluginContainer(config, moduleGraph, watcher)
// we should create a new context for each async hook pipeline so that the
// active plugin in that pipeline can be tracked in a concurrency-safe manner.
// using a class to make creating new contexts more efficient
class Context implements PluginContext {
  ...
}

次のようなものを持つ(特徴的ぽい一部だけ抜粋)

  • parse : acornでコードをparse
  • resolve : ID(ファイルのURLやパス)を解決
  • addWatchFile : chokiderの監視対象にファイルを乗せる

都度生成しているケースもあるし、TransformContext のように継承しているケースもある。

最終的に返される PluginContainer は次のメソッドを持つ

  • buildStart : すべてのプラグインを対象に buildStart を呼ぶ
  • resolveId : ID(ファイルのURLやパス)を解決
  • load : すべてのプラグインを対象に id を引数に load を呼ぶ
  • transform : すべてのプラグインを対象に id を引数に transform を呼ぶ
  • close : すべてのプラグインを対象に buildEndcloseBundle を呼ぶ

サーバー停止用ハンドラの生成

const closeHttpServer = createServerCloseFn(httpServer)

ViteDevServer の生成

ここまで作ってきた全てを一通り保持する ViteDevServer オブジェクトを作る 詳細は次回以降。


感想

  • createServer だけでもやってることめっちゃ多かった
  • vite.config 書くときに「tsでも書けて便利〜〜」とか思ってたけど、裏で普通にesbuildしててそりゃそうだよなってなった
  • RollUp用の PluginContainer で複雑なことをやってんだなってのはわかった

次回

createServer 読み終わってないので、続きをよむ

Viteのコードを読む - CLI経由でのコア実行の流れ

前回: Viteのコードを読む - リポジトリ直下のファイル群 - memo_md

コアのファイルをよむ

  • packages/vite を見ていく
  • とりあえずディレクトリ構造を眺めてみる

ディレクトリ構造

.
├── bin
├── dist
│   ├── client
│   └── node
│       └── chunks
├── scripts
├── src
│   ├── client
│   └── node
│       ├── __tests__
│       │   ├── packages
│       │   │   ├── name
│       │   │   └── noname
│       │   └── plugins
│       ├── optimizer
│       ├── plugins
│       ├── server
│       │   ├── __tests__
│       │   │   └── fixtures
│       │   │       ├── lerna
│       │   │       │   └── nested
│       │   │       ├── none
│       │   │       │   └── nested
│       │   │       ├── pnpm
│       │   │       │   └── nested
│       │   │       └── yarn
│       │   │           └── nested
│       │   └── middlewares
│       └── ssr
│           └── __tests__
└── types
  • 実はそんなにディレクトリはないっぽい
  • 普段はCLI経由で叩くことが多いので、CLIからどういった流れでコアのコードが実行されているのかを追ってみる

CLI経由でのコマンド実行の流れ

  1. bin/vite.js
  2. dist/node/cli
  3. コマンドに応じた振り分け

bin/vite.js

  • source-map-supportのインストール (StackTraceから追えるようにぽい)
  • --profile オプションに応じた挙動の切り替え
    • APIドキュメントとかには記述がない
    • new inspector.Session() を呼び出しているのでデバッグ用?
  • require('../dist/node/cli') … 実行本体
    • 実際には packages/vite/src/node/cli.ts

dist/node/cli (packages/vite/src/node/cli.ts)

コマンドに応じた振り分け

[root]

  • vite起動本体。ViteDevServerが立ち上がる(実体は https://nodejs.org/api/http.html
  • packages/vite/src/node/server/index.ts # createServer
  • CLIオプションを inlineConfig として渡す

build

  • 本番用build
  • packages/vite/src/node/build.ts # build

optimize

  • packages/vite/src/node/optimizer.ts # optimizeDeps
  • https://vitejs.dev/guide/dep-pre-bundling.html
  • 通称 dependency pre-bundling の実行
  • 一部依存を事前解決しておくことで、vite serve 時のパフォーマンス向上に繋がるぽい

preview


  • 依存しているライブラリ (cac とか picocolors とか) は自分でも使えそう
  • CLI経由の場合オプションはそれほどない。まだ読めるって感じする
  • コア(root)の中に入るとそれなりに大きい。そこからが本番って感じ

次 → 振り分けている各コマンドの詳細を見ていく

Viteのコードを読む - リポジトリ直下のファイル群

前回: Viteのコードを読む - ディレクトリ構造とテスト実行 - memo_md


リポジトリ直下のファイル群をみてみる

チェックアウトしたリポジトリの直下にあるファイル群。 主に設定ファイルとかそういう系を眺めてみる。

一覧

  • package.json
  • LICENSE
  • CODE_OF_CONDUCT.md
  • CONTRIBUTING.md
  • jest.config.ts
  • netlify.toml
  • pnpm-lock.yaml
  • pnpm-workspace.yaml
  • README.md

LICENCEとかそういうのは省略。必要そうなのを見ていく。

package.json

  • node ≥ 12.2.0
  • scripts
    • preinstallnpx only-allow pnpm
      • https://github.com/pnpm/only-allow
      • 利用可能なパッケージマネージャを強制するツールらしい。こんなのあったのか..
      • 試しに yarn install とかすると Use "pnpm install" for installation in this project. とエラーにしてくれる
    • formatlint はよくある感じ。eslintやprettierを実行してる。
    • 他は jest実行系, vitepressによるドキュメント生成系、viteやpluginのビルド系、などがある
  • lint-staged
    • https://github.com/okonet/lint-staged
    • gitでstageされたファイルを対象にlint,prettierを実行
    • prettierは全ファイル。eslintはtsファイルのみ対象に実行している
  • simple-git-hooks

pnpm-workspace.yaml / pnpm-lock.yaml

以下をmonorepos対象にしてる

  • packages/*
  • packages/playground/**

jest.config.ts

  • ts-jest利用
    • 意外とテスト実行時に型チェックしてるんだなという感想
  • VITE_TEST_BUILD 指定時は実行対象を playground 配下に絞ってる
    • npm script の test-build test-serve の呼び分けで使う
    • 開発サーバモードでテストするか、ビルドモードでテストするかの違い
    • CONTRIBUTING.md にそのあたりの説明がある
  • globalSetup: './scripts/jestGlobalSetup.cjs'
    • playwright-chromium で browser を起動
    • packages/temp に playground のファイルをコピーしてる?
  • globalTeardown: './scripts/jestGlobalTeardown.cjs'
    • global.__BROWSER_SERVER__ にサーバーがあれば閉じる
    • packages/temp を消して後片付け
  • testEnvironment: './scripts/jestEnv.cjs'
    • 独自のEnvironmentを実装して適用
    • setup
      • wsEndpoint を参照して、ブラウザで接続
      • global.page に新しく開いたブラウザのページを保持
    • teerdown
      • ブラウザを閉じてる
  • setupFilesAfterEnv: ['./scripts/jestPerTestSetup.ts']
    • 各 Playground のテストディレクトリにある serve.js があれば実行する
      • ビルドやサーバ起動を行ってる
      • requireしてみて serve or preServe があれば実行という感じ
    • isBuildTest (VITE_TEST_BUILD で決まる)の値に応じて page から繋ぐ接続先のURLを切り替えてる
      • isBuildTest がtruthyならビルドされる
      • Viteのサーバではなく、ビルド結果を使って http パッケージによる配信を行う

CODE_OF_CONDUCT.md

健全なOSS運営についてのポリシーが書いてある。

大事。

CONTRIBUTING.md

  • リポジトリのセットアップ方法
    • pnpm 周りの導入あたりがわかる
  • テスト実行周り
    • playwright使ってますよ〜という話
    • 開発サーバモードとビルドモードの違い
    • テストの書き方
  • デバッグログの出力方法
  • PRのガイドライン
  • Dependencies周りの注意点
    • 小さく保つためRollupでバンドルするのが前提で、基本的にdevDependenciesになる
    • requireは使えないので dynamic import を使う必要がある
    • 依存関係が大きく、機能のわりにサイズが大きいものは使わない
    • 結構厳しい感じ。自力で作れるものは作りましょうって感じかもしれん
  • 型付けを完璧に維持してますという話
  • オプション追加、ホントに必要かよく考えろよという話
    • 価値があるのか、他に方法(別オプションやプラグインでの解決)が無いのか、など
  • 翻訳や Vite Land (https://chat.vitejs.dev) の話

感想

  • JestのEnvironment独自で作ってるのはナルホドって感じだった
  • 依存関係気軽に足せないのは大変そう
  • lint-staged とか普通に知らんかった..、便利そうなので使っていきたい

次→Viteのコアコードを少しずつ読んでく

Viteのコードを読む - ディレクトリ構造とテスト実行

(全然ブログ書いてなかった...)

Viteのコードを読んでみようという試み

Viteが盛り上がっていて個人的にも使っているので中身を少しでも把握したい。

大変だろうけど、バージョンが上がりまくって機能追加されてからだと中身追うのも無理になりそうなので、今のうちに見れるだけ見てみるという試み。心が折れたらやめるかもしれない。

読む対象

  • v2.8.3
  • hash: e2349569cf96e506e0d5fff1d043727a77fdad70

ファイル一覧を眺める

とりあえず何も考えずに tree コマンドで列挙してみた

見てみる(クリックで展開)

.
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs
│   ├── blog
│   │   └── announcing-vite2.md
│   ├── config
│   │   └── index.md
│   ├── guide
│   │   ├── api-hmr.md
│   │   ├── api-javascript.md
│   │   ├── api-plugin.md
│   │   ├── assets.md
│   │   ├── backend-integration.md
│   │   ├── build.md
│   │   ├── comparisons.md
│   │   ├── dep-pre-bundling.md
│   │   ├── env-and-mode.md
│   │   ├── features.md
│   │   ├── index.md
│   │   ├── migration.md
│   │   ├── ssr.md
│   │   ├── static-deploy.md
│   │   ├── using-plugins.md
│   │   └── why.md
│   ├── images
│   │   ├── bundler.png
│   │   ├── esm.png
│   │   ├── graph.png
│   │   ├── vercel-configuration.png
│   │   └── vite-plugin-inspect.png
│   ├── index.md
│   ├── plugins
│   │   └── index.md
│   └── public
│       ├── _headers
│       ├── cypress.svg
│       ├── divriots.png
│       ├── logo.svg
│       ├── mux.svg
│       ├── plaid.svg
│       ├── stackblitz.svg
│       ├── tailwind-labs.svg
│       ├── vite.mp3
│       ├── voice.svg
│       └── vuejobs.png
├── jest.config.ts
├── netlify.toml
├── package.json
├── packages
│   ├── create-vite
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── __tests__
│   │   │   └── cli.spec.ts
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── template-lit
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── favicon.svg
│   │   │   │   └── my-element.js
│   │   │   └── vite.config.js
│   │   ├── template-lit-ts
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── favicon.svg
│   │   │   │   ├── my-element.ts
│   │   │   │   └── vite-env.d.ts
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.ts
│   │   ├── template-preact
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── app.jsx
│   │   │   │   ├── favicon.svg
│   │   │   │   ├── index.css
│   │   │   │   ├── logo.jsx
│   │   │   │   └── main.jsx
│   │   │   └── vite.config.js
│   │   ├── template-preact-ts
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── app.tsx
│   │   │   │   ├── favicon.svg
│   │   │   │   ├── index.css
│   │   │   │   ├── logo.tsx
│   │   │   │   ├── main.tsx
│   │   │   │   ├── preact.d.ts
│   │   │   │   └── vite-env.d.ts
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.ts
│   │   ├── template-react
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── App.css
│   │   │   │   ├── App.jsx
│   │   │   │   ├── favicon.svg
│   │   │   │   ├── index.css
│   │   │   │   ├── logo.svg
│   │   │   │   └── main.jsx
│   │   │   └── vite.config.js
│   │   ├── template-react-ts
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── App.css
│   │   │   │   ├── App.tsx
│   │   │   │   ├── favicon.svg
│   │   │   │   ├── index.css
│   │   │   │   ├── logo.svg
│   │   │   │   ├── main.tsx
│   │   │   │   └── vite-env.d.ts
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.ts
│   │   ├── template-svelte
│   │   │   ├── README.md
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── jsconfig.json
│   │   │   ├── package.json
│   │   │   ├── public
│   │   │   │   └── favicon.ico
│   │   │   ├── src
│   │   │   │   ├── App.svelte
│   │   │   │   ├── assets
│   │   │   │   │   └── svelte.png
│   │   │   │   ├── lib
│   │   │   │   │   └── Counter.svelte
│   │   │   │   ├── main.js
│   │   │   │   └── vite-env.d.ts
│   │   │   └── vite.config.js
│   │   ├── template-svelte-ts
│   │   │   ├── README.md
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── public
│   │   │   │   └── favicon.ico
│   │   │   ├── src
│   │   │   │   ├── App.svelte
│   │   │   │   ├── assets
│   │   │   │   │   └── svelte.png
│   │   │   │   ├── lib
│   │   │   │   │   └── Counter.svelte
│   │   │   │   ├── main.ts
│   │   │   │   └── vite-env.d.ts
│   │   │   ├── svelte.config.js
│   │   │   ├── tsconfig.json
│   │   │   ├── tsconfig.node.json
│   │   │   └── vite.config.ts
│   │   ├── template-vanilla
│   │   │   ├── _gitignore
│   │   │   ├── favicon.svg
│   │   │   ├── index.html
│   │   │   ├── main.js
│   │   │   ├── package.json
│   │   │   └── style.css
│   │   ├── template-vanilla-ts
│   │   │   ├── _gitignore
│   │   │   ├── favicon.svg
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── main.ts
│   │   │   │   ├── style.css
│   │   │   │   └── vite-env.d.ts
│   │   │   └── tsconfig.json
│   │   ├── template-vue
│   │   │   ├── README.md
│   │   │   ├── _gitignore
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── public
│   │   │   │   └── favicon.ico
│   │   │   ├── src
│   │   │   │   ├── App.vue
│   │   │   │   ├── assets
│   │   │   │   │   └── logo.png
│   │   │   │   ├── components
│   │   │   │   │   └── HelloWorld.vue
│   │   │   │   └── main.js
│   │   │   └── vite.config.js
│   │   └── template-vue-ts
│   │       ├── README.md
│   │       ├── _gitignore
│   │       ├── index.html
│   │       ├── package.json
│   │       ├── public
│   │       │   └── favicon.ico
│   │       ├── src
│   │       │   ├── App.vue
│   │       │   ├── assets
│   │       │   │   └── logo.png
│   │       │   ├── components
│   │       │   │   └── HelloWorld.vue
│   │       │   ├── env.d.ts
│   │       │   └── main.ts
│   │       ├── tsconfig.json
│   │       ├── tsconfig.node.json
│   │       └── vite.config.ts
│   ├── playground
│   │   ├── alias
│   │   │   ├── __tests__
│   │   │   │   └── alias.spec.ts
│   │   │   ├── customResolver.js
│   │   │   ├── dir
│   │   │   │   ├── from-script-src.js
│   │   │   │   ├── module
│   │   │   │   │   ├── index.js
│   │   │   │   │   └── package.json
│   │   │   │   ├── test.css
│   │   │   │   └── test.js
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── test.js
│   │   │   └── vite.config.js
│   │   ├── assets
│   │   │   ├── __tests__
│   │   │   │   └── assets.spec.ts
│   │   │   ├── css
│   │   │   │   ├── css-url.css
│   │   │   │   ├── fonts.css
│   │   │   │   ├── icons.css
│   │   │   │   ├── import.css
│   │   │   │   └── nested
│   │   │   │       └── at-imported-css-url.css
│   │   │   ├── fonts
│   │   │   │   ├── Inter-Italic.woff
│   │   │   │   └── Inter-Italic.woff2
│   │   │   ├── foo.js
│   │   │   ├── index.html
│   │   │   ├── nested
│   │   │   │   ├── asset.png
│   │   │   │   ├── fragment-bg.svg
│   │   │   │   ├── fragment.svg
│   │   │   │   ├── icon.png
│   │   │   │   └── �\203\206�\202��\203\210-測試-white\ space.png
│   │   │   ├── package.json
│   │   │   ├── static
│   │   │   │   ├── icon.png
│   │   │   │   ├── import-expression.js
│   │   │   │   ├── raw.css
│   │   │   │   └── raw.js
│   │   │   ├── vite.config.js
│   │   │   └── �\203\206�\202��\203\210-測試-white\ space.js
│   │   ├── backend-integration
│   │   │   ├── __tests__
│   │   │   │   └── backend-integration.spec.ts
│   │   │   ├── frontend
│   │   │   │   ├── entrypoints
│   │   │   │   │   ├── global.css
│   │   │   │   │   ├── index.html
│   │   │   │   │   └── main.ts
│   │   │   │   ├── images
│   │   │   │   │   └── logo.png
│   │   │   │   └── styles
│   │   │   │       ├── background.css
│   │   │   │       └── tailwind.css
│   │   │   ├── package.json
│   │   │   ├── postcss.config.js
│   │   │   ├── references.css
│   │   │   ├── tailwind.config.js
│   │   │   └── vite.config.js
│   │   ├── cli
│   │   │   ├── __tests__
│   │   │   │   ├── cli.spec.ts
│   │   │   │   └── serve.js
│   │   │   ├── index.html
│   │   │   ├── index.js
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── cli-module
│   │   │   ├── __tests__
│   │   │   │   ├── cli-module.spec.ts
│   │   │   │   └── serve.js
│   │   │   ├── index.html
│   │   │   ├── index.js
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── css
│   │   │   ├── __tests__
│   │   │   │   └── css.spec.ts
│   │   │   ├── async-treeshaken.css
│   │   │   ├── async-treeshaken.js
│   │   │   ├── async.css
│   │   │   ├── async.js
│   │   │   ├── composed.module.css
│   │   │   ├── composed.module.less
│   │   │   ├── composed.module.scss
│   │   │   ├── composes-path-resolving.module.css
│   │   │   ├── css-dep
│   │   │   │   ├── index.css
│   │   │   │   ├── index.js
│   │   │   │   ├── index.scss
│   │   │   │   ├── index.styl
│   │   │   │   └── package.json
│   │   │   ├── dep.css
│   │   │   ├── glob-dep
│   │   │   │   ├── bar.css
│   │   │   │   └── foo.css
│   │   │   ├── glob-dep.css
│   │   │   ├── imported-at-import.css
│   │   │   ├── imported.css
│   │   │   ├── index.html
│   │   │   ├── inlined.css
│   │   │   ├── less.less
│   │   │   ├── linked-at-import.css
│   │   │   ├── linked.css
│   │   │   ├── main.js
│   │   │   ├── minify.css
│   │   │   ├── mod.module.css
│   │   │   ├── mod.module.scss
│   │   │   ├── nested
│   │   │   │   ├── _index.scss
│   │   │   │   ├── _partial.scss
│   │   │   │   ├── icon.png
│   │   │   │   ├── nested.less
│   │   │   │   └── nested.styl
│   │   │   ├── ok.png
│   │   │   ├── options
│   │   │   │   ├── absolute-import.styl
│   │   │   │   └── relative-import.styl
│   │   │   ├── package.json
│   │   │   ├── pkg-dep
│   │   │   │   ├── _index.scss
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── postcss-caching
│   │   │   │   ├── blue-app
│   │   │   │   │   ├── imported.css
│   │   │   │   │   ├── index.html
│   │   │   │   │   ├── main.js
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── postcss.config.js
│   │   │   │   ├── css.spec.ts
│   │   │   │   └── green-app
│   │   │   │       ├── imported.css
│   │   │   │       ├── index.html
│   │   │   │       ├── main.js
│   │   │   │       ├── package.json
│   │   │   │       └── postcss.config.js
│   │   │   ├── postcss.config.js
│   │   │   ├── sass.scss
│   │   │   ├── stylus.styl
│   │   │   └── vite.config.js
│   │   ├── css-codesplit
│   │   │   ├── __tests__
│   │   │   │   └── css-codesplit.spec.ts
│   │   │   ├── index.html
│   │   │   ├── main.css
│   │   │   ├── main.js
│   │   │   ├── other.js
│   │   │   ├── package.json
│   │   │   ├── style.css
│   │   │   └── vite.config.js
│   │   ├── css-codesplit-cjs
│   │   │   ├── __tests__
│   │   │   │   └── css-codesplit.spec.ts
│   │   │   ├── index.html
│   │   │   ├── main.css
│   │   │   ├── main.js
│   │   │   ├── other.js
│   │   │   ├── package.json
│   │   │   ├── style.css
│   │   │   └── vite.config.js
│   │   ├── data-uri
│   │   │   ├── __tests__
│   │   │   │   └── data-uri.spec.ts
│   │   │   ├── index.html
│   │   │   └── package.json
│   │   ├── define
│   │   │   ├── __tests__
│   │   │   │   └── define.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── dynamic-import
│   │   │   ├── __tests__
│   │   │   │   └── dynamic-import.spec.ts
│   │   │   ├── css
│   │   │   │   └── index.css
│   │   │   ├── index.html
│   │   │   ├── mxd.js
│   │   │   ├── mxd.json
│   │   │   ├── nested
│   │   │   │   ├── index.js
│   │   │   │   └── shared.js
│   │   │   ├── package.json
│   │   │   ├── qux.js
│   │   │   ├── views
│   │   │   │   ├── bar.js
│   │   │   │   ├── baz.js
│   │   │   │   └── foo.js
│   │   │   └── vite.config.js
│   │   ├── env
│   │   │   ├── __tests__
│   │   │   │   └── env.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── extensions
│   │   │   ├── __tests__
│   │   │   │   └── extensions.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── file-delete-restore
│   │   │   ├── App.jsx
│   │   │   ├── Child.jsx
│   │   │   ├── __tests__
│   │   │   │   └── file-delete-restore.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── fs-serve
│   │   │   ├── __tests__
│   │   │   │   └── fs-serve.spec.ts
│   │   │   ├── entry.js
│   │   │   ├── nested
│   │   │   │   └── foo.js
│   │   │   ├── package.json
│   │   │   ├── root
│   │   │   │   ├── src
│   │   │   │   │   ├── index.html
│   │   │   │   │   └── safe.txt
│   │   │   │   ├── unsafe.txt
│   │   │   │   └── vite.config.js
│   │   │   ├── safe.json
│   │   │   └── unsafe.json
│   │   ├── glob-import
│   │   │   ├── __tests__
│   │   │   │   └── glob-import.spec.ts
│   │   │   ├── dir
│   │   │   │   ├── baz.json
│   │   │   │   ├── foo.js
│   │   │   │   ├── index.js
│   │   │   │   ├── nested
│   │   │   │   │   └── bar.js
│   │   │   │   └── node_modules
│   │   │   │       └── hoge.js
│   │   │   ├── index.html
│   │   │   └── package.json
│   │   ├── hmr
│   │   │   ├── __tests__
│   │   │   │   └── hmr.spec.ts
│   │   │   ├── customFile.js
│   │   │   ├── global.css
│   │   │   ├── hmr.js
│   │   │   ├── hmrDep.js
│   │   │   ├── hmrNestedDep.js
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── unicode-path
│   │   │   │   └── 中�\226\207-�\201��\201��\202\223�\201\224-�\225\234�\200-�\237\214\225�\237\214\226�\237\214\227
│   │   │   │       └── index.html
│   │   │   └── vite.config.js
│   │   ├── html
│   │   │   ├── __tests__
│   │   │   │   └── html.spec.ts
│   │   │   ├── common.css
│   │   │   ├── emptyAttr.html
│   │   │   ├── foo.html
│   │   │   ├── index.html
│   │   │   ├── inline
│   │   │   │   ├── common.js
│   │   │   │   ├── dep1.js
│   │   │   │   ├── dep2.js
│   │   │   │   ├── dep3.js
│   │   │   │   ├── module-graph.dot
│   │   │   │   ├── shared-1.html
│   │   │   │   ├── shared-2.html
│   │   │   │   ├── shared.js
│   │   │   │   ├── unique.html
│   │   │   │   └── unique.js
│   │   │   ├── invalid.html
│   │   │   ├── link.html
│   │   │   ├── main.css
│   │   │   ├── main.js
│   │   │   ├── nested
│   │   │   │   ├── index.html
│   │   │   │   ├── nested.css
│   │   │   │   └── nested.js
│   │   │   ├── noBody.html
│   │   │   ├── noHead.html
│   │   │   ├── package.json
│   │   │   ├── scriptAsync.html
│   │   │   ├── scriptMixed.html
│   │   │   ├── shared.js
│   │   │   ├── unicode-path
│   │   │   │   └── 中�\226\207-�\201��\201��\202\223�\201\224-�\225\234�\200-�\237\214\225�\237\214\226�\237\214\227
│   │   │   │       └── index.html
│   │   │   ├── vite.config.js
│   │   │   └── zeroJS.html
│   │   ├── json
│   │   │   ├── __tests__
│   │   │   │   └── json.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── public
│   │   │   │   └── public.json
│   │   │   └── test.json
│   │   ├── legacy
│   │   │   ├── __tests__
│   │   │   │   ├── legacy.spec.ts
│   │   │   │   └── ssr
│   │   │   │       ├── legacy-ssr.spec.ts
│   │   │   │       └── serve.js
│   │   │   ├── async.js
│   │   │   ├── entry-server.js
│   │   │   ├── immutable-chunk.js
│   │   │   ├── index.html
│   │   │   ├── main.js
│   │   │   ├── package.json
│   │   │   ├── style.css
│   │   │   ├── vite.config-custom-filename.js
│   │   │   └── vite.config.js
│   │   ├── lib
│   │   │   ├── __tests__
│   │   │   │   ├── lib.spec.ts
│   │   │   │   └── serve.js
│   │   │   ├── index.dist.html
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── main.js
│   │   │   │   ├── main2.js
│   │   │   │   └── message.js
│   │   │   ├── vite.config.js
│   │   │   └── vite.dyimport.config.js
│   │   ├── multiple-entrypoints
│   │   │   ├── __tests__
│   │   │   │   └── multiple-entrypoints.spec.ts
│   │   │   ├── deps.json
│   │   │   ├── dynamic-a.js
│   │   │   ├── dynamic-b.js
│   │   │   ├── entrypoints
│   │   │   │   ├── a0.js
│   │   │   │   ├── a1.js
│   │   │   │   ├── a10.js
│   │   │   │   ├── a11.js
│   │   │   │   ├── a12.js
│   │   │   │   ├── a13.js
│   │   │   │   ├── a14.js
│   │   │   │   ├── a15.js
│   │   │   │   ├── a16.js
│   │   │   │   ├── a17.js
│   │   │   │   ├── a18.js
│   │   │   │   ├── a19.js
│   │   │   │   ├── a2.js
│   │   │   │   ├── a20.js
│   │   │   │   ├── a21.js
│   │   │   │   ├── a22.js
│   │   │   │   ├── a23.js
│   │   │   │   ├── a24.js
│   │   │   │   ├── a3.js
│   │   │   │   ├── a4.js
│   │   │   │   ├── a5.js
│   │   │   │   ├── a6.js
│   │   │   │   ├── a7.js
│   │   │   │   ├── a8.js
│   │   │   │   └── a9.js
│   │   │   ├── index.html
│   │   │   ├── index.js
│   │   │   ├── package.json
│   │   │   ├── reference.js
│   │   │   ├── reference.scss
│   │   │   └── vite.config.js
│   │   ├── nested-deps
│   │   │   ├── __tests__
│   │   │   │   └── nested-deps.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── test-package-a
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── test-package-b
│   │   │   │   ├── index.js
│   │   │   │   ├── node_modules
│   │   │   │   │   └── test-package-a
│   │   │   │   │       ├── index.js
│   │   │   │   │       └── package.json
│   │   │   │   └── package.json
│   │   │   ├── test-package-c
│   │   │   │   ├── index-es.js
│   │   │   │   ├── index.js
│   │   │   │   ├── package.json
│   │   │   │   └── side.js
│   │   │   ├── test-package-d
│   │   │   │   ├── index.js
│   │   │   │   ├── package.json
│   │   │   │   └── test-package-d-nested
│   │   │   │       ├── index.js
│   │   │   │       └── package.json
│   │   │   ├── test-package-e
│   │   │   │   ├── index.js
│   │   │   │   ├── package.json
│   │   │   │   ├── test-package-e-excluded
│   │   │   │   │   ├── index.js
│   │   │   │   │   └── package.json
│   │   │   │   └── test-package-e-included
│   │   │   │       ├── index.js
│   │   │   │       └── package.json
│   │   │   └── vite.config.js
│   │   ├── optimize-deps
│   │   │   ├── __tests__
│   │   │   │   └── optimize-deps.spec.ts
│   │   │   ├── cjs-dynamic.js
│   │   │   ├── cjs.js
│   │   │   ├── dedupe.js
│   │   │   ├── dep-cjs-compiled-from-cjs
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── dep-cjs-compiled-from-esm
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── dep-esbuild-plugin-transform
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── dep-linked
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── dep-linked-include
│   │   │   │   ├── Test.vue
│   │   │   │   ├── foo.js
│   │   │   │   ├── index.mjs
│   │   │   │   ├── package.json
│   │   │   │   └── test.css
│   │   │   ├── glob
│   │   │   │   └── foo.js
│   │   │   ├── index.html
│   │   │   ├── nested-exclude
│   │   │   │   ├── index.js
│   │   │   │   ├── nested-include
│   │   │   │   │   ├── index.js
│   │   │   │   │   └── package.json
│   │   │   │   └── package.json
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── optimize-missing-deps
│   │   │   ├── __test__
│   │   │   │   ├── optimize-missing-deps.spec.ts
│   │   │   │   └── serve.js
│   │   │   ├── index.html
│   │   │   ├── main.js
│   │   │   ├── missing-dep
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── multi-entry-dep
│   │   │   │   ├── index.browser.js
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── package.json
│   │   │   └── server.js
│   │   ├── package.json
│   │   ├── preload
│   │   │   ├── __tests__
│   │   │   │   └── preload.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── router.js
│   │   │   ├── src
│   │   │   │   ├── App.vue
│   │   │   │   └── components
│   │   │   │       ├── About.vue
│   │   │   │       ├── Hello.vue
│   │   │   │       └── Home.vue
│   │   │   └── vite.config.js
│   │   ├── preserve-symlinks
│   │   │   ├── __tests__
│   │   │   │   └── preserve-symlinks.spec.ts
│   │   │   ├── index.html
│   │   │   ├── moduleA
│   │   │   │   ├── linked.js -> ./src/index.js
│   │   │   │   ├── package.json
│   │   │   │   └── src
│   │   │   │       ├── data.js
│   │   │   │       └── index.js
│   │   │   ├── package.json
│   │   │   └── src
│   │   │       └── main.js
│   │   ├── react
│   │   │   ├── App.jsx
│   │   │   ├── __tests__
│   │   │   │   └── react.spec.ts
│   │   │   ├── components
│   │   │   │   └── Dummy.jsx
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   └── vite.config.ts
│   │   ├── react-emotion
│   │   │   ├── App.jsx
│   │   │   ├── __tests__
│   │   │   │   └── react.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   └── vite.config.ts
│   │   ├── resolve
│   │   │   ├── __tests__
│   │   │   │   └── resolve.spec.ts
│   │   │   ├── browser-field
│   │   │   │   ├── multiple.dot.path.js
│   │   │   │   ├── no-ext-index
│   │   │   │   │   └── index.js
│   │   │   │   ├── no-ext.js
│   │   │   │   ├── not-browser.js
│   │   │   │   ├── out
│   │   │   │   │   ├── cjs.node.js
│   │   │   │   │   └── esm.browser.js
│   │   │   │   ├── package.json
│   │   │   │   └── relative.js
│   │   │   ├── config-dep.js
│   │   │   ├── custom-condition
│   │   │   │   ├── index.custom.js
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── custom-ext.es
│   │   │   ├── custom-main-field
│   │   │   │   ├── index.custom.js
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── dir
│   │   │   │   └── index.js
│   │   │   ├── dir-with-ext
│   │   │   │   └── index.js
│   │   │   ├── dir-with-ext.js
│   │   │   │   └── empty
│   │   │   ├── dir.js
│   │   │   ├── exact-extension
│   │   │   │   ├── file.js
│   │   │   │   └── file.js.js
│   │   │   ├── exports-env
│   │   │   │   ├── browser.js
│   │   │   │   ├── browser.mjs
│   │   │   │   ├── browser.prod.mjs
│   │   │   │   ├── fallback.umd.js
│   │   │   │   └── package.json
│   │   │   ├── exports-path
│   │   │   │   ├── cjs.js
│   │   │   │   ├── deep.js
│   │   │   │   ├── dir
│   │   │   │   │   └── dir.js
│   │   │   │   ├── main.js
│   │   │   │   └── package.json
│   │   │   ├── index.html
│   │   │   ├── inline-package
│   │   │   │   ├── inline.js
│   │   │   │   └── package.json
│   │   │   ├── package.json
│   │   │   ├── ts-extension
│   │   │   │   ├── hello.ts
│   │   │   │   └── index.ts
│   │   │   ├── utf8-bom
│   │   │   │   └── main.js
│   │   │   ├── util
│   │   │   │   ├── bar.util.js
│   │   │   │   └── index.js
│   │   │   └── vite.config.js
│   │   ├── resolve-config
│   │   │   ├── __tests__
│   │   │   │   ├── resolve-config.spec.ts
│   │   │   │   └── serve.js
│   │   │   ├── package.json
│   │   │   └── root
│   │   │       ├── index.js
│   │   │       └── vite.config.js
│   │   ├── resolve-linked
│   │   │   ├── dep.js
│   │   │   ├── package.json
│   │   │   └── src
│   │   │       └── index.js
│   │   ├── shims.d.ts
│   │   ├── ssr-deps
│   │   │   ├── __tests__
│   │   │   │   ├── serve.js
│   │   │   │   └── ssr-deps.spec.ts
│   │   │   ├── define-properties-exports
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── define-property-exports
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── forwarded-export
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── index.html
│   │   │   ├── message
│   │   │   ├── object-assigned-exports
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── only-object-assigned-exports
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── package.json
│   │   │   ├── primitive-export
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── read-file-content
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── require-absolute
│   │   │   │   ├── foo.js
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── server.js
│   │   │   ├── src
│   │   │   │   └── app.js
│   │   │   └── ts-transpiled-exports
│   │   │       ├── index.js
│   │   │       └── package.json
│   │   ├── ssr-html
│   │   │   ├── __tests__
│   │   │   │   ├── serve.js
│   │   │   │   └── ssr-html.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── server.js
│   │   │   └── src
│   │   │       └── app.js
│   │   ├── ssr-pug
│   │   │   ├── __tests__
│   │   │   │   ├── serve.js
│   │   │   │   └── ssr-pug.spec.ts
│   │   │   ├── index.pug
│   │   │   ├── package.json
│   │   │   ├── server.js
│   │   │   └── src
│   │   │       └── app.js
│   │   ├── ssr-react
│   │   │   ├── __tests__
│   │   │   │   ├── serve.js
│   │   │   │   └── ssr-react.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── prerender.js
│   │   │   ├── server.js
│   │   │   ├── src
│   │   │   │   ├── App.jsx
│   │   │   │   ├── add.js
│   │   │   │   ├── circular-dep-init
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── circular-dep-init.js
│   │   │   │   │   ├── module-a.js
│   │   │   │   │   └── module-b.js
│   │   │   │   ├── entry-client.jsx
│   │   │   │   ├── entry-server.jsx
│   │   │   │   ├── forked-deadlock
│   │   │   │   │   ├── README.md
│   │   │   │   │   ├── common-module.js
│   │   │   │   │   ├── deadlock-fuse-module.js
│   │   │   │   │   ├── fuse-stuck-bridge-module.js
│   │   │   │   │   ├── middle-module.js
│   │   │   │   │   └── stuck-module.js
│   │   │   │   ├── multiply.js
│   │   │   │   └── pages
│   │   │   │       ├── About.jsx
│   │   │   │       ├── Env.jsx
│   │   │   │       └── Home.jsx
│   │   │   └── vite.config.js
│   │   ├── ssr-vue
│   │   │   ├── __tests__
│   │   │   │   ├── serve.js
│   │   │   │   └── ssr-vue.spec.ts
│   │   │   ├── dep-import-type
│   │   │   │   ├── deep
│   │   │   │   │   └── index.d.ts
│   │   │   │   └── package.json
│   │   │   ├── example-external-component
│   │   │   │   ├── ExampleExternalComponent.vue
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── prerender.js
│   │   │   ├── server.js
│   │   │   ├── src
│   │   │   │   ├── App.vue
│   │   │   │   ├── assets
│   │   │   │   │   ├── button.css
│   │   │   │   │   ├── fonts
│   │   │   │   │   │   ├── Inter-Italic.woff
│   │   │   │   │   │   └── Inter-Italic.woff2
│   │   │   │   │   └── logo.png
│   │   │   │   ├── components
│   │   │   │   │   ├── Foo.jsx
│   │   │   │   │   ├── ImportType.vue
│   │   │   │   │   ├── button.js
│   │   │   │   │   └── foo.css
│   │   │   │   ├── entry-client.js
│   │   │   │   ├── entry-server.js
│   │   │   │   ├── main.js
│   │   │   │   ├── pages
│   │   │   │   │   ├── About.vue
│   │   │   │   │   ├── External.vue
│   │   │   │   │   ├── Home.vue
│   │   │   │   │   └── Store.vue
│   │   │   │   └── router.js
│   │   │   ├── vite.config.js
│   │   │   └── vite.config.noexternal.js
│   │   ├── ssr-webworker
│   │   │   ├── __tests__
│   │   │   │   ├── serve.js
│   │   │   │   └── ssr-webworker.spec.ts
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   └── entry-worker.jsx
│   │   │   ├── vite.config.js
│   │   │   └── worker.js
│   │   ├── tailwind
│   │   │   ├── __test__
│   │   │   │   └── tailwind.spec.ts
│   │   │   ├── index.css
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── postcss.config.js
│   │   │   ├── public
│   │   │   │   └── favicon.ico
│   │   │   ├── src
│   │   │   │   ├── App.vue
│   │   │   │   ├── assets
│   │   │   │   │   └── logo.png
│   │   │   │   ├── components
│   │   │   │   │   └── HelloWorld.vue
│   │   │   │   ├── main.js
│   │   │   │   ├── router.ts
│   │   │   │   └── views
│   │   │   │       └── Page.vue
│   │   │   ├── tailwind.config.js
│   │   │   └── vite.config.ts
│   │   ├── testUtils.ts
│   │   ├── tsconfig-json
│   │   │   ├── __tests__
│   │   │   │   └── tsconfig-json.spec.ts
│   │   │   ├── index.html
│   │   │   ├── nested
│   │   │   │   ├── main.ts
│   │   │   │   ├── not-used-type.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── nested-with-extends
│   │   │   │   ├── main.ts
│   │   │   │   ├── not-used-type.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   ├── main.ts
│   │   │   │   └── not-used-type.ts
│   │   │   └── tsconfig.json
│   │   ├── tsconfig-json-load-error
│   │   │   ├── __tests__
│   │   │   │   └── tsconfig-json-load-error.spec.ts
│   │   │   ├── has-error
│   │   │   │   ├── main.ts
│   │   │   │   └── tsconfig.json
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src
│   │   │   │   └── main.ts
│   │   │   └── tsconfig.json
│   │   ├── tsconfig.json
│   │   ├── vue
│   │   │   ├── Assets.vue
│   │   │   ├── AsyncComponent.vue
│   │   │   ├── CssModules.vue
│   │   │   ├── CustomBlock.vue
│   │   │   ├── CustomBlockPlugin.ts
│   │   │   ├── CustomElement.ce.vue
│   │   │   ├── Hmr.vue
│   │   │   ├── Main.vue
│   │   │   ├── Node.vue
│   │   │   ├── PreProcessors.vue
│   │   │   ├── ReactivityTransform.vue
│   │   │   ├── ScanDep.vue
│   │   │   ├── Slotted.vue
│   │   │   ├── Syntax.vue
│   │   │   ├── __tests__
│   │   │   │   └── vue.spec.ts
│   │   │   ├── assets
│   │   │   │   ├── asset.png
│   │   │   │   └── fragment.svg
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── public
│   │   │   │   └── icon.png
│   │   │   ├── setup-import-template
│   │   │   │   ├── SetupImportTemplate.vue
│   │   │   │   └── template.html
│   │   │   ├── src-import
│   │   │   │   ├── SrcImport.vue
│   │   │   │   ├── script.ts
│   │   │   │   ├── srcImportStyle.vue
│   │   │   │   ├── srcImportStyle2.vue
│   │   │   │   ├── style.css
│   │   │   │   ├── style2.css
│   │   │   │   └── template.html
│   │   │   └── vite.config.ts
│   │   ├── vue-jsx
│   │   │   ├── Comp.tsx
│   │   │   ├── Comps.jsx
│   │   │   ├── OtherExt.tesx
│   │   │   ├── Script.vue
│   │   │   ├── SrcImport.jsx
│   │   │   ├── SrcImport.vue
│   │   │   ├── __tests__
│   │   │   │   └── vue-jsx.spec.ts
│   │   │   ├── index.html
│   │   │   ├── main.jsx
│   │   │   ├── package.json
│   │   │   └── vite.config.js
│   │   ├── vue-lib
│   │   │   ├── __tests__
│   │   │   │   ├── serve.js
│   │   │   │   └── vue-lib.spec.ts
│   │   │   ├── index.html
│   │   │   ├── package.json
│   │   │   ├── src-consumer
│   │   │   │   └── index.ts
│   │   │   ├── src-lib
│   │   │   │   ├── CompA.vue
│   │   │   │   ├── CompB.vue
│   │   │   │   └── index.ts
│   │   │   ├── vite.config.consumer.ts
│   │   │   └── vite.config.lib.ts
│   │   ├── wasm
│   │   │   ├── __tests__
│   │   │   │   └── wasm.spec.ts
│   │   │   ├── heavy.wasm
│   │   │   ├── heavy.wasm.map
│   │   │   ├── index.html
│   │   │   ├── light.wasm
│   │   │   └── package.json
│   │   └── worker
│   │       ├── __tests__
│   │       │   └── worker.spec.ts
│   │       ├── index.html
│   │       ├── my-shared-worker.ts
│   │       ├── my-worker.ts
│   │       ├── newUrl
│   │       │   ├── module.js
│   │       │   ├── url-shared-worker.js
│   │       │   └── url-worker.js
│   │       ├── package.json
│   │       ├── possible-ts-output-worker.mjs
│   │       ├── test-plugin.tsx
│   │       ├── vite.config.ts
│   │       └── workerImport.js
│   ├── plugin-legacy
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── index.d.ts
│   │   ├── index.js
│   │   └── package.json
│   ├── plugin-react
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── api-extractor.json
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── babel.d.ts
│   │   │   ├── fast-refresh.ts
│   │   │   ├── index.ts
│   │   │   └── jsx-runtime
│   │   │       ├── babel-import-to-require.ts
│   │   │       ├── babel-restore-jsx.spec.ts
│   │   │       ├── babel-restore-jsx.ts
│   │   │       └── restore-jsx.ts
│   │   └── tsconfig.json
│   ├── plugin-vue
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── api-extractor.json
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── compiler.ts
│   │   │   ├── handleHotUpdate.ts
│   │   │   ├── helper.ts
│   │   │   ├── index.ts
│   │   │   ├── main.ts
│   │   │   ├── script.ts
│   │   │   ├── style.ts
│   │   │   ├── template.ts
│   │   │   └── utils
│   │   │       ├── descriptorCache.ts
│   │   │       ├── error.ts
│   │   │       └── query.ts
│   │   └── tsconfig.json
│   ├── plugin-vue-jsx
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── index.d.ts
│   │   ├── index.js
│   │   └── package.json
│   └── vite
│       ├── CHANGELOG.md
│       ├── LICENSE.md
│       ├── README.md
│       ├── api-extractor.json
│       ├── bin
│       │   ├── openChrome.applescript
│       │   └── vite.js
│       ├── client.d.ts
│       ├── package.json
│       ├── rollup.config.js
│       ├── scripts
│       │   └── patchTypes.ts
│       ├── src
│       │   ├── client
│       │   │   ├── client.ts
│       │   │   ├── env.ts
│       │   │   ├── overlay.ts
│       │   │   └── tsconfig.json
│       │   └── node
│       │       ├── __tests__
│       │       │   ├── asset.spec.ts
│       │       │   ├── build.spec.ts
│       │       │   ├── config.spec.ts
│       │       │   ├── dev.spec.ts
│       │       │   ├── packages
│       │       │   │   ├── name
│       │       │   │   │   └── package.json
│       │       │   │   └── noname
│       │       │   │       └── package.json
│       │       │   ├── plugins
│       │       │   │   ├── css.spec.ts
│       │       │   │   └── import.spec.ts
│       │       │   ├── scan.spec.ts
│       │       │   └── utils.spec.ts
│       │       ├── build.ts
│       │       ├── certificate.ts
│       │       ├── cli.ts
│       │       ├── config.ts
│       │       ├── constants.ts
│       │       ├── http.ts
│       │       ├── importGlob.ts
│       │       ├── index.ts
│       │       ├── logger.ts
│       │       ├── optimizer
│       │       │   ├── esbuildDepPlugin.ts
│       │       │   ├── index.ts
│       │       │   ├── registerMissing.ts
│       │       │   └── scan.ts
│       │       ├── packages.ts
│       │       ├── plugin.ts
│       │       ├── plugins
│       │       │   ├── asset.ts
│       │       │   ├── assetImportMetaUrl.ts
│       │       │   ├── clientInjections.ts
│       │       │   ├── css.ts
│       │       │   ├── dataUri.ts
│       │       │   ├── define.ts
│       │       │   ├── esbuild.ts
│       │       │   ├── html.ts
│       │       │   ├── importAnalysis.ts
│       │       │   ├── importAnalysisBuild.ts
│       │       │   ├── index.ts
│       │       │   ├── json.ts
│       │       │   ├── loadFallback.ts
│       │       │   ├── manifest.ts
│       │       │   ├── modulePreloadPolyfill.ts
│       │       │   ├── preAlias.ts
│       │       │   ├── reporter.ts
│       │       │   ├── resolve.ts
│       │       │   ├── ssrRequireHook.ts
│       │       │   ├── terser.ts
│       │       │   ├── wasm.ts
│       │       │   ├── worker.ts
│       │       │   └── workerImportMetaUrl.ts
│       │       ├── preview.ts
│       │       ├── server
│       │       │   ├── __tests__
│       │       │   │   ├── fixtures
│       │       │   │   │   ├── lerna
│       │       │   │   │   │   ├── lerna.json
│       │       │   │   │   │   └── nested
│       │       │   │   │   │       └── package.json
│       │       │   │   │   ├── none
│       │       │   │   │   │   └── nested
│       │       │   │   │   │       └── package.json
│       │       │   │   │   ├── pnpm
│       │       │   │   │   │   ├── nested
│       │       │   │   │   │   │   └── package.json
│       │       │   │   │   │   ├── package.json
│       │       │   │   │   │   └── pnpm-workspace.yaml
│       │       │   │   │   └── yarn
│       │       │   │   │       ├── nested
│       │       │   │   │       │   └── package.json
│       │       │   │   │       └── package.json
│       │       │   │   ├── pluginContainer.spec.ts
│       │       │   │   └── search-root.spec.ts
│       │       │   ├── hmr.ts
│       │       │   ├── index.ts
│       │       │   ├── middlewares
│       │       │   │   ├── base.ts
│       │       │   │   ├── error.ts
│       │       │   │   ├── indexHtml.ts
│       │       │   │   ├── proxy.ts
│       │       │   │   ├── spaFallback.ts
│       │       │   │   ├── static.ts
│       │       │   │   ├── time.ts
│       │       │   │   └── transform.ts
│       │       │   ├── moduleGraph.ts
│       │       │   ├── openBrowser.ts
│       │       │   ├── pluginContainer.ts
│       │       │   ├── searchRoot.ts
│       │       │   ├── send.ts
│       │       │   ├── sourcemap.ts
│       │       │   ├── transformRequest.ts
│       │       │   └── ws.ts
│       │       ├── ssr
│       │       │   ├── __tests__
│       │       │   │   └── ssrTransform.spec.ts
│       │       │   ├── ssrExternal.ts
│       │       │   ├── ssrManifestPlugin.ts
│       │       │   ├── ssrModuleLoader.ts
│       │       │   ├── ssrStacktrace.ts
│       │       │   └── ssrTransform.ts
│       │       ├── tsconfig.json
│       │       └── utils.ts
│       ├── tsconfig.base.json
│       └── types
│           ├── alias.d.ts
│           ├── anymatch.d.ts
│           ├── chokidar.d.ts
│           ├── commonjs.d.ts
│           ├── connect.d.ts
│           ├── customEvent.d.ts
│           ├── dynamicImportVars.d.ts
│           ├── hmrPayload.d.ts
│           ├── http-proxy.d.ts
│           ├── importMeta.d.ts
│           ├── package.json
│           ├── shims.d.ts
│           ├── terser.d.ts
│           └── ws.d.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── scripts
│   ├── jestEnv.cjs
│   ├── jestGlobalSetup.cjs
│   ├── jestGlobalTeardown.cjs
│   ├── jestPerTestSetup.ts
│   ├── patchEsbuildDist.ts
│   ├── patchFileDeps.ts
│   ├── publishCI.ts
│   ├── release.ts
│   ├── releaseUtils.ts
│   ├── tsconfig.json
│   └── verifyCommit.ts
└── tree.txt

298 directories, 969 files

  • 298 directories, 969 files
  • packages/playground 配下が大きい
    • 215 directories, 628 files を占める
    • 様々な環境でViteを利用するミニマムセットで、全てテストを含んでいる
    • playgroundgrepしてみると、 CONTRIBUTING.md がヒットし、テストに関する記述などが出てくる
    • jestの設定に含まれており、 playwright-chromium 経由で Playwright を起動してブラウザ上でテストが実行される
  • packages/vite がvite本体ぽい
    • 27 directories, 114 files
    • コア部分は意外と小さい

ディレクトリだけ一覧して眺める

ファイル一覧だと Playground 配下が巨大すぎてアレなので、ディレクトリだけで一覧してみる。

  • tree -d
  • playground node_modules は除去

という感じで出力してみた。

.
├── docs
│   ├── blog
│   ├── config
│   ├── guide
│   ├── images
│   ├── plugins
│   └── public
├── packages
│   ├── create-vite
│   │   ├── __tests__
│   │   ├── template-lit
│   │   │   └── src
│   │   ├── template-lit-ts
│   │   │   └── src
│   │   ├── template-preact
│   │   │   └── src
│   │   ├── template-preact-ts
│   │   │   └── src
│   │   ├── template-react
│   │   │   └── src
│   │   ├── template-react-ts
│   │   │   └── src
│   │   ├── template-svelte
│   │   │   ├── public
│   │   │   └── src
│   │   │       ├── assets
│   │   │       └── lib
│   │   ├── template-svelte-ts
│   │   │   ├── public
│   │   │   └── src
│   │   │       ├── assets
│   │   │       └── lib
│   │   ├── template-vanilla
│   │   ├── template-vanilla-ts
│   │   │   └── src
│   │   ├── template-vue
│   │   │   ├── public
│   │   │   └── src
│   │   │       ├── assets
│   │   │       └── components
│   │   └── template-vue-ts
│   │       ├── public
│   │       └── src
│   │           ├── assets
│   │           └── components
│   ├── playground
│   │   └── (※省略)
│   ├── plugin-legacy
│   ├── plugin-react
│   │   ├── dist
│   │   └── src
│   │       └── jsx-runtime
│   ├── plugin-vue
│   │   ├── dist
│   │   └── src
│   │       └── utils
│   ├── plugin-vue-jsx
│   └── vite
│       ├── bin
│       ├── dist
│       │   ├── client
│       │   └── node
│       │       └── chunks
│       ├── scripts
│       ├── src
│       │   ├── client
│       │   └── node
│       │       ├── __tests__
│       │       │   ├── packages
│       │       │   │   ├── name
│       │       │   │   └── noname
│       │       │   └── plugins
│       │       ├── optimizer
│       │       ├── plugins
│       │       ├── server
│       │       │   ├── __tests__
│       │       │   │   └── fixtures
│       │       │   │       ├── lerna
│       │       │   │       │   └── nested
│       │       │   │       ├── none
│       │       │   │       │   └── nested
│       │       │   │       ├── pnpm
│       │       │   │       │   └── nested
│       │       │   │       └── yarn
│       │       │   │           └── nested
│       │       │   └── middlewares
│       │       └── ssr
│       │           └── __tests__
│       └── types
└── scripts
  • そこまで階層が深いわけでもなく、わりとシンプルなディレクトリ構造な印象
  • create-vite vite の2つがコアって感じ

テストを動かしてみる

pnpm i
pnpm test
  • 普通に大量に落ちる。なんでや!
  • Target page, context or browser has been closed
  • https://github.com/vitejs/vite/issues/4543 1回ビルドしないとダメぽい
  • pnpm build 実行 → まだ落ちる

Since Jest will attempt to run tests in parallel, if your machine has many cores this may cause flaky test failures with multiple Playwright instances running at the same time. You can force the tests to run in series with pnpm run test-serve -- --runInBand.

  • らしいので、 pnpm run test-serve -- --runInBand を試したところパスした

とりあえずディレクトリを眺めてテストを通すところまでやった。

最初に全ファイル出力したときは「おおぅ...」となったが、playground系のコードを省いたらわりとなんとかなる気がしてきた。

次→ルートにある各種ファイルを見てみる