통합 모노레포란

https://nx.dev/concepts/integrated-vs-package-based

  • root에 있는 하나의 package.json에서 모든 의존성을 관리하는 방식

특징

  • 이미 툴링, 의존성이 결정되었기 때문에 새로운 프로젝트를 추가하는 것이 쉬움.
  • 기존 프로젝트를 통합 모노레포로 옮기기는 어려움.
  • 하나의 의존성만 관리하기 때문에 관리비용이 적음.
  • 모든 의존성이 한곳에 있기 때문에 다른 의존성을 가진 프로젝트가 많아지면 오히려 관리가 복잡해질 수 있음.

목표

  • react Ui library 프로젝트 추가
  • nextjs 프로젝트 추가
  • eslint, prettier 설정
  • CD/CI

구축

nx workspace 생성

1
npx create-nx-workspace

원하는 옵션을 선택해 워크스페이스를 생성한다.

ui-component 프로젝트 생성

vscode의 nx console 플러그인으로 생성.

importPath도 지정할 수 있다

airbnb eslint 설정

  1. eslint-config-airbnb 설치
1
npx install-peerdeps --dev eslint-config-airbnb
  1. eslint-config-airbnb-typescript 설치
1
npm install eslint-config-airbnb-typescript --save-dev
  1. airbnb eslint 설정

root의 .eslintrc.json에 다음과 같이 추가

1
2
3
4
5
6
7
"extends": [
"airbnb-typescript", // 추가
"plugin:@nx/react-typescript",
"next",
"next/core-web-vitals",
"../../.eslintrc.json"
],

이제 린트를 돌려보면 다음과 같은 에러가 발생함.

https://nx.dev/recipes/tips-n-tricks/eslint

공홈에 nextjs는 다음과 같은 방법으로 해결하라고 되어있음.

nextjs의 .eslintrc.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"extends": ["plugin:@nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
// We set parserOptions.project for the project to allow TypeScript to create the type-checker behind the scenes when we run linting
"parserOptions": {
"project": ["apps/org/tsconfig(.*)?.json"]
},
"rules": {
"@typescript-eslint/await-thenable": "error"
}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

react library의 .eslintrc.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"extends": ["plugin:@nx/react", "../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
// We set parserOptions.project for the project to allow TypeScript to create the type-checker behind the scenes when we run linting
"parserOptions": {
"project": ["lib/ui-component/tsconfig.*?.json"]
},
"rules": {
"@typescript-eslint/await-thenable": "error"
}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
}
]
}

다시 린트를 돌려보면 다음과 같은 에러 발생한다

1
Parsing error: ESLint was configured to run on `<tsconfigRootDir>/apps/org/jest.config.ts` using `parserOptions.project`

아무리 봐도 jest.config.ts가 include 되어있는데 자꾸 include 하란다.
그래서 tsconfig.json에 있는 exclude 목록에서 jest.config.ts를 제거해보니 정상동작함.
아무래도 include, exclude 둘다 되어있어서 충돌이 난게 아닐까 싶다.

성공!

prettier 설정

eslint의 prettier 설정으로 대체함.

  1. eslint-plugin-prettier

eslint에서 prettier를 설정할 수 있게 해줌.
nx에서 prettier가 있어서 충돌나니 prettier 제거해준 후 설치

1
2
npm remove prettier
npm install --save-dev eslint-plugin-prettier
  1. eslint-config-prettier

plugin:prettier/recommended 설정과 함께 prettier와 중복되는 eslint rule을 자동으로 꺼줌.

root의 .eslintrc.json에서 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{
"root": true,
"ignorePatterns": ["**/*"],
"plugins": ["@nx", "prettier"],
"extends": ["prettier", "plugin:prettier/recommended"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"@nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
]
}
]
}
},
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nx/typescript"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"extends": ["plugin:@nx/javascript"],
"rules": {}
}
],
"rules": {
"prettier/prettier": "error"
}
}