css-loader
는 CSS 파일을 모듈처럼 사용할 수 있도록 해주는 로더이다.
// app.js:
import "./style.css"
/* style.css */
body {
background-color: orange;
}
(리액트에서 컴포넌트 단위 개발 시 위와 같은 상황을 볼 수 있다.)
$ npm install -D css-loader
// webpack.confing.js:
module: {
rules: [{
test: /\.css$/, // css 확장자로 끝나는 모든 파일을 의미
use: ["css-loader"], // css-loader 로더 적용
}],
}
아래와 같이 css 파일 내용을 자바스크립트 코드 내부로 불러 온 것을 볼 수 있다.
DOM에 적용하기 위해서는 style-loader
가 필요하다.
style-loader
는 위에서 자바스크립트로 가져온 css 파일 내용을 style 태그 안에 작성하여 html의 head 태그 안에 넣어줌으로써 스타일이 적용될 수 있게 한다.
$ npm install -D style-loader
// webpack.confing.js:
module: {
rules: [{
test: /\.css$/, // css 확장자로 끝나는 모든 파일을 의미
use: ["style-loader","css-loader"], // style-loader 및 css-loader 로더 적용
}],
}
여기서 로더의 특징 체이닝
이 존재한다.
체이닝
은 로더가 읽어들이는 순서를 의미하는데 로더는 뒤에서 부터 읽어온다.
위의 예시로 보면 css-loader가 먼저 css파일을 불러오고 그 다음 style-loader가 css파일을 style 태그 내에 넣고 html의 head에 넣게 끔 동작하기 위해서 위와 같은 순서로 작성하였다.
file-loader
는 파일을 모듈로써 사용 할 수 있게 해주는 로더이다.
웹팩을 사용하여 png파일을 사용해 보는 예제를 본다면,
react의 예시에서는 아래와 같은 상황을 볼 수 있다.
// App.js:
import MyPicture from "images/my_picture.png";
또는 css 내부에서 url 함수에 이미지 파일 경로를 지정하는 상황을 볼 수 있다.
/* style.css: */
body {
background-image: url(bg.png);
}
위와 같은 방법들에서 웹팩은 png파일이 발견되면 file-loader를 실행시키게 된다.
$ npm install -D file-loader
설치 후에 테스트 해보기 위해서 이미지를 src 내부 안에 넣고 css 파일을 수정하였다.
/* style.css: */
body {
background-image: url(./bg.png);
}
// webpack.confing.js:
module: {
rules: [{
test: /\.png$/, // png 확장자로 끝나는 모든 파일을 의미
use: ["file-loader"], // 파일 로더를 적용한다
}],
}
file-loader는 위에서 적용한 확장자 png 파일을 만나게 되면 설정한 output 경로에 hash값.png이라는 파일이 생성
된다.
이제 output경로에 복사된 파일을 이용하기 위해서는 webpack 설정파일을 조금 더 수정해야 한다.
// webpack.confing.js:
module: {
rules: [{
test: /\.png$/, // png 확장자로 끝나는 모든 파일을 의미
loader: "file-loader", // file-loader 적용
options: {
publicPath: "./dist/", // prefix로 output 경로인 dist폴더를 지정
name: "[name].[ext]?[hash]", // 저장 될 파일 이름 형식
}
}],
}
웹팩 5에서는 Asset Modules를 이용하면 따로 로더를 설치하지 않아도 위와 같이 적용할 수 있다.
asset/resource
emits a separate file and exports the URL. Previously achievable by using file-loader.
그 중 file-loader와 같은 기능을 할 수 있게 하려면 asset/resource
를 이용하면 된다.
module: {
rules: [
...,
{
test: /\.png$/i, // png 확장자로 끝나는 모든 파일을 의미
type: 'asset/resource'
}
],
asset/resource modules의 저장 될 파일 이름 형식의 default 값은
[hash][ext][query]
이기 때문에 위의 예시들처럼 바꾸고 싶다면 assetModuleFilename에 작성하면 된다.output: { filename: "[name].js", path: path.resolve("./dist"), assetModuleFilename: "[name][ext]?[hash]" },
사용하는 이미지 갯수가 많아지게 되면 그에 따라 파일 요청이 많아지는 단점이 있어 Data URL Scheme를 이용하는 방법도 있는데 해당 처리를 자동화 해주는 것이 url-loader
이다.
$ npm install -D url-loader
url-loader에서 보통 파일 중 크기가 일정 크기 미만일 때 url-loader를 사용하고 이상이면 file-loader를 사용한다. 그렇기 때문에 크기가 작은 nyancat.jpg를 src 내부 안에 넣어 테스트 해볼 예정이다.
{
test: /\.(png|jpg|gif|svg)$/i,
use: {
loader: 'url-loader', // url 로더를 설정한다
options: {
publicPath: './dist/', // file-loader와 동일
name: '[name].[ext]?[hash]', // file-loader와 동일
limit: 20000 // 20kb 미만 파일만 data url로 처리
}
}
}
이번에는 png 확장자 뿐만 아니라 jpg, gif, svg등도 적용시키기 위해 위와 같이 작성하였다.
nyancat.jpg가 19KB이기 때문에 적용해보기 위해서 20kb까지 data url로 처리하였다.
웹팩 5에서 url-loader와 같은 효과를 얻기 위해서는 asset
를 이용하면 된다.
{
test: /\.(png|jpg|gif|svg)$/i,
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 20 * 1024, // 기준으로 20kb 로 변경
},
}
}
파일의 크기가 20KB 보다 작으면 inline 모듈로 처리되고(번들에 삽입), 그렇지 않으면 resource 모듈로 처리(별도의 파일로 분리)되기 때문에 output 폴더 에는 bg.png에 대한 파일만 생성된 것을 확인 할 수 있다.
모든 파일을 url-loader로 처리하게 되면 파일 요청 횟수가 줄어든다는 장점이 있지만, 번들파일의 크기가 커진다는 단점이 생긴다. 따라서 크기 제한을 적절히 두는 것이 중요하다고 한다.