Konsep Monorepo, Tips, dan Trik Berorientasi pada NextJS
Howtos untuk monorepo. Baru di Monorepos? Periksa FAQ ini. Contoh ini dikelola oleh Turborepo dan Yarn 4 dengan pendekatan A alias A / TypeScript. Bukan satu -satunya cara untuk melakukannya.
Berguna untuk
Jika Anda menikmati beberapa pekerjaan OSS saya di perusahaan Anda, saya sangat menghargai sponsor, kopi, atau bintang yang dijatuhkan. Itu memberi saya lebih banyak waktu untuk memperbaikinya ke tingkat berikutnya.
| JetBrains | Embie.be | Vercel |
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)
Aplikasi tidak boleh bergantung pada aplikasi, mereka dapat bergantung pada paket
Aplikasi dapat bergantung pada paket, paket dapat saling bergantung ...
.
├── 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/*" ] ,
//...
} Manajer paket akan memindai direktori tersebut dan mencari package.json anak -anak. Konten mereka digunakan untuk mendefinisikan topologi ruang kerja (aplikasi, LIBS, dependensi ...).
Buat folder di ./packages/ direktori dengan nama paket Anda.
mkdir packages/magnificent-poney
mkdir packages/magnificent-poney/src
cd packages/magnificent-poneyInisialisasi paket.json dengan nama paket Anda.
Daripada mengetikkan
yarn init, lebih suka mengambil ./packages/ui-lib/package.json sebagai contoh yang berfungsi dan mengedit nilainya.
{
"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:^" ,
} ,
}Pertama tambahkan paket ke paket app.json. Cara yang disarankan adalah dengan menggunakan protokol ruang kerja yang didukung oleh benang dan PNPM.
cd apps/my-app
yarn add @your-org/magnificent-poney@ ' workspace:^ 'Inspirasi dapat ditemukan di Apps/NextJs-App/Package.json.
{
"name" : "my-app" ,
"dependencies" : {
"@your-org/magnificient-poney" : "workspace:^" ,
} ,
} Kemudian tambahkan Alias Path TypeScript di aplikasi tsconfig.json. Ini akan memungkinkan Anda untuk mengimpornya secara langsung (tidak perlu dibangun)
Inspirasi dapat ditemukan di 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:
- Jangan mencoba mengatur alias di tsonfig.base.json global untuk tetap ketat dengan ketergantungan grafik.
- Bintang di
@your-org/magnificent-poney/*memungkinkan Anda untuk mengimpor subfolder. Jika Anda menggunakan file barel (index.ts), alias dengan bintang dapat dihapus.
Edit next.config.mjs Anda dan aktifkan opsi eksperimental.externaldir. Umpan balik di sini.
const nextConfig = {
experimental : {
externalDir : true ,
} ,
} ;Jika Anda menggunakan versi NextJS yang lebih lama dan tidak memiliki bendera eksperimental, Anda dapat mengganti konfigurasi webpack Anda.
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: Jika paket bersama Anda memanfaatkan Bundler SCSS ... konfigurasi webpack khusus akan diperlukan atau menggunakan modul transpile berikutnya, lihat FAQ di bawah ini.
Paket sekarang ditautkan ke aplikasi Anda, cukup impornya seperti paket reguler: import { poney } from '@your-org/magnificent-poney' .
Opsional
Jika Anda perlu berbagi beberapa paket di luar monorepo, Anda dapat menerbitkannya ke NPM atau repositori pribadi. Contoh berdasarkan microbundle ada di setiap paket. Versi dan penerbitan dapat dilakukan dengan Atlassian/Changeset, dan sederhana seperti mengetik:
$ yarn g:changesetIkuti instruksi ... dan lakukan file Changeset. "Paket Versi" P/R akan muncul setelah pemeriksaan CI. Saat menggabungkannya, tindakan GitHub akan menerbitkan paket dengan versi SEMVER yang dihasilkan dan menghasilkan changelog untuk Anda.
PS:
- Bahkan jika Anda tidak perlu mempublikasikan, Changeset dapat mempertahankan changelog otomatis untuk aplikasi Anda. Bagus !
- Untuk menonaktifkan penerbitan otomatis beberapa paket, cukup atur
"private": "true"di paket mereka.json.- Ingin menyetel perilaku, lihat .changeset/config.json.
Beberapa skrip kenyamanan dapat dijalankan di folder mana pun dari repo ini dan akan memanggil rekan -rekan mereka yang ditentukan dalam paket dan aplikasi.
| Nama | Keterangan |
|---|---|
yarn g:changeset | Tambahkan perubahan untuk mendeklarasikan versi baru |
yarn g:codegen | Jalankan codegen di semua ruang kerja |
yarn g:typecheck | Jalankan typecheck di semua ruang kerja |
yarn g:lint | Tampilkan masalah linter di semua ruang kerja |
yarn g:lint --fix | Mencoba menjalankan linter fix otomatis di semua ruang kerja |
yarn g:lint-styles | Tampilkan masalah CSS Stylelint di semua ruang kerja |
yarn g:lint-styles --fix | Mencoba menjalankan masalah perbaikan otomatis stylelint di semua ruang kerja |
yarn g:test | Jalankan unit dan tes E2E di semua ruang kerja |
yarn g:test-unit | Jalankan tes unit di semua ruang kerja |
yarn g:test-e2e | Jalankan tes E2E di semua ruang kerja |
yarn g:build | Jalankan build di semua ruang kerja |
yarn g:clean | Bangunan bersih di semua ruang kerja |
yarn g:check-dist | Pastikan Bangun File Dist melewati ES2017 (Jalankan g:build First). |
yarn g:check-size | Pastikan file Dist Browser berada dalam batas ukuran (jalankan g:build terlebih dahulu). |
yarn clean:global-cache | Cache Tooling Bersih (Eslint, Jest ...) |
yarn deps:check --dep dev | Akan mencetak paket apa yang dapat ditingkatkan secara global (lihat juga .ncurc.yml) |
yarn deps:update --dep dev | Terapkan Pembaruan yang Mungkin (Jalankan yarn install && yarn dedupe Setelah) |
yarn install:playwright | Instal Playwright untuk E2E |
yarn dedupe | Deduplikasi benang bawaan dari file kunci |
Mengapa Menggunakan
:UNTUK MEMILIKI Nama skrip? Ini nyaman dalam benang 3+, kita dapat memanggil skrip -skrip itu dari folder mana pun di monorepo.g:adalah jalan pintas untukglobal:. Lihat daftar lengkap di root package.json.
Perintah Global yarn deps:check dan yarn deps:update akan membantu mempertahankan versi yang sama di seluruh monorepo. Mereka didasarkan pada pembaruan NPM-check yang sangat baik (lihat opsi, yaitu: yarn check:deps -t minor ).
Setelah menjalankan
yarn deps:update, diperlukanyarn install. Untuk mencegah duplikatyarn dedupe --checkyarn dedupe. Pemeriksaan duplikat ditegakkan dalam contoh tindakan github.
Lihat contoh di ./apps/nextjs-app/.eslintrc.js dan Eslint-Config-Base kami.
Periksa konten folder .husky untuk melihat kait apa yang diaktifkan. Lint-Stage digunakan untuk menjamin bahwa serat dan lebih cantik diterapkan secara otomatis pada komit dan/atau dorongan.
Tes bergantung pada TS-Jest atau Vitest tergantung pada aplikasinya. Semua pengaturan mendukung alias Jalur TypeScript. React-testing-library diaktifkan setiap kali bereaksi terlibat.
Konfigurasi tinggal di folder root dari setiap aplikasi/paket. Sebagai contoh lihat
Anda akan menemukan beberapa contoh alur kerja untuk tindakan github di .github/alur kerja. Secara default, mereka akan memastikan bahwa
Masing-masing langkah tersebut dapat dipilih.
Untuk memastikan kinerja yang layak, fitur -fitur tersebut hadir dalam tindakan contoh:
Caching of Packages (node_modules ...) - Instal sekitar 25s
Caching of NextJS Build Sebelumnya - Dibangun sekitar 20 -an
Dipicu saat diubah menggunakan jalur tindakan, yaitu:
paths: - "apps/nextjs-app/**" - "packages/**" - "package.json" - "tsconfig.base.json" - "yarn.lock" - ".yarnrc.yml" - ".github/workflows/**" - ".eslintrc.base.json" - ".eslintignore"
Plugin Eslint mensyaratkan bahwa pengaturan eslint.workingDirectories diatur:
"eslint.workingDirectories": [
{
"pattern": "./apps/*/"
},
{
"pattern": "./packages/*/"
}
],
Info lebih lanjut di sini
Dukungan Vercel secara asli Monorepos, lihat dokumen Vercel-Monorepo-Deploy.
Ada contoh dasar untuk membangun gambar Docker, baca dokumen Docker.
Netlify, AWS-Amplify, K8S-Docker, Resep Serverless-NextJS mungkin ditambahkan di masa mendatang. PR juga disambut.
Ketergantungan aplikasi dan ketergantungan devdependensi disematkan ke versi yang tepat. Paket Deps akan menggunakan yang kompatibel dengan Semver. Untuk info lebih lanjut tentang perubahan ini, lihat alasan di sini dan file konfigurasi renovabot.json5 kami.
Untuk membantu menjaga DEP tetap terkini, lihat yarn deps:check && yarn deps:update skrip dan / atau gunakan RenovateBot.
Saat menambahkan DEP melalui benang CLI (yaitu: benang menambahkan sesuatu), dimungkinkan untuk mengatur perilaku save-exact secara otomatis dengan mengatur
defaultSemverRangePrefix: ""di yarnrc.yml. Tapi ini akan membuat default untuk paket/* juga. Lebih baik menanganiyarn add something --exactberdasarkan per kasus.