NextJSを中心に向けられたモノレポの概念、ヒント、トリック
モノレポのハウトス。モノレポスは初めてですか?このFAQを確認してください。この例は、A / TypeScript Path Airasesアプローチを備えたTurborepoとYarn 4によって管理されています。する唯一の方法ではありません。
に役立ちます
あなたがあなたの会社で私のOSSの仕事を楽しんでいるなら、私はスポンサーシップ、コーヒー、または落とした星に本当に感謝しています。それは私にそれを次のレベルに改善するためのもう少し時間を与えてくれます。
| ジェットブレイン | Embie.be | ヴェルセル |
corepack enable
yarn install .
├── apps
│ ├── nextjs-app (i18n, ssr, api, vitest)
│ └── vite-app
└── packages
├── common-i18n (locales...)
├── core-lib
├── db-main-prisma
├── eslint-config-bases (to shared eslint configs)
└── ui-lib (emotion, storybook)
アプリはアプリに依存してはならず、パッケージに依存することができます
アプリはパッケージに依存し、パッケージはお互いに依存する可能性があります...
.
├── apps
│ ├── vite-app (Vite app as an example)
│ │ ├── src/
│ │ ├── package.json (define package workspace:package deps)
│ │ └── tsconfig.json (define path to packages)
│ │
│ └── nextjs-app (NextJS app with api-routes)
│ ├── e2e/ (E2E tests with playwright)
│ ├── public/
│ ├── src/
│ │ └── pages/api (api routes)
│ ├── CHANGELOG.md
│ ├── next.config.mjs
│ ├── package.json (define package workspace:package deps)
│ ├── tsconfig.json (define path to packages)
│ └── vitest.config.ts
│
├── packages
│ ├── core-lib (basic ts libs)
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── db-main-prisma (basic db layer with prisma)
│ │ ├── e2e/ (E2E tests)
│ │ ├── prisma/
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── eslint-config-bases
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ └── ui-lib (basic design-system in react)
│ ├── src/
│ ├── CHANGELOG.md
│ ├── package.json
│ └── tsconfig.json
│
├── static (no code: images, json, locales,...)
│ ├── assets
│ └── locales
├── docker (docker...)
│ ├── .dockerignore
│ ├── docker-compose.yml (compose specific for nextjs-app)
│ ├── docker-compose.db.yml (general services like postgresql...)
│ └── Dockerfile (multistage build for nextjs-app)
├── .yarnrc.yml
├── package.json (the workspace config)
└── tsconfig.base.json (base typescript config)
{
"name" : "nextjs-monorepo-example" ,
// Set the directories where your apps, packages will be placed
"workspaces" : [ "apps/*" , "packages/*" ] ,
//...
}パッケージマネージャーは、それらのディレクトリをスキャンし、子供のpackage.jsonを探します。それらのコンテンツは、ワークスペーストポロジ(アプリ、LIBS、依存関係...)を定義するために使用されます。
パッケージの名前で./packages/ディレクトリにフォルダーを作成します。
mkdir packages/magnificent-poney
mkdir packages/magnificent-poney/src
cd packages/magnificent-poneyパッケージの名前でpackage.jsonを初期化します。
yarn init入力するよりも、./packages/ui-lib/package.jsonを実用的な例として取得し、その値を編集することを好みます。
{
"name" : "@your-org/magnificent-poney" ,
"version" : "0.0.0" ,
"private" : true ,
"scripts" : {
"clean" : "rimraf ./tsconfig.tsbuildinfo" ,
"lint" : "eslint . --ext .ts,.tsx,.js,.jsx" ,
"typecheck" : "tsc --project ./tsconfig.json --noEmit" ,
"test" : "run-s 'test:*'" ,
"test:unit" : "echo "No tests yet"" ,
"fix:staged-files" : "lint-staged --allow-empty" ,
"fix:all-files" : "eslint . --ext .ts,.tsx,.js,.jsx --fix" ,
} ,
"devDependencies" : {
"@your-org/eslint-config-bases" : "workspace:^" ,
} ,
}まず、アプリpackage.jsonにパッケージを追加します。推奨される方法は、YARNとPNPMでサポートされているワークスペースプロトコルを使用することです。
cd apps/my-app
yarn add @your-org/magnificent-poney@ ' workspace:^ 'インスピレーションは、Apps/nextjs-app/package.jsonで見つけることができます。
{
"name" : "my-app" ,
"dependencies" : {
"@your-org/magnificient-poney" : "workspace:^" ,
} ,
} 次に、App tsconfig.jsonにタイプスクリプトパスエイリアスを追加します。これにより、直接インポートできます(ビルドは必要ありません)
インスピレーションは、Apps/nextjs-app/tsconfig.jsonで見つけることができます。
{
"compilerOptions" : {
"baseUrl" : "./src" ,
"paths" : {
// regular app aliases
"@/components/*" : [ "./components/*" ] ,
// packages aliases, relative to app_directory/baseUrl
"@your-org/magnificent-poney/*" : [
"../../../packages/magnificent-poney/src/*" ,
] ,
"@your-org/magnificent-poney" : [
"../../../packages/magnificent-poney/src/index" ,
] ,
} ,
} ,
}PS:
- グラフの依存関係を厳格に保つために、グローバルtsonfig.base.jsonにエイリアスを設定しようとしないでください。
@your-org/magnificent-poney/*のスターは、サブフォルダーをインポートできます。バレルファイル(index.ts)を使用すると、星付きのエイリアスを削除できます。
next.config.mjsを編集し、Experiment.Externaldirオプションを有効にします。フィードバックはこちら。
const nextConfig = {
experimental : {
externalDir : true ,
} ,
} ;古いNextJSバージョンを使用していて、実験フラグがない場合は、WebPack設定をオーバーライドするだけです。
const nextConfig = {
webpack : ( config , { defaultLoaders } ) => {
// Will allow transpilation of shared packages through tsonfig paths
// @link https://github.com/vercel/next.js/pull/13542
const resolvedBaseUrl = path . resolve ( config . context , "../../" ) ;
config . module . rules = [
... config . module . rules ,
{
test : / .(tsx|ts|js|jsx|json)$ / ,
include : [ resolvedBaseUrl ] ,
use : defaultLoaders . babel ,
exclude : ( excludePath ) => {
return / node_modules / . test ( excludePath ) ;
} ,
} ,
] ;
return config ;
} ,
} ;PS:共有パッケージがSCSSバンドラーを使用している場合...カスタムWebパック構成が必要になるか、次の輸送モジュールを使用するか、以下のFAQを参照してください。
パッケージはアプリにリンクされ、通常のパッケージのようにインポートするだけです。 import { poney } from '@your-org/magnificent-poney' 。
オプション
Monorepo以外でいくつかのパッケージを共有する必要がある場合は、それらをNPMまたはプライベートリポジトリに公開できます。 Microbundleに基づく例は、各パッケージに存在します。バージョン化と公開は、Atlassian/Changesetで行うことができ、タイピングとして簡単です。
$ yarn g:changeset手順に従ってください...そして、Changesetファイルをコミットします。 「バージョンパッケージ」P/Rは、CIチェック後に表示されます。マージすると、GitHubアクションは、結果のSemverバージョンでパッケージを公開し、Changelogを生成します。
PS:
- 公開する必要がない場合でも、Changesetはアプリ用の自動変更ログを維持できます。ニース !
- いくつかのパッケージの自動公開を無効にするには、Package.jsonで
"private": "true"を設定します。- 動作を調整したい場合は、.changeset/config.jsonを参照してください。
一部の便利なスクリプトは、このレポの任意のフォルダーで実行でき、パッケージやアプリで定義されたカウンターパートを呼び出します。
| 名前 | 説明 |
|---|---|
yarn g:changeset | 新しいバージョンを宣言するには、変更セットを追加します |
yarn g:codegen | すべてのワークスペースでコードゲンを実行します |
yarn g:typecheck | すべてのワークスペースでタイプチェックを実行します |
yarn g:lint | すべてのワークスペースにリナーの問題を表示します |
yarn g:lint --fix | すべてのワークスペースでリナーオートフィックスを実行しようとします |
yarn g:lint-styles | すべてのワークスペースにCSS StyleLintの問題を表示します |
yarn g:lint-styles --fix | すべてのワークスペースでStylelint Auto-Fixの問題を実行しようとします |
yarn g:test | すべてのワークスペースでユニットとE2Eテストを実行します |
yarn g:test-unit | すべてのワークスペースでユニットテストを実行します |
yarn g:test-e2e | すべてのワークスペースでE2Eテストを実行します |
yarn g:build | すべてのワークスペースでビルドを実行します |
yarn g:clean | すべてのワークスペースにクリーンビルドがあります |
yarn g:check-dist | Build DistファイルがES2017を渡すことを確認します( g:build )。 |
yarn g:check-size | ブラウザdistファイルがサイズ制限内にあることを確認します( g:build )。 |
yarn clean:global-cache | クリーンツーリングキャッシュ(eslint、jest ...) |
yarn deps:check --dep dev | グローバルにアップグレードできるパッケージを印刷します(.ncurc.ymlも参照) |
yarn deps:update --dep dev | 可能な更新を適用します( yarn install && yarn dedupe後) |
yarn install:playwright | E2E用のPlaywrightをインストールします |
yarn dedupe | ロックファイルの組み込み糸の重複 |
使用する理由
:スクリプト名をプレフィックスするには? Yarn 3+では便利です。モノレポの任意のフォルダーからこれらのスクリプトを呼び出すことができます。g:global:。 root package.jsonの完全なリストを参照してください。
Global Commands yarn deps:check and yarn deps:update Monorepo全体で同じバージョンを維持するのに役立ちます。それらは、優れたNPMチェックアップデートに基づいています(オプションを参照してください。IE: yarn check:deps -t minor )。
yarn deps:update、yarn installが必要です。 Yarn.Lockに重複があることを防ぐために、yarn dedupe --checkとyarn dedupe実行できます。複製チェックは、GitHubアクションの例で実施されています。
./apps/nextjs-app/.eslintrc.jsおよびslint-config-baseの例を参照してください。
.huskyフォルダーコンテンツを確認して、どのフックが有効になっているかを確認してください。 Lint-Stagedは、LintとPrettierがコミットおよび/またはプッシュ時に自動的に適用されることを保証するために使用されます。
テストは、アプリに応じてTS-JestまたはVitestに依存しています。すべてのセットアップは、タイプスクリプトパスエイリアスをサポートしています。 React-Testing-Libraryは、Reactが関与するたびに有効になります。
構成は、各アプリ/パッケージのルートフォルダーに存在します。例として、参照してください
.github/ワークフローにGithubアクションのワークフローの例を見つけることができます。デフォルトでは、彼らはそれを確保します
これらの各ステップはオプトアウトできます。
適切なパフォーマンスを確保するために、これらの機能は例のアクションに存在します。
パッケージのキャッシュ(node_modules ...) - 約25秒をインストールします
NextJS以前のビルドのキャッシュ- 20代前後
アクションパスを使用して変更されたときにトリガーされます。
paths: - "apps/nextjs-app/**" - "packages/**" - "package.json" - "tsconfig.base.json" - "yarn.lock" - ".yarnrc.yml" - ".github/workflows/**" - ".eslintrc.base.json" - ".eslintignore"
ESLINTプラグインでは、 eslint.workingDirectories設定が設定される必要があります。
"eslint.workingDirectories": [
{
"pattern": "./apps/*/"
},
{
"pattern": "./packages/*/"
}
],
詳細については、こちらをご覧ください
Vercel Support Supportネイティブにモノレポスをご覧ください。VercelMonorepo-Deployドキュメントを参照してください。
Docker画像を構築するための基本的な例があります。DockerDocをお読みください。
netlify、aws-amplify、k8s-docker、serverless-nextJSレシピが将来追加される可能性があります。 PRも大歓迎です。
アプリの依存関係と開発者は、正確なバージョンに固定されています。 Packages Depsは、Semver互換のものを使用します。この変更の詳細については、こちらとrenovabot.json5構成ファイルはこちらをご覧ください。
DEPSを最新の状態に保つために、 yarn deps:check && yarn deps:update Scriptsまたは /またはRenovateBotを使用してください。
Yarn CLIを介してDEPを追加すると(つまり、YARNが何かを追加)、
defaultSemverRangePrefix: ""in yarnrc.ymlを設定して、保存exactの動作を自動的に設定することができます。ただし、これによりパッケージ/*のデフォルトが作成されます。yarn add something --exactケースごとに除外してください。