반응형
{
   // 예시 코드!
  "exports": {
    ".": {
      "require": "./src/index.tsx",
      "import": "./src/index.tsx"
    },
    "./index.scss": "./src/index.scss",
  },
  "source": "src/index.tsx",
  "main": "dist/index.js",
  "files": [
    "dist/**"
  ],
  "devDependencies": {
...
  },
  "dependencies": {
....
  },
  "publishConfig": {
    "access": "restricted",
    "registry": "http://####/api/v4/projects/311/packages/npm/",
    "exports": {
      ".": {
        "require": "./dist/index.js",
        "import": "./dist/index.mjs",
        "types": "./dist/index.d.ts"
      },
      "./index.css": "./dist/index.css"
    },
    "import": "./dist/index.mjs",
    "main": "./dist/index.js",
    "module": "./dist/index.mjs",
    "types": "./dist/index.d.ts"
  }
}

 

모노레포에서 개발 경험 향상을 위해서 레포지토리의 package.json의 exports에 원본 코드 파일을(./src/index.ts) 명시하고, 배포할때는 publishConfig 옵션의 exports에 빌드 결과물 파일을 명시해서 사용하고 있다.

 

*export에 빌드 결과물(./dist/index.js)을 적으면 테스트코드를 돌리기 위해서 반드시 모든 레포지토리를 빌드해줘야해서 위 방법을 사용했음

 

RootDir 문제점..?

이랬더니 빌드하면 의존성 있는 레포지토리 내용이 번들링 결과에 포함되는 결과물이 생겼었는데..

 

dist (번들링된 결과물)
└── 기타 파일 etc...
└── packages (다른 레포지토리 결과물)
    ├── @다른 모노레포 1 
    │   ├── designFiles
    │   └── src
    │       ├── index.css
    │       └── index.js
    ├── @다른 모노레포 2
    │   └── src
    │       ├── .eslintrc.js
    │       ├── .eslintcache
    │       ├── .gitignore
    │       └── .npmrc

 

빌드 과정에서 tsconfig.jsoncompilerOptions.rootDir 설정이 다른 타입스크립트 파일을 포함하기 위해서 모노레포의 최상위 레포지토리 루트(./)로 자동 확장되고, 빌드 결과물에 다른 레포지토리의 내용이 함께 번들링되는 문제가 발생한걸로 추측됐다. 

 

이 타입 관련 문제는 typescript 자체적인 문제로 tsup, rollup등 다른 번들러를 써도 동일한 결과가 나올것이라 추측되고 실제로 tsup, rollup 동일하게 발생했다.

 

해결 방법  

해결방법은 생각보다 간단했는데.. 

 

1. peer dependencies

 

이미 다른 레포지토리를 배포했다면 해당 라이브러리를 참조해서 사용하면 된다.

그래서, peerDependencies에 다른 모노레포 레포지토리 명을 적어주면 개발할때는 export에 적어놓은 타입스크립트 원본 파일을 참조하고, 빌드할때는 peerdependencies이니까 자동적으로 다른 레포지토리의 내용이 빌드 결과물에 빠지게 된다.

 

참고로 rollup external 등 여러 옵션을 써봐도 다른 레포지토리의 빌드 결과는 자동적으로 빠지지 않았다. 번들러 입장에서 다른 레포지토리가 정말로 배포되어 있어서 내가 빌드 안해도 되는지 알 방법이 없으니 peerDependendicies로 명시해줘야한다.

 

2. 빌드할때 내 폴더의 타입은 tsc로 따로 빌드함

 

다른 사람들이 쓴 rollup 코드들을 보면 타입은 tsc 등으로 따로 빌드하던데 왜 그런가 했더니.. 이 rootDir문제 때문이 아닐까?

typescript({
          tsconfig: './tsconfig.json',
          tsconfigOverride: {},
          useTsconfigDeclarationDir,
        }),

 

나는 rollup과 rolllup-plugin-typescript2를 사용하고 있는데 useTsconfigDeclarationDir로 타입만 빼고 자바스크립트 파일만 따로 빌드하게 만들었다. 

해당 옵션을 빼면 peerDependencies를 사용해도 동일한 문제가 발생했다.

 

  "scripts": {
    "build": "rollup -c ./rollup.config.mjs",
    "build:types": "tsc --emitDeclarationOnly --declarationMap false --declaration --declarationDir dist/types/client",
  }

 

그리고 tsc로 레포지토리의 타입만 따로 추출한다.


해당 방법이 완벽한 정답이 아닐수도 있긴 하지만.. 일단 pnpm, turbo repo, typescript, rollup을 사용하는 환경에서는 잘 동작하는것 같다. 

반응형

+ Recent posts