모노레포에서 형제 패키지 하나를 ESM 쪽에서 가져다 쓰다가 막혔어요.
@repo/ui의 package.json에는 "type" 필드가 없고, exports는 이렇게 돼 있어요. "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs". 쓰는 쪽은 "type": "module"이고 moduleResolution은 nodenext예요.
자, import ui from '@repo/ui' 쓰고 ui(까지 쳐 봤어요. 에디터가 호출할 수 없는 값이래요. ui.을 치니까 자동 완성에 default가 떠요. (여기서 좀 웃겼어요.) 그래서 ui.default()로 바꾸면 타입 검사는 통과하는데, 실행하면 Node는 import 조건으로 진짜 ESM 파일을 읽으니까 거기엔 그런 속성이 없죠.
핸드북 모듈 레퍼런스를 다시 읽어 보니 .d.ts는 가장 가까운 package.json에 "type": "module"이 없으면 CommonJS로 취급된대요. 타입은 CJS 모듈을 보고 런타임은 ESM 모듈을 보는 거예요. ESM에서 CJS를 default import하면 module.exports 전체가 들어오니까 default가 한 겹 더 끼는 거고요.
이거 제일 깔끔하게 고치는 방법이 뭘까요? 조건마다 선언 파일을 따로 두는 거랑, 패키지를 그냥 ESM으로 바꾸는 것 사이에서 고민 중이에요.