Turborepo & SvelteKit Starter の モノレポ構成を確認する
こちらのページの手順に従ってプロジェクトを作成する
作成したプロジェクトは IntelliJ IDEAから利用したいので、IdeaProjects
ディレクトリに移動してから次のコマンドを実行する
pnpm dlx create-turbo@latest -e with-svelte
- プロジェクト名(ディレクトリ名) -> デフォルトの ./my-turborepo のままにした
- 利用する Package Manager -> pnpm workspace
あとはこんな感じでプロジェクトが作成される
作成されたプロジェクトのうち、apps/docs
と apps/web
は 異なるアプリだが 設定内容が同じなので apps/docs
の方だけ見ていくことにする
rootで確認しておきたいのは package.json
eslintrc.cjs
.prettierrc
の3つかな
turborepo や workspace 自体は標準的な設定なので
rootの package.json では、eslint
と prettier
の実行に関係する依存関係をインストールしている
scripts を読むと prettierは rootから配下サブプロジェクト全体を一気に実行するみたいなので インストールが必要なのはわかるけど、lint は turboRepoを使っているから、rootじゃなくても良い気はするけど
{
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"lint": "turbo run lint",
"format": "prettier --write ."
},
"devDependencies": {
"eslint": "^8.56.0",
"@repo/eslint-config": "workspace:*",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"turbo": "latest"
},
"packageManager": "pnpm@8.9.0",
"engines": {
"node": ">=18"
}
}
packages/ui
の package.json を 見ると eslint に関する 依存関係は 同じ packages/config-eslint
だけを追加している。なのに scripts で、lintが実行できている。
また、packages/config-eslint
の方も index.js で定義している lintの設定で使う依存関係しか追加していない
apps/docs
には eslint
などの依存関係が追加されていたけど、削除して実行してみたところ lintが実行できたので、eslintrs.cjs で定義している依存関係だけがあれば良さそう
同じ理由で、apps/docs
の prettier
を依存関係から削除しても prettierは正常に動作できた。さらに .prettierrc に prettier-plugin-svelte
が使われているけどこれも apps/docs
から削除しても prettier は正常に動作した。 rootに prettier-plugin-svelte
があれば大丈夫っぽいな
root の .eslintrc.cjs
は次の通り
module.exports = {
root: true,
// This tells ESLint to load the config from the package `eslint-config-custom`
extends: ['custom']
};
プロジェクトの root であることを定義する root: true
を指定している他、extends: ['custom']
で カスタム設定を参照しているが、この設定ファイルは実際は存在しないので、恐らく実際には利用されていない
この .eslintrc.cjs を削除しても各プロジェクトの lint は正常に動作されることを確認した
このプロジェクトのESLint設定は packages/config-eslint/index.js
が請け負っている。rootではサブプロジェクトで eslint を実行するための依存関係をインストールしている
設定内容は rootを含む全サブプロジェクトを網羅する形の内容になっていた
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended',
'prettier',
'turbo'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
extraFileExtensions: ['.svelte']
},
env: {
browser: true,
es2017: true,
node: true
},
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser'
}
}
]
};
apps/*
と packages/*
の各サブプロジェクトでは、次のように この eslintの設定を取り込み検証を実施している
module.exports = {
extends: ['@repo/eslint-config/index.js']
};
消しちゃったけど、rootの eslintrc.cjs extends: ['custom']
の custom
は、eslint-config-*
の *
に相当するpackageらしい。
つまり、packages/eslint-config-custom
というサブパッケージを用意すればそれを参照する模様。(今回は作っていないので結局 参照されるわけではない)
この辺は TurboRepoの仕組みっぽい
root の .prettierrc
は以下の通り
prettier の 実行は root から行い、全サブプロジェクトのファイルに対して適用される
{
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100
}
例えば apps/docs
には 次のような .prettierrc があり このサブプロジェクト配下では rootの設定が上書きされる
rootでは useTabs
は指定されていないので default の false になるのだが、apps/docs では タブが使われるようになっていた
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"plugins": ["prettier-plugin-svelte"],
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
}
余談だけど、IntelliJ IDEAの prittierの機能 で、.svelte
ファイルをフォーマットする scriptタグが不正な形に変換されるバグがあるんだけど、ここで rootにインストールした prettier パッケージを手動設定することで正しくフォーマット変換されるみたい。使いながら様子を見ないとなんとも言えないけど
tsconfigも 管理しようと思ってたけど、サンプルだと apps/*
にしか tsconfig.json がなくて、さらにSveltekitだから "extends": "./.svelte-kit/tsconfig.json",
になってて あまり意味が無いので今回は行わない
なお、作るときはこの辺も参考にする
ところで、packages/ui
プロジェクトでは、エントリファイルとして index.ts
があるんだけど、このプロジェクトには tsconfig.json もないし、typescript も 依存関係に追加していない
これってこのプロジェクト単体ではビルドもコンパイル(トランスパイル)もしない前提だからなんだろうな
{
"name": "@repo/ui",
"version": "0.0.0",
"type": "module",
"module": "index.ts",
"main": "index.ts",
"exports": {
".": {
"types": "./index.ts",
"svelte": "./index.ts"
}
},
"scripts": {
"lint": "eslint ."
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",
"svelte": "^4.2.8"
}
}
IntelliJ IDEA で、このプロジェクトに typescriptで書いたコードちゃんと認識してくれるんだな。
Settings > Languages & Frameworks > Typescript で パッケージを指定しているからなんだろうな。
今は、apps/docs
にインストールした パッケージを見ているけど rootとかベースになるプロジェクトを指してあげたほうが良さそう
IDE (IntelliJ)でも参照するためにrootにこんな感じで typescriptの設定を行うと良いかな? CompilerOptionsは、Viteのビルドでトランスパイルを行うことを想定した設定にはした方が良さそう
-
packages/config-ts
みたいな tsconfig.json 管理プロジェクトを置く- 他のプロジェクトもここの設定ファイルを参照する
- Workspaceのroot に typescript パッケージ をインストールする
- root に tsconfig.json を追加し、config-ts パッケージの 設定ファイルを継承する
- IDEの Typescriptパスを root の typescript パッケージにする
- 必要に応じて、root の tsconfig.json に paths も指定する
- "必要に応じて"とは、IDEが内部パッケージの参照エラーを出す場合という意味
-
references (Project Referemce)
は定義しなくて良いと考えてる-
apps/*
では個別に tsconfig.json, tsconfig.node.json を管理して vite でビルドするため - root にあるのは あくまでも IDE用の位置付けとし、アプリのビルド時のトランスパイルとは切り分ける
-
今回の調査と直接関係ないんだけど、rootにインストールしたパッケージは サブプロジェクトでも利用できるようになるんだな
例えば、svelte とか vite, typescript なんかも rootにインストールしておけば、個々の package.json で定義しなくても使えるようになる
パッケージのバージョンを揃える必要がある時なんかはこれで良い気がする