Turbopack: Next.js 16.2의 새로운 기능들
Next.js가 Turbopack을 기본 번들러로 채택한 지 두 릴리스가 지났습니다. 이제 저희는 성능 개선, 버그 수정, 그리고 호환성 강화에 집중하고 있습니다.
Next.js 16.2에서 새롭게 탑재된 주요 기능들을 소개해드리겠습니다.
- Server Fast Refresh: 세밀한 서버 측 핫 리로딩
- Web Worker Origin: Workers 내 WASM 라이브러리 지원 확대
- Subresource Integrity 지원: JavaScript 파일에 대한 서브리소스 무결성
- 동적 Import 트리 셰이킹: 불필요한 export를 동적 import()에서 제거
- 인라인 로더 설정: import attributes를 통한 import별 로더 설정
- Lightning CSS 설정: 실험적 LightningCSS 설정 옵션
- 로그 필터링: ignoreIssue로 불필요한 로그와 경고 억제
- postcss.config.ts 지원: TypeScript PostCSS 설정
- 성능 개선 및 버그 수정: 200개 이상의 개선 사항과 버그 수정
다음 릴리스에서는 컴파일러 성능을 높이고 메모리 사용량을 줄이는 데 집중할 예정입니다.
Server Fast Refresh
서버 측 코드가 개발 중에 리로드되는 방식을 완전히 재설계했습니다. 기존 시스템은 변경된 모듈과 그것의 전체 import 체인에 속한 모든 모듈의 require.cache를 비웠습니다. 이 방식은 변경되지 않은 node_modules까지 포함해서, 필요 이상으로 많은 코드를 리로드했거든요.
새로운 시스템은 브라우저에서 사용하는 Fast Refresh 방식을 그대로 서버 코드에 적용합니다. Turbopack이 모듈 그래프를 정확히 파악하기 때문에 실제로 변경된 모듈만 리로드하고 나머지는 그대로 유지합니다. 덕분에 서버 측 핫 리로딩이 훨씬 더 효율적이 됩니다.
실제 Next.js 애플리케이션에서는 애플리케이션 새로고침이 67~100% 빨라졌고, Next.js 컴파일 시간은 400~900% 단축되었습니다. 작은 "hello world" 프로젝트부터 vercel.com 같은 대규모 사이트까지 모든 규모에서 이런 개선이 나타납니다.
| Before | After | |
|---|---|---|
| Next.js | 40ms | 2.7ms |
| Application | 19ms | 9.7ms |
375% 더 빠른 서버 새로고침 속도
이 기능은 이제 모든 개발자를 위해 기본으로 활성화됩니다. 현재 Proxy와 Route Handlers는 기존 시스템을 사용하지만, 곧 이들도 지원할 예정입니다. 피드백이나 문제가 있으신 분들은 GitHub에서 알려주세요.
Web Worker Origin
예전엔 Web Workers를 blob:// URL을 통해 부트스트랩했습니다. 워커 로딩을 간단하게 만들었지만, location.origin 값이 비어있게 되었거든요. 워커 코드에서 importScripts()나 fetch()를 사용하려던 시도(특히 서드파티 라이브러리에서)는 수정 없이는 요청을 해결할 수 없었습니다.
업데이트된 Worker 부트스트랩 코드로는 origin이 정확히 여러분의 도메인을 가리키고, 상대 경로 fetch도 제대로 작동합니다. 이전 버전에서 Worker 내 WASM 코드 실행에 어려움을 겪었던 분들이 이제 문제없이 사용할 수 있을 겁니다.
Subresource Integrity 지원
Turbopack이 이제 Subresource Integrity(SRI)를 지원합니다. SRI는 빌드 시점에 JavaScript 파일의 암호화 해시를 생성해서 브라우저가 파일 변조 여부를 검증할 수 있게 합니다.
브라우저의 Content Security Policy는 실행할 수 있는 JavaScript를 제한해서 보안 이슈를 원천 차단할 수 있습니다. 다만 일반적인 nonce 기반 구현은 모든 페이지를 동적으로 렌더링해야 해서 성능에 영향을 미칩니다. SRI는 대안으로, 각 스크립트의 해시를 미리 계산하고 승인된 해시를 가진 스크립트만 실행하도록 허용합니다.
// next.config.js
const nextConfig = {
experimental: {
sri: {
algorithm: 'sha256',
},
},
};
module.exports = nextConfig;
동적 Import의 트리 셰이킹
Turbopack이 이제 구조 분해된 동적 import도 정적 import처럼 트리 셰이킹합니다. 번들에서 사용하지 않는 export가 제거됩니다.
const { cat } = await import('./lib');
이제 이 코드는 트리 셰이킹 목적상 정적 import와 동일합니다. ./lib에서 사용하지 않는 export는 모두 제거됩니다.
인라인 로더 설정
Turbopack이 import attributes를 통한 import별 로더 설정을 지원합니다. turbopack.rules로 전역 로더를 설정하는 대신, with 절을 사용해서 개별 import에 설정할 수 있습니다.
import rawText from './data.txt' with {
turbopackLoader: 'raw-loader',
turbopackAs: '*.js',
};
import value from './data.js' with {
turbopackLoader: 'string-replace-loader',
turbopackLoaderOptions: '{"search":"PLACEHOLDER","replace":"replaced value"}',
};
같은 파일 타입의 다른 import에 영향을 주지 않으면서 특정 import만 특수 처리가 필요할 때 유용합니다. 사용 가능한 attributes는 turbopackLoader, turbopackLoaderOptions, turbopackAs, turbopackModuleType입니다.
가능하면 next.config.ts에서 로더를 설정하는 것이 좋습니다. 인라인 로더를 사용한 코드는 이식성이 떨어지거든요. 이 옵션은 플러그인이나 로더가 생성한 코드에서 더 유용합니다.
Lightning CSS 설정
Lightning CSS는 빠르고 Rust 기반의 CSS 변환 도구로 Turbopack에서 사용됩니다.