Webpack 번들링시 Conflicting order 문제

웅로그·2024년 3월 5일
0
post-custom-banner

webpack으로 번들링시 아래와 같은 문제가 발생함.

원인

css는 코드의 순서가 중요.

mini-css-extract-plugin에서 번들링할 때 css 파일간의 순서 의존성을 파악할 수 없어 css 코드가 합쳐질 때 문제가 생길 수 있기 때문에 나타나는 경고 메세지임.

순서 의존성을 파악할 수 없는 이유는 css를 import하는 컴포넌트들의 상위 컴포넌트들에서 css를 import하는 하위 컴포넌트를 import할 때 해당 컴포넌트의 import 순서가 상위 컴포넌트들마다 다를 때 webpack에서는 css 코드간의 순서를 정확히 파악하여 번들링을 진행할 수 없기 때문.

예시1)

아래와 같은 순서로 컴포넌트들을 import하는 App컴포넌트가 있을 때

1. ZoomSlider
2. SummaryToolpane
3. SearchToolpane

SummaryToolpane는 SearchToolpane 컴포넌트를 import하고 import 순서는 아래와 같을 때 webpack은 css 파일의 순서를 파악할 수 없음.

1. SearchToolpane
2. ZoomSlider

해결 방법은 상위 컴포넌트들에서 css를 직접적으로 import하는 컴포넌트의 임포트 순서를 일관되게 유지하는 것. 예를 들어, 위의 코드에서 모든 컴포넌트의 임포트 순서를 다음과 같이 변경하면 오류를 해결할 수 있다.

1. ZoomSlider
2. SearchToolpane
3. SummaryToolpane

예시2)

  1. 하위 컴포넌트들: ComponentAComponentB라는 두 개의 리액트 컴포넌트가 있다. 각각 A.module.scssB.module.scss를 직접 임포트한다.
  2. 상위 컴포넌트들: ParentComponent1ParentComponent2라는 두 개의 상위 컴포넌트가 있다. 이들은 ComponentAComponentB를 모두 임포트한다.
  3. 임포트 순서 불일치: 문제는 ParentComponent1ComponentA를 먼저, 그 다음에 ComponentB를 임포트하는 반면, ParentComponent2는 반대 순서, 즉 ComponentB를 먼저 그 다음에 ComponentA를 임포트한다는 점입니다.
// ParentComponent1
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';

// ParentComponent2
import ComponentB from './ComponentB';
import ComponentA from './ComponentA';

이러한 불일치는 Webpack에서 CSS 파일을 처리할 때 어떤 순서로 CSS를 번들링해야 할지 혼란을 초래한다. 결과적으로 "Conflicting order" 경고가 발생함.

해결 방안

1. 상위 컴포넌트에서 import 순서를 일관되게 유지

위에서 언급한 것처럼 상위 컴포넌트에서 import 순서를 일관되게 유지해야 한다. 예를 들면 모든 import 순서를 알파벳 순으로 하여 각 컴포넌트마다 import순서를 맞추는 것이다.

2. 번들링시 css 파일마다 청크 생성

아래와 같은 설정을 추가하여 css 파일마다 청크를 생성하면 webpack에서 번들링시 css 파일들을 합치며 순서 의존성을 잃어버리는 일을 방지할 수 있음.

그렇지만 이 방법은 번들링 후에 css 파일들이 너무 많이 생겨 문제가 됨. → 첫 로딩시 css 파일을 받아오며 http 요청을 많이 하게 됨.

optimization: {
    splitChunks: {
      cacheGroups: {
        scss: {
          test: /\.scss$/,
          chunks: 'all',
          enforce: true,
          name(module) {
            // 모듈 경로에서 SCSS 파일 이름을 추출하여 청크 이름으로 사용
            const moduleName = module.identifier().split('/').reduceRight(item => item).split('.')[0];
            return `scss.${moduleName}`;
          }
        }
      }
    }
  }

3. css import를 한 파일로 순서대로 모으기

index.css 같은 한 파일에 다른 css 파일들을 import 해오고 컴포넌트에서는 모든 css가 import 되어 있는 하나의 css 파일만 import하면 webpack은 순서를 제대로 알 수 있다.


CSS 모듈을 쓸 때는 신경쓸 필요가 없다

css 모듈은 최종적으로 해시값을 이용하여 고유한 클래스명을 생성하므로 css 캐스캐이딩 문제를 피할 수 있다. 그러므로 CSS 모듈을 쓸 때는 번들링시 css 순서 의존성 문제는 신경 쓸 필요가 없다. 따라서 아래처럼 무시하는 것이 좋다.

new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
      ignoreOrder: true
    })
profile
프론트엔드 개발자입니다.
post-custom-banner

0개의 댓글