Rspack 완벽 가이드 — Webpack 호환 Rust 번들러·마이그레이션·SWC·실전 설정

Rspack 완벽 가이드 — Webpack 호환 Rust 번들러·마이그레이션·SWC·실전 설정

이 글의 핵심

Rspack은 Rust로 구현된 모듈 번들러로, Webpack의 설정·생태계와의 호환성을 의도적으로 유지하면서 빌드 파이프라인의 핵심을 네이티브 성능에 가깝게 옮긴 도구입니다. 이 글에서는 Rspack의 아키텍처적 특징, Webpack에서의 이전 절차, Loader와 Plugin 대응 관계, builtin:swc-loader를 중심으로 한 SWC 통합, React·Vue 프로젝트 구성, 벤치마크 해석 방법, 그리고 Webpack·Rspack·Turbopack의 역할 차이를 한 번에 정리합니다.

선행 지식: 모듈 해석, entry/output, Loader 체인, Plugin 훅에 대한 이해가 있으면 학습 곡선이 완만합니다. Webpack 경험이 있다면 대부분의 개념을 그대로 이어갈 수 있습니다.

들어가며: “Webpack은 익숙한데, 속도만 아쉽다”

프론트엔드 빌드 도구 선택은 팀의 기존 자산(플러그인, 설정, CI 스크립트)성능 목표 사이의 절충입니다. Rspack은 “설정을 거의 그대로 가져가면서도 빌드·HMR을 크게 개선할 수 있는가?”에 대해 에 가깝게 답하려는 프로젝트입니다. 다만 100% 동일한 동작을 보장하는 것은 아니며, 마이그레이션 시에는 동작 차이 목록회귀 테스트가 필수입니다.


1. Rspack이란 무엇인가

1.1 설계 목표

Rspack은 다음을 동시에 추구합니다.

  • Webpack과의 API·설정 유사성: 팀이 익숙한 module.rules, plugins, resolve 등의 개념을 유지합니다.
  • Rust 기반 코어: 핫 경로의 연산을 네이티브 코드로 처리하여 CPU 활용도를 높입니다.
  • SWC 등 고성능 트랜스파일 스택과의 결합: JavaScript·TypeScript 변환을 builtin:swc-loader 등으로 통합하기 쉽습니다.

즉, “완전히 새로운 철학의 도구”라기보다 Webpack 모델을 존중하면서 구현만 고속화한 번들러에 가깝습니다. 이는 Vite가 개발 서버에서 ESM 네이티브 접근을 취하는 방식이나, Turbopack이 Next.js 생태계에 깊게 묶이는 방식과 문제 정의가 다릅니다(후반부에서 비교합니다).

1.2 핵심 개념 정리

개념설명
Compilation 파이프라인Webpack과 유사하게 모듈 그래프를 구성하고 청크로 나눕니다.
Loader파일을 모듈로 변환하는 함수 체인. 일부 Webpack Loader는 그대로 사용하거나 대체재가 존재합니다.
Plugin컴파일 라이프사이클에 훅으로 개입. rspack.DefinePlugin 등 이름이 정렬되어 있습니다.
내장 SWCbuiltin:swc-loader로 Babel·Terser 조합을 대체하는 패턴이 일반적입니다.
Dev Server@rspack/dev-server로 개발 서버·HMR을 구성합니다.

이 구조 덕분에 팀 내 문서·온보딩 자료를 크게 바꾸지 않고도 도구만 교체하는 시도가 가능해집니다.


2. 설치와 기본 프로젝트 뼈대

2.1 패키지 구성

일반적으로 개발 의존성으로 다음을 둡니다.

npm add -D @rspack/core @rspack/cli @rspack/dev-server

@rspack/cli는 로컬 개발·CI에서 rspack 명령을 제공하고, @rspack/dev-serverrspack dev에 대응하는 개발 서버 기능을 담당합니다. 팀 정책에 따라 일부 패키지는 선택적으로 둘 수 있으나, 실무에서는 위 셋을 함께 두는 구성이 가장 흔합니다.

2.2 설정 파일 이름

Webpack 관례에서 webpack.config.js를 쓰었다면, Rspack에서는 rspack.config.js(또는 .mjs, .ts)를 기본으로 사용합니다. 최신 메이저 버전에서는 패키지가 ESM 중심으로 정리되는 추세이므로, Node 버전 요구 사항(예: Rspack 2.x는 Node 20.19+ 또는 22.12+ 등)을 릴리스 노트에서 반드시 확인해야 합니다.

2.3 npm 스크립트 예시

{
  "scripts": {
    "dev": "rspack dev",
    "build": "rspack build",
    "preview": "rspack preview"
  }
}

기존에 webpack serve·webpack --mode production을 쓰던 스크립트를 위와 같이 치환합니다. CI에서 캐시 디렉터리(node_modules/.cache 등)를 보존하면 반복 빌드 시간을 더 줄일 수 있습니다.


3. Webpack에서 마이그레이션하기

3.1 권장 절차

  1. 의존성 인벤토리: 사용 중인 Loader·Plugin·resolve alias·환경 변수 주입 방식을 표로 만듭니다.
  2. 최소 설정으로 부트스트랩: entry/output만 맞춘 뒤 rspack dev로 애플리케이션 기동 여부를 확인합니다.
  3. 규칙 이전: module.rules를 단계적으로 옮기고, 파일 형식별로 스모크 테스트합니다.
  4. 플러그인 매핑: DefinePlugin, Copy 계열 등 이름이 바뀐 항목을 공식 마이그레이션 가이드와 대조합니다.
  5. 프로덕션 최적화: optimization.splitChunks, usedExports 등 프로덕션 전용 옵션을 검증합니다.

한 번에 전부 옮기기보다 브랜치를 짧게 유지하고, 주 단위로 리스크를 나누는 편이 안전합니다.

3.2 자주 만나는 치환

  • webpack.DefinePluginrspack.DefinePlugin
  • copy-webpack-plugin → Rspack이 제공하는 CopyRspackPlugin 등으로 대체
  • CLI 플래그: Rspack 2.x에서는 번들 분석용 --analyze가 CLI에서 제거되었고, Rsdoctor 등 별도 도구로 분석하는 흐름이 권장됩니다.

Webpack 설정에 커스텀 Plugin이 깊게 파고든 경우, Rspack 쪽 훅 지원 범위를 먼저 확인해야 합니다. 내부적으로 Webpack과 다른 엣지 케이스가 존재할 수 있습니다.

3.3 exportsPresence 등 기본값 변화

Rspack 2.x에서는 module.parser.javascript.exportsPresence 기본값이 warn에서 error로 변경된 바 있습니다. 마이그레이션 직후 수많은 타입·export 관련 오류가 한꺼번에 드러날 수 있으므로, 팀은 일시적으로 값을 완화하거나, 코드베이스를 정리한 뒤 엄격 모드로 맞추는 전략을 택할 수 있습니다.


4. Loader와 Plugin 호환성

4.1 Loader

Rspack은 Webpack Loader API와 유사한 계약을 따릅니다. 따라서 순수하게 AST가 아닌 변환을 수행하는 Loader는 그대로 동작하는 경우가 많습니다. 다만 다음은 항상 검증이 필요합니다.

  • 비동기·콜백 패턴과 캐싱(this.cacheable) 사용 방식
  • Pitch Loader 의존 여부
  • Native 애드온을 쓰는 Loader의 플랫폼 호환성

스타일시트·에셋 파이프라인은 프로젝트마다 차이가 크므로, CSS Modules·Sass·PostCSS 조합을 작은 샘플 리포지터리에서 먼저 재현해 보는 것이 좋습니다.

4.2 Plugin

Rspack은 Webpack 사용자에게 익숙한 이름의 내장 Plugin을 제공합니다. 커뮤니티 Webpack Plugin은 그대로 사용 가능한 경우Rspack 전용 포크가 필요한 경우로 나뉩니다. 특히 번들 분석·내부 청크 ID에 의존하는 Plugin은 깨질 확률이 높습니다.

실무에서는 핵심 Plugin 목록을 통과 기준으로 삼고, 나머지는 이슈 트래커에서 호환성을 추적하는 방식이 현실적입니다.


5. SWC 통합과 최적화

Rspack은 SWC를 기본 트랜스파일 경로로 밀접하게 엮습니다. builtin:swc-loader는 JavaScript 구현의 swc-loader와 옵션을 맞추려는 목적을 가지며, Rust 쪽에서 실행되어 프로세스 간 오버헤드를 줄입니다.

5.1 TypeScript 처리 예시

export default {
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: [/node_modules/],
        loader: 'builtin:swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: 'typescript',
            },
          },
        },
        type: 'javascript/auto',
      },
    ],
  },
};

type: 'javascript/auto'는 해당 규칙이 생성하는 모듈 타입을 번들러에 알려 주는 데 사용됩니다. 규칙을 추가할 때마다 테스트·프로덕션 양쪽에서 동일하게 검증해야 합니다.

5.2 JSX와 React

JSX를 사용하는 경우 jsc.parserjsx: true를 주고, jsc.transform.react에서 개발·프로덕션 모드를 분리합니다. Fast Refresh를 쓰는 팀은 React 플러그인·dev 서버 설정을 Rspack 문서의 권장 예제와 맞추는 것이 안전합니다.

5.3 타깃·폴리필

jsc.targetenv.targets동시에 설정할 수 없습니다. 브라우저 범위를 browserslist로 관리하는 팀은 env.targets를, 단순 ES 버전만 낮추면 되는 라이브러리는 jsc.target을 선택하는 식으로 역할을 분리합니다.

env.mode: 'usage'core-js를 주입할 때는 문서에 나온 대로 core-js 패키지를 SWC 처리에서 제외해야 합니다. 이를 빼먹으면 런타임에서 이상 동작이 발생할 수 있습니다.

5.4 rspackExperiments.import

Ant Design 등에서 흔히 쓰던 babel-plugin-import 유사 최적화를 rspackExperiments.import로 이식할 수 있습니다. 함수형 customName 대신 템플릿 문자열을 쓰도록 설계되어 있어, Rust 쪽에서 효율적으로 처리할 수 있습니다. 다만 팀 컨벤션이 복잡한 경우 Babel 층을 유지해야 할 수도 있습니다.

5.5 실험적 최적화와 타입 정보

collectTypeScriptInfo 등은 후속 단계에서 타입 정보를 활용합니다. SWC 이후 Loader가 AST를 깨뜨리지 않는다는 전제가 있으므로, 체인 끝에 이질적인 변환을 붙일 때는 주의가 필요합니다.


6. React 프로젝트 설정

6.1 권장 흐름

  1. @rspack/plugin-react 등 공식·준공식 React Plugin을 검토합니다.
  2. Fast Refresh를 개발 모드에서만 켭니다.
  3. 경로 별칭(resolve.alias)을 tsconfig.jsonpaths와 동기화합니다.

React 18 이후 서버 컴포넌트·프레임워크 번들링은 Next.js 등 별도 스택에서 처리하는 경우가 많습니다. 순수 CSR 앱이라면 Rspack 구성이 단순해집니다.

6.2 설정 스케치

import { defineConfig } from '@rspack/cli';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default defineConfig({
  entry: { main: './src/index.tsx' },
  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
  },
  module: {
    rules: [
      {
        test: /\.(j|t)sx?$/,
        use: {
          loader: 'builtin:swc-loader',
          options: {
            jsc: {
              parser: { syntax: 'typescript', tsx: true },
              transform: { react: { runtime: 'automatic' } },
            },
          },
        },
        type: 'javascript/auto',
      },
    ],
  },
});

프로젝트 규모가 커질수록 TS isolatedModules·경로 별칭을 CI에서도 검증하는 것이 중요합니다.


7. Vue 프로젝트 설정

Vue 3·단일 파일 컴포넌트(SFC) 파이프라인은 Vue Loader 및 관련 Plugin에 의존합니다. Rspack에서도 Webpack 시절과 동일하게 Vue Loader를 규칙에 추가하는 패턴이 일반적입니다.

7.1 체크리스트

  • vue-loader 버전과 Vue 컴파일러 버전을 정확히 맞춥니다.
  • compiler-sfc가 요구하는 Node 범위를 만족하는지 확인합니다.
  • CSS 전처리기(Sass, Less) 규칙을 Vue SFC의 <style lang="...">와 일치시킵니다.

Vue 생태계는 Vite와의 궁합이 널리 알려져 있지만, 기존 Webpack 기반 Vue 앱을 Rspack으로 이전하려는 경우에도 동일한 개념으로 접근할 수 있습니다. 다만 플러그인 호환성 이슈는 재현 가능한 최소 예제로 커뮤니티에 공유하는 것이 해결 속도를 높입니다.


8. 성능 벤치마크: 숫자를 읽는 법

8.1 왜 결과가 제각각인가

벤치마크는 입력 규모, 캐시 상태, Loader 구성, 디스크 속도, CI 병렬도에 크게 좌우됩니다. Rspack이 Webpack 대비 냉 시작 빌드·증분 빌드·HMR에서 유리한 경향이 보고되는 경우가 많지만, 특정 레포지터리에서는 I/O 병목이나 커스텀 Plugin 때문에 격차가 줄어들 수 있습니다.

8.2 비교 시 반드시 고정할 변수

  • 동일한 Node·OS·CPU 전력 정책
  • 깨끗한 node_modules 설치 vs 캐시 재사용
  • 프로덕션 최적화 플래그 동일 여부
  • 소스맵·코드 분할 설정 일치

8.3 대표적인 관찰(정성적)

항목WebpackRspack
냉 시작대규모에서 분 단위로 이어지기 쉬움Rust 코어 덕에 체감상 크게 단축되는 사례가 많음
증분 빌드캐시·스냅샷에 의존변경 그래프 처리가 빠른 편
HMR설정에 따라 느림개발 서버 설정이 맞으면 반응성이 좋아지는 보고가 많음

위 표는 평균을 보장하는 것이 아니라, 커뮤니티·사례 연구에서 반복적으로 등장하는 경향을 요약한 것입니다. 도입 전에는 스테이징 브랜치에서 실제 CI 시간을 측정해야 합니다.


9. Webpack vs Rspack vs Turbopack

기준WebpackRspackTurbopack
성숙도매우 높음, 레거시 호환 광범위빠르게 성장, Webpack 모델 친화Next.js 중심으로 진화
설정 모델사실상 업계 표준Webpack과 유사Next/Vercel 툴링에 최적화
적합한 사용 사례모든 유형Webpack 이전·고성능 필요Next.js 앱 개발 서버 가속
일반 SPA흔함흔함프레임워크 밖 단독 사용은 상대적으로 드묾

Webpack은 여전히 가장 보편적인 기준점입니다. Rspack은 그 설정을 최대한 끌어안으면서 성능을 끌어올리려는 선택지입니다. Turbopack은 Next.js 생태계와 맞물릴 때 강점이 크고, 임의의 Webpack 설정을 그대로 들고 오기보다는 프레임워크가 정한 경로를 따르는 경우가 많습니다.


10. 트러블슈팅과 운영 팁

  • SWC Wasm 플러그인 버전 불일치: SWC 버전과 Wasm 플러그인 빌드 타깃이 맞지 않으면 조용히 실패하거나 이상한 코드가 나올 수 있습니다. 공식 FAQ의 버전 정합성 안내를 따릅니다.
  • export 관련 엄격 오류: Rspack 2의 기본 파서 엄격도 변화로 기존 코드가 깨질 수 있습니다. 팀 차원에서 타입·런타임 export를 정리하는 편이 장기적으로 유리합니다.
  • 분석 도구 전환: CLI --analyze에 의존하던 파이프라인은 Rsdoctor 등으로 스크립트를 갱신합니다.

11. 마무리

Rspack은 “Webpack을 완전히 버리지 않고도 성능을 한 단계 끌어올릴 수 있는가?”에 대한 실무적인 답을 제공합니다. 성공적인 도입은 호환성 표를 만드는 일측정 가능한 성능 목표를 정하는 일에서 시작됩니다. 마이그레이션 후에도 주기적으로 의존성과 Plugin을 감사하고, Rspack 릴리스 노트의 파싱·실험적 옵션 변화를 추적하면 운영 리스크를 줄일 수 있습니다.

공식 문서의 마이그레이션 가이드와 예제 레포지터리를 북마크해 두고, 팀 내에서는 동일한 rspack.config 템플릿을 공유하는 것을 권장합니다.