Lerna(๐)๋ก ๋ชจ๋ ธ๋ ํฌ ํด๋ณด๋ฌ๋?
Lerna๋ก mono-repo ๋ง๋ค์ด๋ณด๊ธฐ

์์ํ๊ธฐ ์ ์
์ด ๊ธ์ FE๊ฐ๋ฐ๋ฉ ์คํ์์ค ํ๋ก์ ํธ mono-repo ๋์ ์ ์ํด ์กฐ์ฌํ๋ ๋ด์ฉ์ ์กฐ๊ธ ๋ค๋ฌ์ด ๊ณต์ ์ฉ์ผ๋ก ์์ฑํ ๊ธ์ ๋๋ค.
์ด๋ฏธ Mono-Repo๋ฅผ ์ ์ฉํด์ ๋ง์ ๊ฟํ์ ๊ฐ๊ณ ๊ณ์๊ฑฐ๋ ์๋ชป๋ ๋ด์ฉ์ด ์๋ค๋ฉด ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค.
`Multi Repo`์ `Poly Repo`๋ ๊ฐ์ ์๋ฏธ๋ก ์ฌ์ฉ๋๋ ๋จ์ด์ ๋๋ค. ์ด ๊ธ์์๋ ์ข ๋ ๋ฒ์ฉ์ ์ผ๋ก ์ฐ์ด๊ณ ์๋ `Multi Repo`๋ก ํต์ผ ์์ผ ์์ฑํ์ต๋๋ค.
Mono-Repo์ Multi-Repo?

Mono๋ ๋จ์ผ์ ์๋ฏธ๋ฅผ ๋ํ๋ด๋ ์ ๋์ฌ์ ๋๋ค. ๋ฐ๋์ ์๋ฏธ๋ก๋ Multi, ๋ณต์์ผ ๊ฒ์ ๋๋ค. ๋ํ, Repo๋ Repository์ ์ค์๋ง๋ก ์ ์ฅ์๋ฅผ ์๋ฏธํฉ๋๋ค. ๋ ๋จ์ด๋ฅผ ํฉ์ณ๋ณด๋ฉด Mono-Repo์ ๋ฒ์ฉ์ ์๋ฏธ๋ฅผ ์ ์ ์์ต๋๋ค.
Contains multiple packages or projects
Multi-Repo๋ ์ฌ๋ฌ ์ ์ฅ์์ ํ๋ก์ ํธ, ํจํค์ง๋ฅผ ๋ถ์ฐํด ๋๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
์ ๋ฐ๋๋ก Mono-Repo๋ ํ๋์ repository(์ ์ฅ์)์ ์ฌ๋ฌ ํ๋ก์ ํธ, ํจํค์ง๋ฅผ ๊ฐ์ง ๊ฒ์ ์๋ฏธํฉ๋๋ค.
Mono-Repo์ ์ฅ์ ์ด์ Multi-Repo์ ๋จ์
Multi-Repo๋ ์ ์ฐ์ฑ, ๋ฐฐํฌ, ํ์ฅ์ด ์ฝ์ต๋๋ค. ๋ํ, ์ ์ฑ ์ ์ ํ๊ฑฐ๋ ์ฑ ์์ ๋ช ํํ๊ฒ ํ์๋ค์๊ฒ ๋ง๊ฒ ๋ถ๋ฐฐํ ๋ ์ ์ฅ์๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
ํ์ง๋ง, ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์์ํ ๊ฒฝ์ฐ ์ค๋ณต๋ ์ค์ ์ ๋งค๋ฒ ํด์ค์ผ ํ๋ฉฐ ์คํ์์ค๋ฅผ ์ด์ํ ๋์๋ ์ด์๊ฐ ๋ถ์ฐ๋๊ณ ์ค๋ณต๋๋ ์ฝ๋ ๋ฐฐํฌ๊ฐ ์ฆ์ ์ ์์ต๋๋ค.
๊ทธ๋ผ ์ด์ Mono-Repo์ ์ฅ์ ์ ํ๋ํ๋ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
# Common config
Multi-repo๋ ๋ชจ๋ ์ค์ ์ ๊ฐ๊ฐ ํ๋ก์ ํธ๋ง๋ค ๊ฐ๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง Mono-repo์์๋ `ESLint`, `Prettier`, `Babel` ๋ฑ์ ์ค์ ์ ๋ฃจํธ ๋ ๋ฒจ์ ํ ์ ์์ด ์ฌ๋ฌ ํจํค์ง์์ ํ๋์ ์ค์ ์ ๊ณต์ ํ ์ ์์ต๋๋ค.

# ์ฝ๋ ์ฌ์ฌ์ฉ
๋ํ, ํจํค์ง๋ฅผ ๋๋๋ค๋ฉฐ ๋ชจ๋ํ ์์ผ ์ฌ์ฉํ ์ ์์ต๋๋ค.

์ฌ๊ธฐ์ `babel/packages/babel-cli/src/babel/util.js` ๊ฒฝ๋ก์ ๋ค์ด๊ฐ ์ฝ๋๋ฅผ ๋ณด๋ฉด
// โฆ ๋ค๋ฅธ ๋ชจ๋ import
import * as babel from โ@babel/coreโ;
export function transform(
filename: string,
code: string,
opts: Object,
): Promise<Object> {
opts = {
โฆopts,
caller: CALLER,
filename,
}; return new Promise((resolve, reject) => {
babel.transform(code, opts, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
}
@babel/core ์์กด์ ๊ฐ์ ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.

๊ฐ๋จํ๊ฒ ๋ง๋ค์ด๋ณธ Mono-Repo์ ์์์ ๋๋ค. ๊ณตํต์ผ๋ก ์ฌ์ฉํ๋ core, util, routing ์ฝ๋๋ค์ ๊ฐ ํจํค์ง๋ก ๋ถ๋ฆฌํ๊ณ ์ด ํจํค์ง๋ฅผ ์ด์ฉํด ํ๋์ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค ์ ์์ต๋๋ค. ๋ํ, ์ด core, util, routing์ ์ด ์์ฒด๋ก๋ ์๋ฏธ๊ฐ ์์ด ์ธ๋ถ์์ ์ฌ์ฉ์ ํ ์ ์๋๋ก ๋ฐฐํฌ๋ ์ ์์ต๋๋ค. ๋ง์น TOAST UI์ tui-code-snippet, tui-dom ์ฒ๋ผ์!
# One PR
TOAST UI Application + TOAST UI Component + React Wrapper + Vue Wrapper ์ ๊ฐฏ์๋ ๋ช๊ฐ์ผ๊น์?
๋ต์ 41๊ฐ์ ๋๋ค. ์ผ๋ง ์ ์ค์ ๋ก ์์๋ ์ผ์ ๋๋ค. ์ฌ๋ช ์ด NHN Entertainment์์ NHN์ผ๋ก ๋ณ๊ฒฝ๋์์ ๋ ์ฌ๋ช ์ด ๋ณ๊ฒฝ๋ ๊ฒ์ npm์ ๋ฐ์์ํค๋ ค๋ฉด 41๋ฒ์ ๋ฐฐํฌ๊ฐ ํ์ํ์ต๋๋ค.(repository์ ๋ณ๊ฒฝ์ ์กฐ๊ธ ๋ ๋ค์ ์์์ผ๋ ๋ ๋ง์ ํ์์ ๋ฐฐํฌ๊ฐ ์์์ต๋๋ค.) ๋ฌผ๋ก , ๋ค๋ฅธ ์คํ์์ค๋ค์ ๋นํด ๋ง์ ๊ฐ์๋ ์๋์ง๋ง ๊ทธ๋๋ ์ ์ง ์์ ๊ฐฏ์์ด๊ธฐ๋ ํฉ๋๋ค.(1000๊ฐ ์ด์์ ๋ชจ๋์ npm์ ๋ฑ๋กํ์ ๋ถ๋ ์กด์ฌํฉ๋๋ค.) ์ ์ด๋ TOAST UI์ ๊ฐ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ํผ๋ค์ ํตํฉ์์ผ Mono-Repo ํํ๋ฅผ ๋ง๋ค์ด์ค๋ค๋ฉด 10๊ฐ์ ์ ์ฅ์ ๊ด๋ฆฌ ์ด์๊ฐ ์ค์ด๋ค๊ณ ํ๋์ PR๋ก ๋ง์ ๊ฒ์ ํ ๋ฒ์ ๊ด๋ฆฌํ ์ ์๊ฒ ๋ ๊ฒ์ ๋๋ค.
TOAST UI Grid๋ ์ง๊ธ ์ด๋ป๊ฒ ํ๊ณ ์๋?

TOAST UI Application์ ์ง๊ธ multi-repo์ ํํ๋ฅผ ๋๊ณ ์์ต๋๋ค. TOAST UI Grid๋ฅผ ์๋ก ๋ค๋ฉด(๋๋จธ์ง Application ๋ํ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค.) tui.grid, toast-ui.vue-grid, toast-ui.react-grid ์ธ๊ฐ์ ์ ์ฅ์๋ก ๋ถ๋ฆฌ๋์ด ์์ต๋๋ค.
# ๊ด๋ฆฌ์ ๋ถํธํจ
- ๐์ด์์ ๋ถ์ฐ๐: ์ด์๊ฐ ๋ถ์ฐ๋๋ ๊ฒ์ ๊ฐ์ฅ ํฐ ๋ฌธ์ ์์ต๋๋ค. TOAST UI Grid๋ฅผ vue-wrapper๋ฅผ ํตํด ์ฌ์ฉํ ๋ ๋ฌธ์ ๊ฐ ์๊ธด๋ค๋ฉด ์ด๋ ์ ์ ์์ ์ด์๋ฅผ ์ฌ๋ ค์ผ ํ๋์ง ์ฌ์ฉ์๋ ์ถฉ๋ถํ ํท๊ฐ๋ฆด ์ ์์ต๋๋ค. ๋ํ ์ง์ผ๋ด์ผ ํ ์ ์ฅ์๊ฐ ๋ง์์ง ์๋ก ๋น ๋ฅธ ๋์์ด ํ๋ค์ด์ง๋ ๊ฒ ๋ํ ํ์ค์ด์์ต๋๋ค.
- ๋งค๋ฒ ํ๋ก์ ํธ๋ฅผ ์์ฑํ ๋๋ง๋ค ์ ์ ๋ถ์๋๊ตฌ๋ ์คํ์ผ ๊ท์น์ ๋งค๋ฒ ์ค์ ํด์ค์ผ ํ์ต๋๋ค.(Prettier, Eslint, Cypress, storybookโฆ)
- ์์กด์ ๊ฐ๊ณ ์๋ ๋ ํฌ๋ฅผ ์์ ํ์ ๋ ๋ชจ๋ ํ๊บผ๋ฒ์ ์์ ํ์ฌ ๋ฐฐํฌํ๊ธฐ์ ์ด๋ ค์์ด ์์์ต๋๋ค.
์ด๋ฐ ๋ถํธํ ์ ์ ์ ํํ๊ฒ mono-repo์ ์ฅ์ ๊ณผ ๋งค์นญ๋์์ต๋๋ค.
Mono-Repo์ ํ์์ฑ๊ณผ ์ฅ์ ๋ค์ ๊ฐ๋จํ๊ฒ ์์๋ดค์ผ๋ ์ ์ฅ์ ๊ตฌ์ฑ์ ๋์์ฃผ๋ ํ ์คํ์์ค๋ฅผ ์๊ฐํด๋ณด๊ฒ ์ต๋๋ค.
Lerna ๋?

Lerna๋ ๋ฌ๋ ํน์ ๋ ๋ฅด๋๋ก ์ฝํ๋๋ค. ํ๊ตญ์์๋ ๋ ๋ฅด๋๋ก ๋ ๋ง์ด ์ฝํ๋๋ฐ์. (๋ก๊ณ ์ ํ๋๋ผ๊ฐ ๊ถ๊ธํ์๋ฉด ์ํค๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์.)
Lerna๋ ๋จ์ผ ์ ์ฅ์(Repository)์์ ๋ค์ํ packages๋ฅผ ๊ตฌ์ฑํ๋ ๊ฒ์ ๋์์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. ํ๋ก์ ํธ ์ ์ฒด๋ฅผ ๋น๋ํ๊ฑฐ๋, ํ
์คํธ ํ ๋ ๋ณ๊ฒฝ์ด ์๋ ํจํค์ง๋ค์ ๋ฐฐํฌํ ๋ ๋์์ ์ค๋๋ค.
Lerna๋ก ๋ฌด์์ ํ ์ ์๋?
Lerna์์ ๊ณต์์ฌ์ดํธ์์ ์ธ๊ธํ๊ธฐ๋ก๋ lerna publish, lerna bootstrap ๋๊ฐ์ง๊ฐ ์ฃผ์ ๊ธฐ๋ฅ์ด๋ผ๊ณ ํฉ๋๋ค. ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฌ์ฉํ ๊ฒ์ ์๋์ง๋ง ์ด์ธ์ ๋ง์ ๊ธฐ๋ฅ์ ํ๋ฒ์ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ์ด์ ์ฌ๋ฌ ์ปค๋งจ๋๋ค๋ ๊ฐ์ด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. ๊ตฌ์ฒด์ ์ธ ์ปค๋งจ๋ ์ค๋ช ์ด๋ ์ฌ๊ธฐ ๋ฑ์ฅํ์ง ์๋ ์ปค๋งจ๋๊ฐ ๊ถ๊ธํ๋ค๋ฉด ๋ค์ ๋งํฌ๋ฅผ ํ์ธํ์ธ์.
# lerna init
$ lerna init
$ lerna init โ independent
ํด๋น ํ๋ก์ ํธ์ lerna repo๋ฅผ ๋ง๋ค๊ฑฐ๋ ์ต์ ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ๋ฅผ ํ ๋ ์ฌ์ฉํฉ๋๋ค. โ independent ์ต์ ์ ๋ถ์ผ ๊ฒฝ์ฐ ํจํค์ง๋ค์ ๋ฒ์ ๋ ์ ์ฑ ์ ๋ ๋ฆฝ์ผ๋ก ๊ฐ์ ธ๊ฐ๋๋ค.
# lerna version
$ lerna version 1.0.1 # explicit
$ lerna version patch # semver keyword
$ lerna version # select from prompt(s)
์ด์ ๋ฐฐํฌ ๋ฒ์ ์์ ๋ณ๊ฒฝ์ด ์กด์ฌํ๋ pacakge๋ค์ ๋ฒ์ ์ ๋ณ๊ฒฝ์์ผ์ค๋๋ค. semver ํค์๋๋ฅผ ์ ๋ ฅ์ํค๊ฑฐ๋ ๋ฒ์ ์ ๋ช ์ํด์ฃผ๊ฑฐ๋, ์ ํํด์ ์ ์ฉ์ํฌ ์ ์์ต๋๋ค.
# lerna diff
$ lerna diff [package]
ํด๋น ํจํค์ง์ ์ง๋ ๋ฐฐํฌ ์ดํ ๋ณ๊ฒฝ์ ์ ๋ํ ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๊ฒ ๋ฉ๋๋ค.
# lerna bootstrap
$ lerna bootstrap
lerna bootstrap์ ํตํด ๊ฐ ํจํค์ง๋ค์ ์์กด์ ์ค์นํ๊ณ cross-dependencies๋ฅผ ์ฐ๊ฒฐ, ์ฌ์ ๋น ํด์ค๋๋ค. ์์กด์ด ์๋ ํจํค์ง๋ ์ค์น ๋์ Symlink๋ฅผ ์ ๋น ํฉ๋๋ค.
# lerna run
$ lerna run <script>
$ lerna run test
$ lerna run build# my-component ํจํค์ง๋ง test
$ lerna run โ scope my-component test
๊ฐ ํจํค์ง๋ค์ npm ๋ช ๋ น์ด๋ฅผ ์คํํฉ๋๋ค. scope๋ฅผ ์ง์ ํ ์ ์์ผ๋ฉฐ scope๋ฅผ ์ง์ ํ์ง ์์ ๊ฒฝ์ฐ ์ ์ฒด ํจํค์ง์ ๋ช ๋ น์ด๋ฅผ ์ํํฉ๋๋ค.
# lerna publish
$ lerna publish
ํ๋ก์ ํธ์์ ์ง๋ ๋ฆด๋ฆฌ์ฆ ์ดํ ๋ณ๊ฒฝ์ด ์์๋ ํจํค์ง๋ฅผ ๋ฐฐํฌํฉ๋๋ค.
# lerna clean
$ lerna clean
๊ฐ ํจํค์ง๋ค์ node_modules ํด๋๋ฅผ ์ญ์ ํฉ๋๋ค. workspaces๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ธฐ ์ค์ ์ ๊ตฌํํ ๋ ์ฌ์ฉํ๊ธฐ ์ข์ต๋๋ค.
# lerna link convert
$ lerna link convert
lerna link convert๋ฅผ ํตํด ๊ฐ ํจํค์ง์ devDependencies๋ฅผ ๋ฃจํธ์์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.


Mono-Repo ์ ์ฉ ํด๋ณด๊ธฐ
* ํ ์คํธ ๊นํ ๋งํฌ: https://github.com/jung-han/tt-grid-test
๊ฐ ์ปค๋งจ๋๋ค์ ๊ฐ๋จํ๊ฒ ์ดํด๋ดค์ต๋๋ค. ์ด๋ค ์ญํ ์ ํด์ฃผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ์ง ๋๋์ด ์ค์๋์? ๊ทธ๋ผ ํ๋ฒ ๊ฐ๋จํ๊ฒ ์ ์ฉํด ๋ณด๊ฒ ์ต๋๋ค.
๋ ๋ฆฝ๋ฒ์
lerna๋ฅผ ์ค์นํ๊ณ independent๋ก ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ์ต๋๋ค.
$ lerna init โ independent
lerna.json ํ์ผ์ lerna init์ ํ ์ํ ๊ทธ๋๋ก ์ ๋๋ค.
{
โpackagesโ: [
โpackages/*โ
],
โversionโ: โindependentโ
}
๊ฐ ํจํค์ง๋ค์ ๊ฒฝ๋ก๊ฐ ์ด๋ป๊ฒ ๋๋์ง, version์ ์ด๋ป๊ฒ ๊ฐ์ ธ๊ฐ๋์ง๋ฅผ ๋ํ๋ด๋ ์ค์ ํ์ผ์ ๋๋ค.
# ํด๋ ์์ ํ๊ธฐ

packages ํด๋์ ๊ฐ ํจํค์ง๋ค์ ์์น ์ํต๋๋ค. ์ด๋ ๊ณตํต์ผ๋ก ๋ฌถ์ ์ ์๋ docs ํ์ผ์ด๋ ์ค์ ํ์ผ๋ค์ root๋ก ์์น ์ํต๋๋ค.
# ๋ฐฐํฌํ๊ธฐ

npm publish๋ฅผ ํ๊ฒ๋๋ฉด ๋ณด๊ฒ ๋๋ ํ๋ฉด์ ๋๋ค. CLI๋ฅผ ํตํด ์ด๋ค ๋ฒ์ ์ ๋ฐฐํฌํ ๊ฒ์ธ์ง ๊ฐ๊ฐ ํจํค์ง๋ค ๋ณ๋ก ๋ฒ์ ์ ์ง์ ํด ์ค ์ ์์ต๋๋ค.
# ๋ฆด๋ฆฌ์ฆ ๋ ธํธ์ ํํ

๋ ๋ฆฝ๋ฒ์ ๋ฐฐํฌํ ํ๊ทธ์ ํํ๋ ๋ฐฐํฌ๋ ํจํค์ง์ ์ด๋ฆ@๋ฒ์ ์ ํํ์ ๋๋ค. lerna publish๋ฅผ ์ด์ฉํ๋ฉด ์๋์ผ๋ก ํ๊ทธ๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
# bower ์ฌ์ฉํ๊ธฐ
bower๋ฅผ ์ ๊ณตํ๋ ๋ฐฉ์์ ๋์ผํฉ๋๋ค.

์ค์ ํ์ผ์ packages์ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ฒ๋คํ์ผ ์์น๋ก ๋ณ๊ฒฝํด์ฃผ๋ฉด ๋ฉ๋๋ค. ๋ค๋ง `bower`์ ๊ธฐ์ค์ ํ๋ก์ ํธ์ ๋ฃจํธ์ด๋ฉฐ ์ฌ๋ฌ ํจํค์ง๋ฅผ ๊ฐ๊ฐ bower๋ก ๋ฐฐํฌํ๋ ๊ฒ์ ์ด๋ ค์ ๋ณด์ ๋๋ค.(๋ฐฉ๋ฒ์ด ์กด์ฌํ๋ค๋ฉด..๋๊ธ ๋ถํ๋๋ฆฝ๋๋คใ ใ )
ํตํฉ๋ฒ์
independent ์ต์ ์ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ด์ ๊ณผ ๋ค๋ฅด๊ฒ ๋ฒ์ ์ ์ซ์๊ฐ ์๊ธฐ๊ฒ ๋ฉ๋๋ค. ์ด ํํ๋ ๊ธฐ๋ณธ์ ์ผ๋ก semver๋ฅผ ๋ฐ๋ฆ ๋๋ค. ์ด ์ต์ ์ด ์ ์ฒด package๋ค์ ํตํฉ ๋ฒ์ ์ ๋ํ๋ด๊ฒ ๋ฉ๋๋ค.
{
โpackagesโ: [
โpackages/*โ
],
โversionโ: โ0.0.0โ
}
# ๋ฐฐํฌํ๊ธฐ
์ด์ ๊ณผ๋ ๋ค๋ฅด๊ฒ ๋ณํ๊ฐ ์กด์ฌํ๋ ์ ์ฒด ํจํค์ง๋ค์ ๋ฒ์ ์ ๋ง์ถฐ ํ๋ฒ์ ๋ฐฐํฌํฉ๋๋ค.

๋ฆด๋ฆฌ์ฆ ๋ ธํธ ๋ํ ์ด์ ์ฒ๋ผ ํ๋๋ก ๊ด๋ฆฌ๋๊ฒ ๋ฉ๋๋ค.

๋ง์ฝ react wrapper์ ๋ณํ๋ฅผ ์ฃผ๊ณ ๋ฐฐํฌ๋ฅผ ํ๋ค๋ฉด ๋ณํ๊ฐ ์๋ ํจํค์ง๋ง ๋ฐฐํฌ๋๊ฒ ๋ฉ๋๋ค.

yarn workspace๋ฅผ ํตํ code sharing
# ํ๊ฒฝ ์ค์
- lerna.json
{
โpackagesโ: [
โpackages/*โ
],
โversionโ: โ0.0.0โ,
โnpmClientโ: โyarnโ,
โuseWorkspacesโ: true
}
๊ฐ pacakge์ ์ฝ๋๋ฅผ ๊ณต์ ํ๊ธฐ ์ํด์๋ yarn์ npm client๋ก ์ง์ ํด์ผ ํ๋ฉฐ useWorkspaces ์ต์ ์ true๋ก ์ง์ ํฉ๋๋ค.
- root packages.json
{
โworkspacesโ: [
โpackages/*โ
]
}
์ต์๋จ packages.json์๋ workspaces์ ์์น๋ฅผ ๋ช ์ํด์ค๋๋ค.
yarn workspace๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด ๊ฐ ํจํค์ง์์ ์ฌ์ฉํ๋ ๋ ธ๋ ๋ชจ๋๋ค์ ์ค๋ณต์ผ๋ก ์ค์นํ์ง ์๊ณ ์๋จ์์ ๊ด๋ฆฌํ ์ ์๊ฒ ๋ฉ๋๋ค.

์ค๋ณต์ผ๋ก ์ฌ์ฉํ๋ ๋ชจ๋ ์ธ์ ํ์ผ๋ค์ ๊ฐ ํจํค์ง๋ค์ ์์นํ์ฌ ์ฌ์ฉ๋ฉ๋๋ค. ํด๋น ์์กด์ package.json์ ๋ช ์ํ๊ณ ์ฌ์ฉํ๋ฉด ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
- yarn workspace๋ฅผ ์ฌ์ฉํ์ง ์๊ณ lerna bootstrap์ ํตํด์๋ง cross-dependency๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- npm 7 roadmap์ ํ์ธํด ๋ณด๋ฉด 7๋ฒ์ ๋ถํฐ workspace๊ฐ ์ถ๊ฐ๋๋ค๊ณ ํฉ๋๋ค. yarn์ ๊ตณ์ด ์ฌ์ฉํ์ง ์์๋ ๊ด์ฐฎ์ ๋ณด์ ๋๋ค. (์กด๋ฒํฉ์๋ค)
์คํ์์ค๋ค์ ๋ฒ์ ์ ์ฑ
๋ง์ฝ Mono-Repo๋ฅผ ๋์ ํ๋ค๋ฉด ๊ฐ์ฅ ํฌ๊ฒ ๊ณ ๋ คํ ์ ์ ๋ฒ์ ์ ์ฑ ์ผ ๊ฒ์ ๋๋ค. ๊ฐ ์คํ์์ค๋ค์ ๊ฐ์์ ์๋น์ค์ ํน์ฑ์ ๋ง๊ฒ ๋ฒ์ ์ ์ฑ ์ ์ ํ ๋ค ๋ฐ๋ฅด๊ณ ์์ต๋๋ค. ๋ช ๊ฐ์ง ์คํ์์ค๋ค์ ํตํด ์ฌ์ฉํ ์ ์๋ ๋ฒ์ ์ ์ฑ ์ ๊ฒํ ํด ๋ณผ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. ๊ฐ ์คํ์์ค๋ค์ ๋ฒ์ ์ ์ฑ ๊ณผ ๋ฆด๋ฆฌ์ฆ ๋ ธํธ๋ ์ด๋ป๊ฒ ์์ฑ๋๊ณ ์๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ค ์ ์ฑ ์ ์ ํํด ๋ณผ ์ ์์์ง ์ ๋ฆฌํด๋ดค์ต๋๋ค.
babel/babel
๋จผ์ , ๋ชจ๋ ธ๋ ํฌ๋ฅผ ๊ฐ์ฅ ์ด์ฌํ ์ ์ฉํ๊ณ ์๋ ๋ฐ๋ฒจ์ ๋๋ค.
* ๋งํฌ: https://github.com/babel/babel
# ๋ฒ์ ์ ์ฑ ์?
๋ฐ๋ฒจ์ ํ๊ฐ์ง ๋ฉ์ธ๋ฒ์ ์ ๋๊ณ ์ปค๋ฐ ๋ํ๊ฐ ์กด์ฌํ๋ ํจํค์ง๋ฅผ ๋ฐฐํฌํฉ๋๋ค. ๋ฉ์ธ ๋ฒ์ ์ด ํ๋ ์กด์ฌํ๋ฉฐ ๋ฐฐํฌ๊ฐ ์๋ ํจํค์ง๋ ๊ทธ ๋ฒ์ ์ ๋ฐ๋ผ๊ฐ๋๋ค.

์ ๊ทธ๋ฆผ์ ๋ณด๋ฉด babel-node๊ฐ 7.4.5 ๋ฒ์ ์ด ๋๊ฐ์ ๋์ diff ์
๋๋ค. ๋ฒ์ ์ด ๋ฐ๋ก 7.2.2์์ 7.4.5 ๋ก ๋ด ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๊ฐ ํจํค์ง๋ค์ ๋
๋ฆฝ๋ ํ๋ก์ ํธ๋ก ๋ณธ๋ค๋ฉด semver๋ฅผ ์งํค์ง ๋ชปํ๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค. ํ์ง๋ง, ํ๋์ ํฐ ํ๋ก์ ํธ๋ผ ์๊ฐํ๋ค๋ฉด ๋งค์ฐ ํธํ ์ ์ฑ
์ด๋ผ ๋ณผ ์ ์์ต๋๋ค.
# ๋ฆด๋ฆฌ์ฆ ๋ ธํธ๋?

๋ณ๊ฒฝ์ด ๋๋ ๋ด์ฉ๊ณผ ์ํฅ์ ๋ฐ์ ํจํค์ง๋ค์ ๋์ดํฉ๋๋ค.
facebook/react
* ๋งํฌ: https://github.com/facebook/react
# ๋ฒ์ ์ ์ฑ ์?
babel๊ณผ ๋น์ทํ ์ ์ฑ ์ ์ถ๊ตฌํฉ๋๋ค. ๊ตฌ์ฒด์ ์ธ ์ ์ฑ ์ ์ ์ ์์ง๋ง ์ฃผ์ํ ๊ธฐ๋ฅ์ด ๋๋ ํจํค์ง๋ค์ ํ๋์ ๋ฉ์ธ ๋ฒ์ ์ ๋ฐ๋ผ๊ฐ๋๋ค. ๋ ๋ฆฝ์ ์ผ๋ก ๋ฒ์ ์ ์ฃผ๋ ํจํค์ง๋ค ๋ํ ๋ฐ๋ก ์กด์ฌ ํฉ๋๋ค.
# ๋ฆด๋ฆฌ์ฆ ๋ ธํธ๋?

๋ณ๊ฒฝ์ด ๋๋ ๋ด์ฉ๊ณผ ์ํฅ์ ๋ฐ์ ํจํค์ง๋ค์ ๋์ดํฉ๋๋ค.
facebook/jest
* ๋งํฌ: https://github.com/facebook/jest
# ๋ฒ์ ์ ์ฑ ์?

react, babel๊ณผ ์ ์ฌํฉ๋๋ค. ์๋ฌด๋๋ ๊ฐ์ ๊ณ์ด์ ํ๋ก์ ํธ์ด๊ธฐ ๋๋ฌธ์ด๊ฒ ์ฃ ?
- ๋ชจ๋ ํจํค์ง๋ค์ด ๋ฒ์ ์ ๋ฐ๋ผ๊ฐ์ง๋ ์๋๋ค.
- ๋น์ ์ ๋ฐ์ดํธ๊ฐ ์๋(commit์ diff ๊ฐ ์๋) ํจํค์ง๋ง ์ ๋ฐ์ดํธ ํ๋ฉฐ ๋ฒ์ ์ lerna.json์ ๋ฐ๋ผ๊ฐ๋ค.
- patch ๋ฒ์ ์ด ์ฌ๋ผ๊ฐ๋ ๊ฒฝ์ฐ๋ ๊ฑฐ์ ์์ผ๋ฉฐ ์ฃผ๋ก minor ๋ฒ์ ์ด ์ฆ๊ฐํฉ๋๋ค.
- major ๋ฒ์ ์ด ๋น ๋ฅด๊ฒ ์ฆ๊ฐํ๋ ์ด์ ๋ ์ด๋๋ฌธ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
# ๋ฆด๋ฆฌ์ฆ ๋
ธํธ๋?
๊นํ์๋ ์์ฑํ์ง ์์ต๋๋ค.
๋ง์ด๋ ๋ฒ์ , ํจํค์ง ๋จ์์ ์
๋ฐ์ดํธ๋ ๋ฐ๋ก ์์ฑํ์ง ์๋๋ค. ๋ฉ์ด์ ๋ฒ์ ์ ์
๋ฐ์ดํธ๋ ๊ณต์ ์ฌ์ดํธ์ Blog ์ ์์ฑํฉ๋๋ค.
airbnb/enzyme
* ๋งํฌ: https://github.com/facebook/jest
react adapter๋ฅผ react์ ๋ฒ์ ๋ณ๋ก ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ํผ๋ค์ ๊ด๋ฆฌํ๋ ๊ฒ๊ณผ ๋น์ทํฉ๋๋ค.
# ๋ฒ์ ์ ์ฑ ์?
independent ๋ชจ๋๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ฐ ํจํค์ง ๋ณ๋ก ๋ ๋ฆฝ๋ ๋ฒ์ ์ ๊ฐ์ต๋๋ค.

# ๋ฆด๋ฆฌ์ฆ ๋ ธํธ๋?

๊นํ์๋ ์์ฑํ์ง ์์ต๋๋ค. ๊ณต์ ์ฌ์ดํธ์ Change Log์ ๋ณ๋ ์ฌํญ์ ๊ฐ๊ฐ ์ด๋ค ๋ณ๋์ด ์๋์ง ์ ๋ฆฌํฉ๋๋ค.
๊ฐ๋ฅํ ๋ฒ์ ์ ์ฑ ์ ์ ๋ฆฌํด๋ณด๋ฉด?

์ธ ๊ฐ์ง ํํ์ ๋ชจ๋ธ์ด ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค. ๋ฉ์ธ ๋ฒ์ ์ ๋๊ณ ๋ณํ๊ฐ ์๋ ํจํค์ง๋ง ๋ฐฐํฌํ๋ ๋ชจ๋ธ, ์ ์ฒด๋ฅผ ๋ชจ๋ ๋ฐฐํฌํ๋ ๋ชจ๋ธ, ๊ฐ๊ฐ์ ํจํค์ง๊ฐ ๋ ๋ฆฝ๋ ๋ฒ์ ์ ๊ฐ์ ธ๊ฐ๋ ๋ชจ๋ธ์ ๋๋ค. ์ธ ๊ฐ์ง ๋ชจ๋ธ์ ํ๋ก์ ํธ๋ฅผ ์ด๋ป๊ฒ ๊ตฌ๋ถํ๊ณ ๋ฐ๋ผ๋ณด๋๊ฐ์ ๋ฐ๋ผ ๋ค๋ฅผ ๊ฒ ๊ฐ์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๋ชจ๋ธ์ lerna์ ๊ธฐ๋ณธ ๋ชจ๋ธ์ ๋๋ค. ๊ฐ pacakge์์ ๋ณํ๊ฐ ์๋ ๋ธ๋์น๋ง ์ ๋ฐ์ดํธํ๋ ๋ชจ๋ธ์ ๋๋ค. ๋๋ฒ์งธ ๋ชจ๋ธ์ ๋ณํ๊ฐ ์๋ ๋ธ๋์น์ ๋ง์ถฐ ๋ฒ์ ์ ๊ฐ์ด ์ฌ๋ฆฌ๋ ๊ฒฝ์ฐ์ธ๋ฐ ์ด ๋ชจ๋ธ์ ์ฌ์ฉํ ๋๋ ์ฃผ๋ก ์์กด์ ๊ฐ๊ณ ์๋ ํจํค์ง์ `package.json` ํ์ผ์ ์ ๋ฐ์ดํธ ๋๋ ๋ฒ์ ์ ํจํค์ง ๋ฒ์ ์ ๋ช ์ํด ๋ณํ๋ฅผ ์ค ๊ฐ์ด ์ ๋ฐ์ดํธ ํ๋ ๋ฐฉ์์ ๋ฐ๋ฆ ๋๋ค. ์ธ๋ฒ์จฐ ๋ชจ๋ธ์ independent๋ก ๋ณํ๊ฐ ์กด์ฌํ๋๋ผ๋ ๊ฐ๊ฐ ๋ฐฐํฌํ๊ฒ ๋๋ ํํ์ ๋๋ค.
์ค๋นํ ๋ด์ฉ์ ์ฌ๊ธฐ๊น์ง ์ ๋๋ค. TOAST UI๋ Mono-Repo ๋์ ์ ์ค๋น ์ค์ด๊ณ ๊ฒฐ๊ณผ์ ์ผ๋ก ์ด๋ค ์ฅ๋จ์ ์ ์ป๋์ง ๋ค์ ํ๋ฒ ์ ๋ฆฌํ์ฌ ์ดํ์ ๊ณต์ ํ๋๋ก ํ๊ฒ ์ต๋๋ค.
Mono-Repo๋ ์คํ์์ค์์ ๊ท๋ชจ๊ฐ ์ปค์ง ์๋ก ํ์๊ฐ ๋์ด๊ฐ๋ ๋๋์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ Lerna๋ฅผ ์ฌ์ฉํ์ง ์์๋ Mono-Repo๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ํ๋ก์ ํธ ๋ํ ์ฝ๊ฒ ์ฐพ์ ์ ์์ต๋๋ค. ์ดํ Mono-Repo ์ ์ฉ์ ๋์์ด ๋์์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค. ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๐