Monorepo 개념, 팁 및 요령은 Nextjs를 중심으로합니다
Monorepo의 Howtos. Monorepos를 처음 접했습니까? 이 FAQ를 확인하십시오. 이 예제는 Turborepo와 Yarn 4에서 관리합니다. 할 수있는 유일한 방법은 아닙니다.
유용합니다
당신이 당신의 회사에서 나의 OSS 일을 즐기고 있다면, 후원, 커피 또는 떨어진 별에 감사드립니다. 그것은 다음 단계로 개선 할 시간을 더합니다.
| 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)
앱은 앱에 의존해서는 안되며 패키지에 의존 할 수 있습니다.
앱은 패키지에 따라 다를 수 있으며 패키지는 서로에 따라 다를 수 있습니다 ...
.
├── 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/*" ] ,
//...
} 패키지 관리자는 해당 디렉토리를 스캔하고 Children package.json 찾습니다. 해당 콘텐츠는 작업 공간 토폴로지 (앱, LIB, 종속성 ...)를 정의하는 데 사용됩니다.
패키지 이름으로 ./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:^" ,
} ,
} 그런 다음 앱 tsconfig.json에 TypeScript 경로 별명을 추가하십시오. 이를 통해 직접 가져올 수 있습니다 (빌드 필요 없음)
영감은 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" ,
] ,
} ,
} ,
}추신:
- 그래프 종속성을 엄격하게 유지하려면 Global Tsonfig.base.json에서 별명을 설정하려고하지 마십시오.
@your-org/magnificent-poney/*의 스타를 사용하면 서브 폴더를 가져올 수 있습니다. 배럴 파일 (index.ts)을 사용하는 경우 별이있는 별칭을 제거 할 수 있습니다.
next.config.mjs .config.mjs를 편집하고 실험 .externaldir 옵션을 활성화하십시오. 여기에 피드백.
const nextConfig = {
experimental : {
externalDir : true ,
} ,
} ;이전 NextJS 버전을 사용하고 실험 플래그가없는 경우 웹 팩 구성을 무시할 수 있습니다.
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 ;
} ,
} ;추신 : 공유 패키지가 SCSS Bundler를 사용하는 경우 ... 사용자 정의 웹 팩 구성이 필요하거나 차세대 트랜스 파일 모듈을 사용하십시오. 아래 FAQ를 참조하십시오.
패키지는 이제 앱에 연결되어 있으며 import { poney } from '@your-org/magnificent-poney' 를 일반 패키지처럼 가져옵니다.
선택 과목
Monorepo 외부의 일부 패키지를 공유 해야하는 경우 NPM 또는 개인 리포지토리에 게시 할 수 있습니다. 마이크로 펀들을 기반으로 한 예는 각 패키지에 존재합니다. 버전 작성 및 게시는 Atlassian/Changes 세트를 사용하여 수행 할 수 있으며 입력하는 것이 간단합니다.
$ yarn g:changeset지침을 따르고 변경 사항 파일을 커밋하십시오. CI 점검 후 "버전 패키지"P/R이 나타납니다. 병합 할 때 GitHub 액션은 결과 Semver 버전으로 패키지를 게시하고 ChangElogs를 생성합니다.
추신:
- 게시 할 필요가 없더라도 Changeet은 앱의 자동 변경 사항을 유지할 수 있습니다. 멋진 !
- 일부 패키지의 자동 게시를 비활성화하려면 Package.json에
"private": "true"설정하십시오.- 동작을 조정하려면 .changeset/config.json을 참조하십시오.
일부 편의성 스크립트는이 repo의 모든 폴더에서 실행할 수 있으며 패키지 및 앱으로 정의 된 상대를 호출합니다.
| 이름 | 설명 |
|---|---|
yarn g:changeset | 새 버전을 선언하려면 변경 사항을 추가하십시오 |
yarn g:codegen | 모든 작업 공간에서 CodeGen을 실행하십시오 |
yarn g:typecheck | 모든 작업 공간에서 TypEchecks를 실행하십시오 |
yarn g:lint | 모든 작업 공간에 Linter 문제를 표시합니다 |
yarn g:lint --fix | 모든 작업 공간에서 Linter Auto-Fix를 실행하십시오 |
yarn g:lint-styles | 모든 작업 공간에 CSS 스타일 링트 문제를 표시합니다 |
yarn g:lint-styles --fix | 모든 작업 공간에서 스타일 린트 자동 고정 문제를 실행하십시오 |
yarn g:test | 모든 작업 공간에서 장치 및 E2E 테스트를 실행하십시오 |
yarn g:test-unit | 모든 작업 공간에서 단위 테스트를 실행합니다 |
yarn g:test-e2e | 모든 작업 공간에서 E2E 테스트를 실행하십시오 |
yarn g:build | 모든 작업 공간에서 빌드를 실행하십시오 |
yarn g:clean | Clean은 모든 작업 공간에서 빌드됩니다 |
yarn g:check-dist | 빌드 Dist Files가 ES2017을 통과하는지 확인하십시오 (실행 g:build First). |
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 용 극작가를 설치하십시오 |
yarn dedupe | 자물쇠 파일의 내장 원사 중복 제거 |
사용하는 이유
:스크립트 이름을 접두어로 사용하는 이유는 무엇입니까? Yarn 3+에서는 편리합니다. Monorepo의 모든 폴더에서 해당 스크립트를 호출 할 수 있습니다.g:global:의 바로 가기입니다. Root Package.json의 전체 목록을 참조하십시오.
Global Commands yarn deps:check and yarn deps:update 전체 Monorepo에서 동일한 버전을 유지하는 데 도움이됩니다. 이들은 우수한 NPM-Check 업데이트를 기반으로합니다 (옵션 참조 : yarn check:deps -t minor ).
yarn deps:update,yarn install필요합니다. 원사에서 복제를 방지하려면yarn dedupe --check및yarn dedupe실행하여 중복 제거를 적용 할 수 있습니다. 중복 점검은 예제 GitHub 작업에서 시행됩니다.
./apps/nextjs-app/.eslintrc.js 및 eslint-config-bases의 예를 참조하십시오.
.husky 폴더 컨텐츠를 확인하여 활성화 된 후크가 있는지 확인하십시오. Lint-Stage는 Lint and Pretier가 커밋 및/또는 푸시시 자동으로 적용되도록 보장하는 데 사용됩니다.
테스트는 앱에 따라 TS-Jest 또는 Vitest에 의존합니다. 모든 설정은 TypeScript 경로 별칭을 지원합니다. React-Testing-Library는 RECT가 관련 될 때마다 활성화됩니다.
구성은 각 앱/패키지의 루트 폴더에 있습니다. 예를 들어보십시오
.github/Workflows에서 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 지원 기본적으로 Monorepos를 지원하고 Vercel-Monorepo-Deploy Deport 문서를 참조하십시오.
Docker 이미지를 만들기위한 기본 예가 있습니다. Docker Doc을 읽으십시오.
NetLify, AWS-Amplify, K8S-Docker, Serverless-NextJS 레시피가 향후 추가 될 수 있습니다. PR도 환영합니다.
앱 종속성 및 DevDependencies는 정확한 버전으로 고정됩니다. 패키지 DEP는 Semver 호환 가능한 패키지를 사용합니다. 이 변경에 대한 자세한 내용은 여기와 renovabot.json5 구성 파일을 참조하십시오.
DEP를 최신 상태로 유지하려면 yarn deps:check && yarn deps:update 및 / 또는 RenovateBot 사용을 참조하십시오.
원사 CLI (예 : 원사 추가)를 통해 DEP를 추가 할 때, yarnrc.yml에서
defaultSemverRangePrefix: ""설정하여 Save-Oxact 동작을 자동으로 설정할 수 있습니다. 그러나 이것은 패키지/*의 기본값도 만듭니다.yarn add something --exact다루는 것이 더 좋습니다.