HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🧐
Sonny
/
🥲
npm workspace으로 구성된 환경 바로잡기
🥲

npm workspace으로 구성된 환경 바로잡기

상태
해결
작성일
Mar 26, 2024
태그
WorkSpace

요구사항

  • 변경 사항 없이 ui 패키지만 빌드 및 패키지 배포

테스트 환경

  • 패키지 : npm monorepo, vite로 빌드
  • 패키지 사용처 : npm link로 심볼릭 링크로 사용

문제 상황

  • 문제 1. children 관련 에러 발생
    • @types/react버전이 playground쪽과 완전히 호환이 되어야지만 타입 에러가 발생하지 않는 현상 (forwardRef로 감싼 컴포넌트만 해당 문제 발생)
      • 'Button' cannot be used as a JSX component. Its return type 'ReactElement<any, string | JSXElementConstructor<any>> | null' is not a valid JSX element. Type 'ReactElement<any, string | JSXElementConstructor<any>>' is not assignable to type 'Element'. Types of property 'key' are incompatible. Type 'Key | null' is not assignable to type 'string | null'. Type 'number' is not assignable to type 'string'.ts(2786)
    • 신기하게도 멀티 레포로 분리했을 때는 해당 에러가 발생하지 않음
  • 문제 2. 사용처에서 tsc로 타입 체킹을 했을 때, 원본 소스 파일까지 컴파일 되는 현상
    • 멀티레포로 분리했을 때, 문제 1의 에러는 발생하지 않지만 타입 체킹을 위해 tsc로 컴파일 시, 원본 소스까지 컴파일이 되는 문제가 있었음
 

해결 방안 Bad Case

  • playground쪽 @types/react 버전을 ui 패키지의 @types/react 버전과 동일하게 맞추기
  • playground쪽 tsconfig.json에 속성을 추가하기
    • // tsconfig.json "compileOptions": { "paths": { "react": [ "./node_modules/@types/react" ] } }
⇒ 문제 1은 해결이 가능했지만 결과적으로 문제 2는 동일하게 발생한다.

해결방안 New

@types/react버전이 동일해야 해결되는 게 이상하다.. 다른 방안을 모색하쟈

해결 과정

  1. 문제가 되는 곳 찾아보기
    1. 현재 타입 컴파일(tsc)을 했을 때, 에러들이 발생하는데 플러그인을 사용해서 컴파일하면 에러가 발생하지 않는다. ⇒ 타입 문제 해결해보기
 

솔루션

  • 문제 1에 대한 해결
    • 원인
      • npm workspace로 인한 호이스팅 + npm link의 심볼릭 링크
    • 과정
      • 말도 안대.. 전혀 예측하지 못했던 npm workspace의 패키지 호이스팅과 npm link의 심볼릭 링크로 인한 문제였다.
      • 배포가 될 패키지의 package.json에는 의존성을 명시했지만 npm link로 테스트 해보았기 때문에 프로덕션 환경과 완전히 일치하지 않았다.
      • npm link는 해당 패키지를 심볼릭 링크로 연결하기 때문에 해당 디렉토리의 소프트 링크를 가리킨다. ⇒ 해당 소스 디렉토리 구조 그대로 된다. monorepo를 사용하고 있다면 npm 호이스팅으로 인해 의존성에 명시된 모듈들이 없을수도 있는 상태가 된다.
  • 문제 2에 대한 해결
    • 원인
      • npm workspace로 인한 호이스팅 + npm link의 심볼릭 링크
    • 과정
      • npm link는 타입스크립트가 기본적으로 따르는 심볼릭 링크를 생성하여 잠재적으로 링크된 패키지가 원치않게 컴파일 될 수 있다.
      • tarball에서 설치하면 패키지가 격리되고 컴파일된 모듈로 처리된다.
 

레퍼런스

  • https://twitter.com/dan_abramov/status/1512833611401150474
  • https://stackoverflow.com/questions/71788254/react-18-typescript-children-fc/71809927#71809927
  • https://stackoverflow.com/questions/71841181/some-components-cannot-be-used-as-a-jsx-component
  • 'ReactModal' cannot be used as a JSX component.
    Github
    'ReactModal' cannot be used as a JSX component.
    Updated
    Feb 28, 2025
  • [styled-components] Cannot use forwardRef with styled component
    Github
    [styled-components] Cannot use forwardRef with styled component
    Updated
    Nov 30, 2022