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)
ComponentA
와 ComponentB
라는 두 개의 리액트 컴포넌트가 있다. 각각 A.module.scss
와 B.module.scss
를 직접 임포트한다.ParentComponent1
과 ParentComponent2
라는 두 개의 상위 컴포넌트가 있다. 이들은 ComponentA
와 ComponentB
를 모두 임포트한다.ParentComponent1
이 ComponentA
를 먼저, 그 다음에 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" 경고가 발생함.
위에서 언급한 것처럼 상위 컴포넌트에서 import 순서를 일관되게 유지해야 한다. 예를 들면 모든 import 순서를 알파벳 순으로 하여 각 컴포넌트마다 import순서를 맞추는 것이다.
아래와 같은 설정을 추가하여 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}`;
}
}
}
}
}
index.css 같은 한 파일에 다른 css 파일들을 import 해오고 컴포넌트에서는 모든 css가 import 되어 있는 하나의 css 파일만 import하면 webpack은 순서를 제대로 알 수 있다.
css 모듈은 최종적으로 해시값을 이용하여 고유한 클래스명을 생성하므로 css 캐스캐이딩 문제를 피할 수 있다. 그러므로 CSS 모듈을 쓸 때는 번들링시 css 순서 의존성 문제는 신경 쓸 필요가 없다. 따라서 아래처럼 무시하는 것이 좋다.
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
ignoreOrder: true
})