# Cjs 최적화 패스 작업 기록



- [PR](https://github.com/vercel/next.js/pull/49972)

간단한 PR이었기는 한데 그래도 기록해두려고 한다.
작업을 시작한 건 슬랙에서 middleware 번들 사이즈 관련 얘기가 나와서다.
next의 일부분만 임포트하는데 cjs로 컴파일 되어있어서 트리 셰이킹이 작동하지 않는다는 얘기였다.
cjs 모듈을 직접 짜는 사람은 거의 없고 대부분 ESM으로 임포트한 뒤 common js로 컴파일하니까, 패턴을 인식해서 최적화 할 수 있을 것 같다고 했다.

그래서 내가 구현해주겠다고 하고 작업 시적했다.
일단 `require` 호출을 인식하는 비지터를 만들고 `modularize-import`의 코드를 베껴와서 `require` 호출을 변경해도록 했다.
코드를 베껴오는 건 내 전문이라 진짜 금방 했다.
그런데 테스트를 추가하고 리뷰 요청하니까 설정이 더 자세해야한다고 얘기했다.
내가 구현한 설정은 `modularize-import`랑 똑같았다.

```json
{
  "packages": {
    "next/server": {
      "transform": "next/server/{{ kebabCase member }}"
    }
  }
}
```

이게 설정인데, `next/server` 같은 경우

```js
const serverExports = {
  NextRequest: require("next/dist/server/web/spec-extension/request")
    .NextRequest,
  NextResponse: require("next/dist/server/web/spec-extension/response")
    .NextResponse,
  ImageResponse: require("next/dist/server/web/spec-extension/image-response")
    .ImageResponse,
  userAgentFromString: require("next/dist/server/web/spec-extension/user-agent")
    .userAgentFromString,
  userAgent: require("next/dist/server/web/spec-extension/user-agent")
    .userAgent,
};
```

처럼 컴파일된다더라.
그래서 아예 모든 걸 직접 설정할 수 있게 바꿨다.
설정 코드가 좀 길어지겠지만 별 수 없는 상황이었다.

```json
{
  "packages": {
    "next/server": {
      "transforms": {
        "Response": "next/server/response"
      }
    }
  }
}
```

새로 구현된 설정은 이런 식이다.
`require('next/server').Response`를 `next/server/response`로 컴파일하라는 뜻이다.
물론 `require`한 결과물을 변수에 할당했다가 사용하는 경우를 지원하는 것이다.
여기까지 하고 리뷰 요청했는데, 리뷰 보니까 내가 새로 구현한 패스를 `next-swc`랑 연결하는 걸 까먹었더라.
`unresolved_mark`를 어떻게 넘겨야하는지 모르겠다고 하셔서 내가 고치고 다시 리뷰 요청했다.

