내가 esbuild-plugin-babel-next 를 선택한 이유

HumbleMincho·2024년 7월 19일
6
post-thumbnail

개요

정정 게시물 추가. 꼭 봐주세요.

esbuild를 사용해보고 싶어서 next.js세팅 후 설치를 해봤는데 선택권이 여러 개가 있었다.
1. esbuild-loaderwebpack에 세팅하는 법
2. esbuild-plugin-babel-nextnext.config.mjs에 세팅하는 법

근데 난 두번째 방향으로 진행했다. 그 이유는 간단하다. 플젝이 커질지 안커질지 모르니까 우선 작고 간편한 방식을 채택한거다.

상세 비교 내용을 아래에 적어놨으니 확인해보자.


esbuild-loaderesbuild-plugin-babel-next는 모두 Next.js 프로젝트에서 빌드 속도를 향상시키기 위해 esbuild를 활용하는 도구이지만, 사용 방식, 특징, 그리고 적합한 프로젝트 유형에 있어 차이가 있다.

1. 사용 방식 및 통합

esbuild-loader

사용 방식

주로 Webpack 프로젝트에서 기존 Babel 로더대체하여 Webpack 빌드 프로세스 내에서 esbuild를 사용하도록 한다.

통합 방식

Webpack 설정 파일에서 esbuild 옵션을 직접 설정해야 한다. 이는 트랜스파일, 번들링 및 기타 esbuild 관련 작업에 대한 설정을 수동으로 정의하는 것을 의미한다.

esbuild-plugin-babel-next

사용 방식

Next.js 프로젝트에 특화적으로 설계되어 Next.js 빌드 프로세스에 esbuild를 통합한다.

통합 방식

Next.js 설정을 크게 변경하지 않고도 esbuild를 활용할 수 있도록 Next.js 빌드 프로세스와 매끄럽게 통합된다.


2. 성능 및 최적화

esbuild-loader

성능

기존 Babel 로더보다 훨씬 빠른 빌드 속도를 제공하여 성능을 크게 향상시킨다. 이유는 크게...
1. Go 언어가 컴파일 언어기 때문에 실행 자체의 속도가 빠름
2. 병렬프로세스 기능을 사용하여 cpu코어를 효율적으로 활용
3. AST(추상 구문 트리) 기반 트랜스파일
4. 빌드 캐싱기법
5. 번들 재사용
등이 있다.

최적화

특정 프로젝트 요구 사항에 맞게 최적의 성능을 달성하기 위해 esbuild 옵션을 수동으로 구성해야 한다.

esbuild-plugin-babel-next

성능

esbuild의 강점을 활용하여 Next.js 애플리케이션에 최적화된 성능 제공.

최적화

Next.js 프로젝트에 특화된 최적화 및 설정을 자동으로 적용하여 수동 미세 조정의 필요성을 줄인다.


3. 타겟 대상 및 적합성

esbuild-loader

타겟 대상

빠른 빌드 속도와 성능 향상을 추구하는 Webpack 프로젝트, 특히 코드 기반이 크거나 의존성이 복잡한 프로젝트.

적합성

esbuild 옵션에 대한 세밀한 제어와 Webpack 빌드 프로세스 내 통합이 필요한 프로젝트에 적합함.

esbuild-plugin-babel-next

타겟 대상

빠른 프로토타입 제작 및 반복 작업에 중점을 둔 Next.js 프로젝트, 특히 개발 경험의 간소화최적화를 추구하는 프로젝트.

적합성

광범위한 구성이나 통합 노력 없이 esbuild의 성능 이점을 활용할 수 있는 Next.js 프로젝트에 이상적.


올바른 도구 선택

esbuild-loaderesbuild-plugin-babel-next 중 어떤 도구를 선택할지는 프로젝트 유형, 개발 목표 및 기술 전문성에 따라 달라진다.

최대 성능과 esbuild 구성에 대한 제어를 원하는 Webpack 프로젝트: esbuild-loader

Next.js 프로젝트에서 개발 경험을 간소화하고 Next.js 특정 작업에 최적화된 성능을 원하는 경우: esbuild-plugin-babel-next


추가 고려 사항

프로젝트 복잡성: 의존성이 복잡하거나 코드 기반이 큰 프로젝트에서는 esbuild-loader의 세밀한 제어가 유용할 수 있다.
개발 워크플로우: 빠른 프로토타입 제작 및 반복 작업이 중요한 경우 esbuild-plugin-babel-next의 간소화된 통합으로 시간과 노력을 절약할 수 있다.


구현

next.config.mjs

import withEsbuild from "esbuild-plugin-babel-next";
/** @type {import('next').NextConfig} */

// Use:
export default withEsbuild({
  esbuild: {
    // esbuild 옵션
    loader: "tsx", // TypeScript 및 JSX 지원
    target: "es2015", // 대상 ECMAScript 버전
    minify: true, // 프로덕션 빌드시 코드 최소화
    drop_annotations: true, // 주석 제거
    dro_debugger: true, // 디버거 문 제거
  },
  // 기타 Next.js 옵션
  webpack: (config, { dev, isServer }) => {
    // 추가적인 webpack 설정
    return config;
  },
});

종속성 설치

참고로 필자는 yarn 사용한다.

devDependencyesbuild-plugin-babel-next add

~~ % yarn add --dev esbuild-plugin-babel-next
➤ YN0000: · Yarn 4.3.1
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + esbuild-plugin-babel-next@npm:1.0.0
➤ YN0000: └ Completed
➤ YN0000: ┌ Post-resolution validation
➤ YN0002: │ trade-world@workspace:. doesn't provide @babel/core (p47c5e), requested by esbuild-plugin-babel-next.
➤ YN0086: │ Some peer dependencies are incorrectly met by your project; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code.
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0013: │ A package was added to the project (+ 5.44 KiB).
➤ YN0000: └ Completed in 0s 861ms
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed
➤ YN0000: · Done with warnings in 1s 211ms

~~ % yarn dev
node:internal/modules/esm/resolve:844
  throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null);
        ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@babel/core' imported from /Users/jominsu/Documents/workspace/trade-world/node_modules/esbuild-plugin-babel-next/src/index.js
    at packageResolve (node:internal/modules/esm/resolve:844:9)
    at moduleResolve (node:internal/modules/esm/resolve:901:20)
    at defaultResolve (node:internal/modules/esm/resolve:1121:11)
    at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:396:12)
    at ModuleLoader.resolve (node:internal/modules/esm/loader:365:25)
    at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:240:38)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:85:39)
    at link (node:internal/modules/esm/module_job:84:36) {
  code: 'ERR_MODULE_NOT_FOUND'
}

Node.js v20.10.0

위처럼 run 돌렸을 때 에러났더니 봤는데 babel core 필요하다 해서 설치

~~ % yarn add @babel/core
➤ YN0000: · Yarn 4.3.1
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + @babel/core@npm:7.24.9, @types/babel__core@npm:7.20.5, @ampproject/remapping@npm:2.3.0, @babel/code-frame@npm:7.24.7, @babel/compat-data@npm:7.24.9, @babel/generator@npm:7.24.10, @babel/helper-compilation-targets@npm:7.24.8, @babel/helper-environment-visitor@npm:7.24.7, and 43 more.
➤ YN0000: └ Completed in 1s 179ms
➤ YN0000: ┌ Fetch step
➤ YN0013: │ 51 packages were added to the project (+ 9.01 MiB).
➤ YN0000: └ Completed in 1s 17ms
➤ YN0000: ┌ Link step
➤ YN0000: └ Completed in 0s 552ms
➤ YN0000: · Done in 2s 827ms
![](https://velog.velcdn.com/images/watermincho_96/post/4b084460-d1fb-4242-b7c0-03518585cb28/image.png)

아래와 같이 esbuild-plugin-babel-nextpeerDependency에는 기재가 돼있지만 내가 설치 안해서 발생한거임.
esbuild-plugin-babel-next의 package.json


보일러 플래이트 빌드 속도 차이(수정. 의미 없습니다.)

아무것도 얹지 않는 상태에서의 빌드 속도 차이를 수치는 아니지만 비교가 가능하게끔 기록해놓겠다.

esbuild-plugin-babel-next 적용 전

esbuild-plugin-babel-next 적용 후

우선 내가 next.js 빌드 원리 및 순서를 대강 알고 정확하게 모르지만 확실한건 Ready in에 해당하는 시간이 5분의 1수준으로 감소하고 나머지는 0.1~0.5초대 소폭 증가한 수준인건 보인다. 체감으로도 금방되는건 느껴진다. 나중에 프로젝트가 커졌을 때의 차이가 과연 클지도 기대가 된다. (이건 내가 반드시 더 파내고 만다. 어쨌든 할거임)


NEW Insight

새로운 인사이트를 얻어 esbuild-plugin-babel-next 제거했습니다.
자세한건 해당 포스팅을 확인해주세요!

기술 전문성 및 번외

Webpack 구성 및 esbuild 개념을 정확하게 알 필요가 있다. Next.js가 빌드되는 순서부터 파악해보자. 개념도 모르고 개발하는건 더이상 안된다. 시간이 오래걸리더라도 정확히 알고 개발하자. 난 겸손하니까.
번외로, 추후 프로젝트 확장시 esbuild-loader로 마이그레이션할 의지는 있다.

2024.07.22) 댓글과 같이 기본 swc를 사용하면 어떨까 하여 비교 글을 작성할 예정이다.

profile
javascript, typescript, react-native, react.js, next.js

3개의 댓글

comment-user-thumbnail
2024년 7월 21일

혹시 Next.js에서 기본적으로 제공하는 SWC를 쓰지 않으신 이유가 있나요?

2개의 답글