内部パッケージ
内部パッケージは、モノレポの内部でのみ使用されることを意図したパッケージです。クローズドソースのモノレポでアプリ間でコードを共有するのに非常に便利です。
内部パッケージは簡単に作成でき、最終的にnpm
に公開したい場合は、外部パッケージに変えることができます。
パッケージを内部にする理由
外部パッケージは、パッケージレジストリに配置する前に、ファイルをバンドラーに通します。つまり、処理するために多くのツールが必要になります。
- バンドラー:パッケージをビルドするため
- バージョニング:バージョニングとリリースを支援するため
- 公開:パッケージを公開するため
これらのファイルをローカルで使用する場合は、以下も必要になります
- 開発スクリプト:ファイルが変更されたときにローカルでパッケージをバンドルするため
内部パッケージは公開されないため、これらの手順をすべてスキップできます。パッケージを自分でバンドルする代わりに、パッケージをインポートするアプリにバンドルさせます。
これは複雑に聞こえるかもしれませんが、設定は非常に簡単です。
最初の内部パッケージ
モノレポ内に共有math-helpers
パッケージを作成します。
1. モノレポを作成する
既存のモノレポがない場合は、ガイドを使用して作成してください。
2. 新しいパッケージを作成する
/packages
内に、math-helpers
という名前の新しいフォルダーを作成します。
mkdir packages/math-helpers
package.json
を作成します
{
"name": "math-helpers",
"version": "0.0.1",
"dependencies": {
// Use whatever version of TypeScript you're using
"typescript": "latest"
}
}
src
フォルダーを作成し、packages/math-helpers/src/index.ts
に TypeScript ファイルを追加します。
export const add = (a: number, b: number) => {
return a + b;
};
export const subtract = (a: number, b: number) => {
return a - b;
};
また、packages/math-helpers/tsconfig.json
にtsconfig.json
を追加する必要があります
{
"compilerOptions": {
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"preserveWatchOutput": true,
"skipLibCheck": true,
"noEmit": true,
"strict": true
},
"exclude": ["node_modules"]
}
素晴らしい!これで、内部パッケージに必要なファイルがすべて揃いました。
3. パッケージをインポートする
次に、パッケージをインポートして何が起こるかを確認します。アプリのいずれかに移動し、その package.json の依存関係にmath-helpers
を追加します
{
"dependencies": {
"math-helpers": "*"
}
}
ルートからすべてのパッケージをインストールして、依存関係が機能することを確認します。
次に、アプリのソースファイルの1つに、math-helpers
からのインポートを追加します。
+ import { add } from "math-helpers";
+ add(1, 2);
おそらくエラーが表示されるでしょう!
Cannot find module 'math-helpers' or its corresponding type declarations.
それは、ステップを一つ飛ばしているからです。私たちは math-helpers/package.json
に、パッケージのエントリーポイントが何かを伝えていません。
4. exports
を修正する
packages/math-helpers/package.json
に戻り、exports
フィールドを追加します。
{
"name": "math-helpers",
"exports": {
".": "./src/index.ts"
},
"dependencies": {
"typescript": "latest"
}
}
これで、math-helpers
モジュールをインポートするものはすべて、src/index.ts
ファイルに直接ポイントされるようになります。それがインポートされるファイルです。
apps/web/pages/index.tsx
に戻ります。エラーは消えているはずです!
5. アプリを実行してみる
次に、アプリの開発用スクリプトを実行してみましょう。デフォルトの turborepo では、これは以下のように簡単です。
turbo dev
起動すると、Webブラウザにエラーが表示されるでしょう。
../../packages/math-helpers/src/index.ts
Module parse failed: Unexpected token (1:21)
You may need an appropriate loader to handle this file type,
currently no loaders are configured to process this file.
See https://webpack.dokyumento.jp/concepts#loaders
> export const add = (a: number, b: number) => {
| return a + b;
| };
これは、バンドルされていないファイルを Next.js アプリにインポートしようとしたときに起こります。
解決策は簡単です。インポートする特定のパッケージのファイルをバンドルするように Next.js に指示する必要があります。
6. アプリの設定
next.config.js
の transpilePackages
を使用してそれを行うことができます (v13.1 以降が必要)。
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['math-helpers'],
};
module.exports = nextConfig;
開発用スクリプトを再起動し、ブラウザに移動します。
エラーは消えました!
7. まとめ
これで、math-helpers
パッケージに任意の量のコードを追加し、モノレポ内の任意のアプリで使用できるようになりました。パッケージをビルドする必要さえありません。そのまま動作します。
このパターンは、チーム間で簡単に共有できるコードを作成するのに非常に強力です。
クイックリファレンス
クイックリファレンス - 新しい内部パッケージの作成
packages/<folder>
に新しいフォルダを作成します。package.json
を追加し、name
とtypes
をsrc/index.ts
(またはsrc/index.tsx
) にポイントするようにします。- 少なくとも1つの名前付きエクスポートを含む
src/index.tsx
を追加します。 - ルートからパッケージをインストールします。
クイックリファレンス - 内部パッケージのインポート
- 正しくインポートしているか確認します。
- アプリがそれをトランスパイルするように設定しているか確認します。