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

[Feature] svg 아이콘 컴포넌트 방식 변환 자동화 스크립트 작성 #31

Merged
merged 32 commits into from
May 31, 2024

Conversation

ghdtjgus76
Copy link
Collaborator

@ghdtjgus76 ghdtjgus76 commented May 30, 2024

🎉 변경 사항

svg 아이콘을 컴포넌트 방식으로 변환하는 자동화 스크립트 작성했습니다.
기존 wow-ui에서 사용하던 스크립트와 이 스크립트를 별도의 패키지로 관리하는 게 나을 거 같아 scripts라는 패키지로 이동시켰습니다.

이번에 작성한 스크립트는 generateReactComponentFromSvg 파일인데, 주요 로직은 다음과 같습니다.

  1. 컴포넌트와 그에 대응되는 svg 파일을 매핑한 map 생성
  2. svg 파일이 존재하지 않는 변환된 컴포넌트 방식 파일은 삭제 (svg 파일 삭제 후 싱크를 맞추기 위함)
  3. 템플릿을 이용해 아이콘 컴포넌트 내용 파일에 작성
  4. 모든 컴포넌트 방식 아이콘을 export할 수 있는 배럴 파일(wow-icons/react/index.ts) 작성

🚩 관련 이슈

🙏 여기는 꼭 봐주세요!

한 가지 롤업 설정 관련해서 해결해야 할 문제가 있습니다.
이전에 현영님이 말씀하신 use client 주석이 사라지는 문제를 해결하기 위해서 wow-ui rollup.config에 관련 설정을 해놨습니다.
이때 두 가지 설정을 해놨는데, rollup-plugin-preserve-directives 플러그인을 사용하도록 지정해줬고, 이 플러그인을 쓰기 위해서는 preserveModules 속성을 활성화해야 한다고 해서 같이 설정해놨습니다.
그런데, wow-ui 패키지를 빌드하면 styled-system도 같이 빌드됩니다.

image

preserveModules 속성을 true로 지정해주면 현재 폴더 구조를 최대한 유지?하려는 식으로 동작한다고 하네요
rollup/rollup#3684 (comment)
https://so-so.dev/tool/rollup/rollupjs-config/#preservemodules

어제 계속 해결 방법을 좀 찾아보긴 했는데 아직 유의미한 방법을 모르겠어서 일단 올립니다.

Copy link
Contributor

Comment on lines 30 to +31
JSX: true,
console: true,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

이건 자꾸 console이 정의되지 않은 거라고 되어 있어서 추가했습니다

Comment on lines 28 to 32
"scripts": {
"build": "rm -rf dist && rollup -c --bundleConfigAsCjs && tsc --emitDeclarationOnly"
"build": "pnpm generate:icons && rm -rf dist && rollup -c --bundleConfigAsCjs && tsc --emitDeclarationOnly",
"generate:icons": "tsx ../scripts/generateReactComponentFromSvg.ts && pnpm format && pnpm lint",
"lint": "eslint --fix ./src/react/**/*.tsx",
"format": "prettier --write ./src/react/**/*.tsx ./src/react/index.ts"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

wow-icons 빌드할 때 아이콘 자동 변환하도록 해놨습니다.

Copy link
Member

@hamo-o hamo-o left a comment

Choose a reason for hiding this comment

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

스크린샷 2024-05-30 오후 1 35 50
스크린샷 2024-05-30 오후 1 34 22

요거 롤업 세팅하신거 전후 비교입니다! 원래 styled-system은 필요한 부분이 함께 빌드되지만, 하나의 css 파일에 모여 있었던 것 같아요. preserveModules: true 지정해주시면서 한 파일이 아닌 기존 폴더 구조대로 빌드되었는데, 트리쉐이킹은 동일하다고 생각되어서 저는 현상태 유지해도 괜찮다고 생각합니다.

import path from "path";

const SVG_DIR = "../wow-icons/src/svg";
const COMPONENT_DIR = "../wow-icons/src/react";
Copy link
Member

Choose a reason for hiding this comment

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

image

디렉토리가 없어서 만들어주고 generate 해봤습니다!! 넘모 신기해요.
잘 되는데 요렇게 react 폴더 내부에 만들어지는걸 의도하신게 맞을까요?! 기존 UpArrow 컴포넌트 위치 때문에 쪼끔 헷갈렸네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아하 넵 일단은 svg 폴더 내부에 필요한 파일들 다 넣어두고 스크립트 실행시키면 react 폴더에 변환된 아이콘 + export 파일 생성되게 하는 걸 의도했어요
react 폴더 없는 경우는 고려하지 못한 거 같아서 그 부분도 코드 추가해서 올려놨습니다!

Copy link
Contributor

@ghdtjgus76
Copy link
Collaborator Author

스크린샷 2024-05-30 오후 1 35 50 스크린샷 2024-05-30 오후 1 34 22

요거 롤업 세팅하신거 전후 비교입니다! 원래 styled-system은 필요한 부분이 함께 빌드되지만, 하나의 css 파일에 모여 있었던 것 같아요. preserveModules: true 지정해주시면서 한 파일이 아닌 기존 폴더 구조대로 빌드되었는데, 트리쉐이킹은 동일하다고 생각되어서 저는 현상태 유지해도 괜찮다고 생각합니다.

확인해보니까 그런 거 같아요!
사실 제가 걱정한 부분은 styled-system이 들어가서 번들 크기가 크지 않을까...라는 점이었는데
이전 설정으로 빌드했을 때도 dist 폴더 전체는 448 B로 뜨고 지금 설정도 동일하게 뜨네요
그냥 변경된 부분이 폴더 구조를 지킬지 말지? 정도의 차이인 거 같아요

@eugene028
Copy link
Collaborator

스크린샷 2024-05-30 오후 1 35 50 스크린샷 2024-05-30 오후 1 34 22
요거 롤업 세팅하신거 전후 비교입니다! 원래 styled-system은 필요한 부분이 함께 빌드되지만, 하나의 css 파일에 모여 있었던 것 같아요. preserveModules: true 지정해주시면서 한 파일이 아닌 기존 폴더 구조대로 빌드되었는데, 트리쉐이킹은 동일하다고 생각되어서 저는 현상태 유지해도 괜찮다고 생각합니다.

확인해보니까 그런 거 같아요! 사실 제가 걱정한 부분은 styled-system이 들어가서 번들 크기가 크지 않을까...라는 점이었는데 이전 설정으로 빌드했을 때도 dist 폴더 전체는 448 B로 뜨고 지금 설정도 동일하게 뜨네요 그냥 변경된 부분이 폴더 구조를 지킬지 말지? 정도의 차이인 거 같아요

저도 그럼 현 상태 유지해도 괜찮을 것 같다는 생각이 듭니다!!!

Copy link
Collaborator

@eugene028 eugene028 left a comment

Choose a reason for hiding this comment

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

스크립트 작성의 달인이 되셨군요! 수고하셨습니당

Copy link
Collaborator

@SeieunYoo SeieunYoo left a comment

Choose a reason for hiding this comment

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

image

수고많으셨어용!! 다만 apps 쪽에서 한번 컴포넌트 써보려는데 prop 추론이 잘 되지 않는 것 같아요 😥 혹시 저만 그런걸까용,,?

Comment on lines 65 to 77
import { forwardRef } from 'react';
import { color } from "wowds-tokens";

import type { IconProps } from "@/types/Icon.ts";

const ${componentName} = forwardRef<SVGSVGElement, IconProps>(
({ className, width = 24, height = 24, viewBox = "0 0 24 24", fill = "white", stroke = "white", ...rest }, ref) => {
return (
${modifiedSvgContent}
);
}
);

Copy link
Collaborator

Choose a reason for hiding this comment

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

p3;
내부 svg 에서 color 가 적용될 때 fill 이나 stroke 가 하나만 적용되는 아이콘의 경우에는 prop 이 쓰이지 않았다고 린트 에러가 나는 것 같아요! 린트 에러가 발생하지 않도록 수정해보면 어떨까요? 저는 아래의 2가지 방법이 생각납니당!

  • 린팅 에러를 해결하는 주석도 코드에 넣어주기
  • stroke 만 적용되는 경우에는 stroke prop 만 전달되도록 수정하기

image

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

두 번째 방식으로 해결했어요!
fill이나 stroke 중 사용되지 않는 경우 prop으로 전달하지 않도록 했습니다~

Comment on lines 90 to 102
const componentContent = createComponentContent(
componentName,
svgContent,
svgFile
);
const componentFilePath = path.resolve(
COMPONENT_DIR,
`${componentName}.tsx`
);

await fs.writeFile(componentFilePath, componentContent);
components.push(componentName);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

p4;
이미 생성된 컴포넌트의 경우에는 다시 만들지 않고 새로운 svg(아직 컴포넌트화 되지 않은 아이콘)들만 컴포넌트로 만들면 어떨까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

굿굿 좋습니다! 반영해뒀습니다~!

@ghdtjgus76
Copy link
Collaborator Author

image

수고많으셨어용!! 다만 apps 쪽에서 한번 컴포넌트 써보려는데 prop 추론이 잘 되지 않는 것 같아요 😥 혹시 저만 그런걸까용,,?

원래는 잘 됐는데, 마지막에 절대 경로로 import하도록 변경해서 그런 거 같아요..
타입을 못 불러와서 타입 추론이 안 되더라고요

image

롤업 관련해서 절대 경로 설정 좀 해보다가 안 되길래,,, 일단은 이전처럼 상대 경로로 불러오도록 수정해놨어요
이제 타입 추론은 잘 될 거예요!

Copy link
Contributor

Copy link
Contributor

Copy link
Contributor

Copy link
Collaborator

@SeieunYoo SeieunYoo left a comment

Choose a reason for hiding this comment

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

좋아용!! 수고 많으셨습니다👍👍

@ghdtjgus76 ghdtjgus76 changed the title [Feature] svg 아이콘 컴포넌트 방식 자동화 스크립트 작성 [Feature] svg 아이콘 컴포넌트 방식 변환 자동화 스크립트 작성 May 31, 2024
@ghdtjgus76 ghdtjgus76 merged commit 379fa1b into main May 31, 2024
3 checks passed
@ghdtjgus76 ghdtjgus76 deleted the feature/svg-to-react-component-script branch May 31, 2024 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants