Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore : 기존 프로젝트를 turborepo 기반 모노레포로 변경합니다. #55

Merged

Conversation

hhhminme
Copy link
Collaborator

@hhhminme hhhminme commented Sep 3, 2023

📌 이슈 링크


📖 작업 배경

  • 메인페이지 개발에 필요한 컴포넌트, 글로벌 설정, 기타 모듈 등을 잘 관리하기 위해 모노레포를 적용하였습다.

🛠️ 구현 내용

  • turborepo 라는 빌드매니저를 이용하여 모노레포를 구성하였어요.

  • library, next.js, react 내부에서 사용하는 lib, 컴포넌트 세 가지로 나눠 eslint를 설정해주었어요. 이 때 lint 설정들은 custom이 아닌 모두 vercel style guide 에서 가져왔어요

  • tsconfig공통,next.js, react 내부에서 사용하는 lib, 컴포넌트 세 가지로 나눠 설정해두었어요.

  • 모노레포 구성

    • app/web, app/docs

      • web : 서비스 되는 real world, next.js 로 구성
      • docs : 차후 어떻게 개발했는지 남겨두기 위한 문서, nextra 로 개발할 예정입니다.
    • packages/eslint-config-custom, packages/tsconfig, pakages/ui

      • eslint-config-custom : 패키지별 eslint
      • tsconfig : 공통 설정 및 패키지별 tsconfig
      • ui : web에서 쓰일 공통 컴포넌트 및 디자인 시스템

💡 참고사항

node 16버전 이상에서 사용가능합니다.

  • 만약 빌드가 안된다면 npm install turbo --global를 해주시고 npm install -g pnpm 를 해주세요.

이미 pnpm에서 workspace를 제공하는데 왜 turborepo를 적용하였나요?

  • 물론 pnpm workspace를 통해서 모노레포 환경에서 효율적인 패키지 매니징이 가능합니다. 하지만 패키지 별 빌드 환경 설정과 산출물 관리를 위해서는 각각의 프로젝트마다 설정을 해주어야한다는 불편함이 있습니다. 이를 효과적으로 도와주는 것이 nx, lerna, turborepo 와 같은 빌드 매니징 툴입니다.

빌드 매니징 툴을 쓰기 위한거라면 다른 툴도 많은데 왜 turborepo를 적용했나요?

  • 저는next.js 기반의 웹 서비스를 개발하고 있기 때문에 vercel에서 만든 turborepo를 통해 모노레포를 구성하였어요. 또한 turborepo는 패키지에 중점을 두고 있기 때문에 설정도 쉽고 캐싱병렬 빌드 기능을 제공하기 때문에 차후 CI 환경에서 좋은 성능을 낼 수 있을 것이라 생각했어요.

🖼️ 스크린샷

  • lint
image
  • prettier
image
  • build
image

@hhhminme hhhminme self-assigned this Sep 3, 2023
@hhhminme hhhminme added chore Updating build tasks, package manager configs, etc; no production code change and removed chore Updating build tasks, package manager configs, etc; no production code change labels Sep 3, 2023
Comment on lines +2 to +3
// eslint-disable-next-line import/named
import { cache } from "react";
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

캐시 객체는 React 자체에서 가져오는 것이 아니라 Next.js에서 next 패키지로 부터 가져옵니다.

실제 객체는 올바르게 가져오지만 next 13 app router 와 모노레포를 함께 사용했을 때 의존성을 찾지 못하여 린트를 꺼둡니다.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호... 신선하네요

Comment on lines -12 to -14
"docker:build": "pnpm build && docker build --file ./Dockerfile.dev -t react-world .",
"docker:run": "docker run -p 3000:3000 react-world",
"docker:start": "pnpm docker:build && pnpm docker:run"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배포 환경을 어떻게 정할지 고민중에 있어 잠시 docker 관련 코드는 제거합니다.

클러스터 구성과 관련하여 사내에서 모노레포를 쓰시고 계신 분들이 있다면 첨언 부탁드립니다.

Comment on lines +1 to +15
"use client";

export function Button(): JSX.Element {
return (
<button
onClick={(): void => {
// eslint-disable-next-line no-alert -- alert is being used for demo purposes only
alert("booped");
}}
type="button"
>
Boop
</button>
);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

예제 코드입니다. 차후 개발 시 삭제해둘게요

Comment on lines +1 to +31
import type { PlopTypes } from "@turbo/gen";

// Learn more about Turborepo Generators at https://turbo.build/repo/docs/core-concepts/monorepos/code-generation

// eslint-disable-next-line import/no-default-export -- Turbo generators require default export
export default function generator(plop: PlopTypes.NodePlopAPI): void {
// A simple generator to add a new React component to the internal UI library
plop.setGenerator("react-component", {
description: "Adds a new react component",
prompts: [
{
type: "input",
name: "name",
message: "What is the name of the component?",
},
],
actions: [
{
type: "add",
path: "{{pascalCase name}}.tsx",
templateFile: "templates/component.hbs",
},
{
type: "append",
path: "index.tsx",
pattern: /(?<insertion>\/\/ component exports)/g,
template: 'export * from "./{{pascalCase name}}";',
},
],
});
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

문서 내에 특정 데이터를 노출시켜야 할 때 직접 DOM을 파싱하고 데이터가 들어갈 공간을 찾아서 넣어주는 작업을 반복해야합니다. 이런 일을 많이해야할 때 템플릿 엔진을 사용합니다.

요것을 Turbo 에서 loader 역할을 해주어 템플릿 엔진을 사용할 수 있게 해줍니다.

Comment on lines +1 to +14
import * as React from "react";

interface Props {
children?: React.ReactNode;
}

export const {{ pascalCase name }} = ({ children }: Props) => {
return (
<div>
<h1>{{ name }}</h1>
{children}
</div>
);
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handlebars를 사용하기 위해서는 hbs 로 확장자를 변경해줍니다.

handlebars를 사용하는 장점은 아래와 같습니다. 저도 자세히 몰라서 공부하면서 참고하였어요.

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오래된 사이드 템플릿 엔진이죠! 초기에는 우아한형제들에서도 요뇨속을 통해 어드민을 구축했거든요. 사이드 템플릿 엔진 특성이 서버에 상당히 치우쳐져 있어서... 위에 언급한대로 잘 차용하신 것 같네요!

Copy link
Member

@InSeong-So InSeong-So left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모노레포 최초 세팅 때는 정말 변경된 파일이 많네요 🫠

Comment on lines +1 to +3
module.exports = {
extends: ["custom/next"],
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs에 린트 설정 파일이 있군요? 👀

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://nextra.site/ 를 이용해서 static 한 docs 사이트를 만들어서 함께 배포할려고합니다.

차후 불필요하면 제거해두도록 할게요

Comment on lines +1 to +2
# Logs
logs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.gitignore도 루트에서 관리하면 더 좋을지도...!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다 수정해둘게용

Comment on lines +2 to +3
// eslint-disable-next-line import/named
import { cache } from "react";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호... 신선하네요

Comment on lines +1 to +14
import * as React from "react";

interface Props {
children?: React.ReactNode;
}

export const {{ pascalCase name }} = ({ children }: Props) => {
return (
<div>
<h1>{{ name }}</h1>
{children}
</div>
);
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오래된 사이드 템플릿 엔진이죠! 초기에는 우아한형제들에서도 요뇨속을 통해 어드민을 구축했거든요. 사이드 템플릿 엔진 특성이 서버에 상당히 치우쳐져 있어서... 위에 언급한대로 잘 차용하신 것 같네요!

@hhhminme hhhminme merged commit d89e431 into pagers-org:team9/hhhminme Sep 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants