Webpack4 Code splitting 과 동적 import

sy.kim·2025년 12월 4일
post-thumbnail

실무 프로덕트의 프론트엔드는 Ruby on Rails 환경에서 Webpacker 를 통해, webpack 4 을 이용한 asset 번들링을 하고 있어요.

동적 import 사용해서 작업해주신 팀원 분과 논의하던 중 webpack code-splitting 과 동적 import 개념을 다시 살펴보았습니다.

webpack의 생성방식과 Chunk

웹팩은 모던 자바스크립트 앱을 위한 정적 번들러입니다.
Entry Point 를 통해 의존성을 추적하고, 모듈들을 Chunk로 그룹화해서 Bundle 파일로 만들어줘요.

모듈은 import 가능한 모든 파일이며, Chunk는 번들링 과정의 중간 산출물, Bundle은 브라우저에서 로드되는 실제 파일이라고 보시면 됩니다.

Chunks

중간 산출물인 Chunk는 두 가지의 생성 방식이 있어요.

1.Initial: Entry Point 기반, 페이지 로드 시 즉시 다운로드 되는 HTML에 직접 포함되는 번들.

Initial chunks contain all modules and dependencies specified for an entry point.

2.Non-Initial: 동적 로드를 위한 번들

Non-initial chunks are lazy-loaded separately, typically created through dynamic imports or code-splitting strategies.

아래 문서에도 적혀있지만, initial인 경우 이름을 따라 생성되지만, non-initial 인 경우는 중복되지 않는 id 값으로 자동 생성돼요.

By default, there is no name for non-initial chunks so that a unique ID is used instead of a name.

https://webpack.js.org/concepts/
https://webpack.js.org/concepts/under-the-hood/#chunks

Code-Spliting

code splitting을 사용하면 코드를 여러 번들로 분할하여 필요에 따라 또는 병렬로 로드할 수 있습니다.
더 작은 번들로 쪼개서 활용할 수 있는 기능이라고 보시면 됩니다.

다음 세 가지 접근 방법으로 code splitting 기능을 구현할 수 있는데요,

  • Entry Points: Manually split code using entry configuration.
  • Prevent Duplication: Use the SplitChunksPlugin to dedupe and split chunks.
  • Dynamic Imports: Split code via inline function calls within modules.

이번에는 동적 import 를 통해 code splitting 을 구현했습니다.

  splitChunks: {
    chunks: 'all',
    name: true,
  },

environment 에 name 값을 설정해서 chunks를 분리하도록 합니다.

https://v4.webpack.js.org/guides/code-splitting/
https://v4.webpack.js.org/plugins/split-chunks-plugin/#splitchunksname

Bundle 의 path와 이름은 어떻게 결정될까?

non-initial chunk인 경우는 중복되지 않는 id 값으로 자동 생성된다고 했습니다.
그 전에 output은 어떤식으로 설정되는지 짚고 넘어갑시다.

Public output 구조

public/packs/js/page/MainPage-eea4ad22932cbfe2c26a.chunk.js
└─┬──┘ └─┬─┘└┬┘ └─────┬─────┘ └────────┬─────────┘└───┬───┘
  │      │   │        │                │              │
  ①     ②   ③        ④               ⑤              ⑥

① public/ : Rails Public Root

설정 위치: config/webpacker.yml
public_root_path: public

② packs/ : Webpacker Output Path

설정 위치: config/webpacker.yml
public_output_path: packs

③ js/ : Chunk Filename Prefix

④ page/MainPage : Chunk Name
⑤ -eea4ad22932cbfe2c26a : 해시
⑥ .chunk.js : File 확장자

설정 위치: config/webpack/environment.js
chunkFilename: 'js/[name]-[contenthash].chunk.js',

Webpacker 설정 기준으로 정리한 점 참고 부탁드립니다.

name을 설정하려면?

그러면 non-initial인 경우, name이 id 로 들어오지 않고 모듈의 이름으로 들어오게 하려면 어떻게 해야할까요?
그럴 때 주석으로 Magic Comment를 설정하면 됩니다.

Magic Comment 있을 때:

const MainPage = React.lazy(() =>
  import(/* webpackChunkName: "page/MainPage" */ './Page/MainPage')
  //                          ^^^^^^^^^^^^^^^
  //                          [name]에 들어갈 값
);

생성 과정:
chunkFilename 패턴: js/[name]-[contenthash].chunk.js
                       ^^^^^^
                       "page/MainPage" 대입

결과: js/page/MainPage-eea4ad22932cbfe2c26a.chunk.js

Magic Comment 없을 때:

const MainPage = React.lazy(() =>
  import('./Page/MainPage')
  // webpackChunkName이 없음!
);

생성 과정:
chunkFilename 패턴: js/[name]-[contenthash].chunk.js
                       ^^^^^^
                       Webpack이 자동으로 숫자 ID 할당 (1, 2, 3, ...)

결과: js/1-eea4ad22932cbfe2c26a.chunk.js
     js/2-f1b52411c84c06b72.chunk.js
     js/3-a2b3d6a34331c201b.chunk.js

magic comment 없을 때

https://v4.webpack.js.org/api/module-methods/#magic-comments

Magic Comment 는 설정해야할까?

Magic Comment 를 설정하면 동적 import 시 여러 유용한 설정을 할 수 있으나, 필수는 아닙니다.
webpackChunkName 을 설정하지 않는 경우 위 처럼 숫자 id 가 할당 되니 에러가 발생할 일도 없어요.

그러나 번들 출력물을 명시적으로 확인하거나 기타 설정을 위해서 사용하는 것이라고 봐야할 것 같습니다.
(설정하는 것이 다소 귀찮으나...)

정리

동적 import 와 함께 React.lazy()를 사용하면 SPA 에서 컴포넌트가 필요할 때 필요한 번들을 로딩하여 Code Splitting 을 구현할 수 있습니다.

profile
프론트엔드 개발자

0개의 댓글