정정 게시물 추가. 꼭 봐주세요.
esbuild를 사용해보고 싶어서 next.js
세팅 후 설치를 해봤는데 선택권이 여러 개가 있었다.
1. esbuild-loader
를 webpack
에 세팅하는 법
2. esbuild-plugin-babel-next
를 next.config.mjs
에 세팅하는 법
근데 난 두번째 방향으로 진행했다. 그 이유는 간단하다. 플젝이 커질지 안커질지 모르니까 우선 작고 간편한 방식을 채택한거다.
상세 비교 내용을 아래에 적어놨으니 확인해보자.
esbuild-loader
와 esbuild-plugin-babel-next
는 모두 Next.js 프로젝트에서 빌드 속도를 향상시키기 위해 esbuild를 활용하는 도구이지만, 사용 방식, 특징, 그리고 적합한 프로젝트 유형에 있어 차이가 있다.
주로 Webpack
프로젝트에서 기존 Babel 로더
를 대체
하여 Webpack
빌드 프로세스 내에서 esbuild
를 사용하도록 한다.
Webpack
설정 파일에서 esbuild
옵션을 직접 설정해야 한다. 이는 트랜스파일
, 번들링
및 기타 esbuild
관련 작업에 대한 설정을 수동
으로 정의하는 것을 의미한다.
Next.js
프로젝트에 특화적으로 설계되어 Next.js
빌드 프로세스에 esbuild
를 통합한다.
Next.js
설정을 크게 변경하지 않고도 esbuild
를 활용할 수 있도록 Next.js
빌드 프로세스와 매끄럽게 통합된다.
기존 Babel 로더보다 훨씬 빠른 빌드 속도를 제공하여 성능을 크게 향상시킨다. 이유는 크게...
1. Go 언어가 컴파일 언어기 때문에 실행 자체의 속도가 빠름
2. 병렬프로세스 기능을 사용하여 cpu코어를 효율적으로 활용
3. AST(추상 구문 트리) 기반 트랜스파일
4. 빌드 캐싱기법
5. 번들 재사용
등이 있다.
특정 프로젝트 요구 사항에 맞게 최적의 성능을 달성하기 위해 esbuild
옵션을 수동으로 구성해야 한다.
esbuild
의 강점을 활용하여 Next.js
애플리케이션에 최적화된 성능 제공.
Next.js
프로젝트에 특화된 최적화 및 설정을 자동으로 적용하여 수동 미세 조정의 필요성을 줄인다.
빠른 빌드 속도와 성능 향상을 추구하는 Webpack
프로젝트, 특히 코드 기반이 크거나 의존성이 복잡한 프로젝트.
esbuild
옵션에 대한 세밀한 제어와 Webpack
빌드 프로세스 내 통합
이 필요한 프로젝트에 적합함.
빠른 프로토타입 제작 및 반복 작업에 중점을 둔 Next.js
프로젝트, 특히 개발 경험의 간소화
및 최적화
를 추구하는 프로젝트.
광범위한 구성이나 통합 노력 없이 esbuild
의 성능 이점을 활용할 수 있는 Next.js
프로젝트에 이상적.
esbuild-loader
와 esbuild-plugin-babel-next
중 어떤 도구를 선택할지는 프로젝트 유형, 개발 목표 및 기술 전문성에 따라 달라진다.
최대 성능과 esbuild
구성에 대한 제어를 원하는 Webpack
프로젝트: esbuild-loader
Next.js
프로젝트에서 개발 경험을 간소화하고 Next.js
특정 작업에 최적화된 성능을 원하는 경우: esbuild-plugin-babel-next
프로젝트 복잡성
: 의존성이 복잡하거나 코드 기반이 큰 프로젝트에서는 esbuild-loader
의 세밀한 제어가 유용할 수 있다.
개발 워크플로우: 빠른 프로토타입 제작 및 반복 작업이 중요한 경우 esbuild-plugin-babel-next
의 간소화된 통합으로 시간과 노력을 절약할 수 있다.
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 사용한다.
devDependency
로 esbuild-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

아래와 같이 esbuild-plugin-babel-next
의 peerDependency
에는 기재가 돼있지만 내가 설치 안해서 발생한거임.
아무것도 얹지 않는 상태에서의 빌드 속도 차이를 수치는 아니지만 비교가 가능하게끔 기록해놓겠다.
esbuild-plugin-babel-next 적용 전
esbuild-plugin-babel-next 적용 후
우선 내가 next.js
빌드 원리 및 순서를 대강 알고 정확하게 모르지만 확실한건 Ready in
에 해당하는 시간이 5분의 1수준
으로 감소하고 나머지는 0.1~0.5초
대 소폭 증가한 수준인건 보인다. 체감으로도 금방되는건 느껴진다. 나중에 프로젝트가 커졌을 때의 차이가 과연 클지도 기대가 된다. (이건 내가 반드시 더 파내고 만다. 어쨌든 할거임)
새로운 인사이트를 얻어 esbuild-plugin-babel-next 제거했습니다.
자세한건 해당 포스팅을 확인해주세요!
Webpack
구성 및 esbuild
개념을 정확하게 알 필요가 있다. Next.js가 빌드되는 순서부터 파악해보자. 개념도 모르고 개발하는건 더이상 안된다. 시간이 오래걸리더라도 정확히 알고 개발하자. 난 겸손하니까.
번외로, 추후 프로젝트 확장시 esbuild-loader
로 마이그레이션할 의지는 있다.
2024.07.22) 댓글과 같이 기본 swc를 사용하면 어떨까 하여 비교 글을 작성할 예정이다.
혹시 Next.js에서 기본적으로 제공하는 SWC를 쓰지 않으신 이유가 있나요?