👋

Lerna + viteで他パッケージの依存関係をうまく解決できないときの確認ポイント

2021/06/16に公開

Lernaを使ったmonorepo内でviteを使ったときに少し詰まった点があったので備忘録として残しておきます。vite v2.3 時点の情報であることにご注意ください。

例えば、このようなmonorepo構成で3つのパッケージを管理しているとします。

├── lerna.json
└── packages
    ├── module-a # ①
    ├── module-b # ②
    └── main-app # ③
        └── vite.config.ts

この中の③main-appから他の2つのパッケージ(①②)をimportしているイメージです。

しかし、実際にvitevite buildといったコマンドで動かしてみるとこれらのパッケージの依存関係をうまく解決できませんでした。

vite.configでresolve.aliasを設定して解決

調べてみると該当の問題についてのIssueがありました。

https://github.com/vitejs/vite/issues/1491

この中でEvan Youさんが以下のようにコメントしています。

  1. Make sure you have your local linked packages also listed in your example (vite) package's dependencies list
  2. If listed, Vite 2 will auto detect linked packages and you shouldn't need to use optimizeDeps.link
  3. If your ui module packages define entry points to built files in their package.json, you will need to configure an alias in the example project to redirect to their source entry instead.

このうちの(3)が今回の問題の原因でした。
importしているパッケージのpackage.jsonでは"main": "dist/index.js"というようにビルド後のファイルをentrypointとして指定しており、その場合はvite.configのresolve.aliasにソース側のentrypointを指定する必要があるようです。

module-a
packages
  └── module-a
  ├── dist
  │   └── index.js # package.jsonのmain
  └── src
      └── index.ts # 👈 こっちをvite.configのaliasに指定する
vite.config.ts
 import { defineConfig } from 'vite';
 
 export default defineConfig({
   ...
+  resolve: {
+    alias: {
+      'module-a': 'module-a/src/index.ts',
+      'module-b': 'module-b/src/index.ts',
+    },
+  }

これでパッケージの依存関係が問題なく解決されるようになりました。このあたりのvite(というかRollup?)の仕組みについてちゃんと理解できていないので、今度ちゃんと探ってみようと思います。

Discussion