이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌2 - Webpack - 2년 전 등록 / 3달 전 수정

웹팩4로 CSS와 기타 파일 번들링하기

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

안녕하세요. 이번 시간에도 지난 시간에 이어 웹팩4 강좌를 계속 하겠습니다. 오늘은 CSS와 기타 이미지, 폰트 파일을 번들링하는 방법에 대해 알아보겠습니다.

지난 시간 JS는 상식적으로 이해가 가죠? entry에서 시작해서 loader과 plugin의 가공 과정을 거쳐 output으로 나오는 거요. entry의 파일들부터 시작해서 import나 require로 엮어진 모든 js들을 하나 또는 소수의 파일로 묶습니다.

놀라운 것은... import나 require로 css랑 기타 이미지, html 또는 폰트 파일도 묶을 수 있습니다. import랑 require은 자바스크립트 모듈 구문인데 어떻게 그게 가능하냐고요? 저도 정확한 내부 과정은 잘 모르겠지만 그게 가능합니다. 대신 그게 가능하도록 설정을 해주어야 합니다.

일단 CSS부터 번들링하도록 설정해주겠습니다.

npm i -D style-loader css-loader extract-text-webpack-plugin@next

extract-text-webpack-plugin은 꼭 next 버전임을 확인하세요! 그래야 웹팩4 이상과 사용이 가능합니다. css-loader는 css 파일들을 읽어주고 style-loader는 읽은 css 파일들을 style 태그로 만들어 head 태그 안에 넣어줍니다. 만약 style 태그 대신 css파일로 만들고 싶은 경우에 extract-text-webpack-plugin을 사용하면 됩니다.

{
  module: {
    rules: [{
      // 전 시간 babel-loader
    }, {
      test: /\.css$/,
      use: ['style-loader', 'css-loader'],
    }],
  }
}

위와 같이 하면 됩니다. test 부분은 css파일에 적용하는 거라서 익숙한데 loader 대신 use가 있습니다. 여러 개의 로더를 동시에 사용할 때는 use를 사용합니다. (사실 loader 그대로 해도 됩니다) 아, 로더는 연달아서 사용이 가능합니다. babel-loader처럼 하나로 사용할 수도 있지만, style-loader과 css-loader처럼 두 개를 한 번에 사용할 수도 있습니다. 나중에 less-loader, sass-loader, postcss-loader과 함께 세 네개를 동시에 사용하기도 합니다. 먼저 css-loader로 처리한 뒤 그것을 style-loader로 한 번 더 처리하는 겁니다.

이제 entry의 js파일 상단에서 require('app.css');를 하면 알아서 읽어서 style 태그로 만들어줍니다. 신기하죠?

지금까지의 방법은 css를 style 태그로 만드는 거였습니다. 이제는 따로 css 파일을 만드는 방법을 살펴보겠습니다. 아까 설치한 extract-text-webpack-plugin을 사용합니다. webpack.config.js 제일 윗 부분에 require 해줍니다.

const ExtractTextPlugin = require('extract-text-webpack-plugin');

style-loader를 대체하지만 플러그인인만큼 module과 plugins에 모두 써줘야 합니다.

{
  module: {
    rules: [{
      // 전 시간 babel-loader
    }, {
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: 'css-loader'
      }),
    }],
  },
  plugins: [
    // 기타 플러그인
    new ExtractTextPlugin({
      filename: 'app.css',
    });
  ]
}

fallback은 이 플러그인이 실패했을 때 대안으로 style-loader가 작동함을 의미합니다. 안의 use는 css-loader를 거친 후 extract-text-webpack-plugin으로 파일을 추출하겠다는 뜻입니다.

이제 webpack을 실행하면 output에서 설정한 path 경로에 app.css라는 파일이 생겼을 겁니다. 그 파일을 기존에 css를 넣던 방식대로 link 태그로 head에 넣어주면 됩니다.

참고로 서버 사이드에서 사용할 때는 style-loader와 css-loader 대신 css-loader/locals로 적어주면 됩니다. 서버는 css를 지원하지 않기 때문에 다르게 사용해야 합니다. 여기서 에러가 많이 나는데 절대로 style-loader를 넣어서는 안 됩니다! style-loader는 서버 사이드 렌더링을 지원하지 않습니다.

나중에 더 나아가 css modules(css-loader?modules)나 postcss(postcss-loader)를 사용할 수도 있는데 그것까지는 다루지 않겠습니다. 공식 문서에 잘 나와있습니다.

이번에는 기타 파일들에 대한 번들링 방법을 알아보겠습니다. 먼저 추가적인 로더를 설치해줍니다.

npm i -D file-loader url-loader

file-loader는 특정 파일을 그대로 내보내줍니다. 아무리 그래도 png랑 js랑 합친다는 건 말이 안 되죠? 웹팩도 한계가 있습니다. url-loader가 좀 특이합니다. 설정한 사이즈보다 작은 이미지나 폰트 파일을 인라인화 합니다. 아니 이미지랑 폰트를 어떻게 인라인화 하냐고요? base64로 인코딩하면 됩니다. base64가 뭐냐고요? 다음과 같은 겁니다. 

undefined

엄청나게 길죠? data-uri라고도 하는데요. 작은 파일은 따로 http 요청을 하느니 그냥 문자열로 인코딩해서 불러오겠다는 고육지책입니다. 원래라면 이미지 주소를 써야할 곳에 data:image/타입;base64, 이렇게 한 후 인코딩한 문자열들을 넣어주면 브라우저가 이미지로 인식합니다.

{
  module: {
    rules: [{
      ... // 바벨로더와 css 로더들
    }, {
      test: /\.(ico|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
      loader: 'url-loader',
      options: {
        name: '[hash].[ext]',
        limit: 10000,
      },
    }],
  }
}

test 부분이 길어졌습니다. 다양한 파일들을 지원하려고 하는 만큼 정규식도 길어집니다. options가 중요합니다. limit(바이트 단위)보다 작은 파일은 base64로 인코딩해서 인라인화합니다. name에서는 지난 시간 output처럼 [hash], [name] 등을 쓸 수 있습니다. [ext]는 현재 확장자를 그대로 하겠다는 뜻입니다. 잠깐, 인라인화 하는데 결과물 이름은 왜 적어줄까요? 바로 limit보다 큰 파일은 알아서 file-loader가 처리하여 파일로 내보내주기 때문입니다.

역시 js 파일에서 require('./이미지경로/zero.png');같이 하면 알아서 인라인화하거나 파일로 만들고 경로도 알아서 연결해줍니다. 아까 css보다 더 신기하죠? 리액트의 경우 보통 아래처럼 사용합니다.

<img src={require('이미지경로')} />

이미지나 폰트 외의 다른 파일(html, jade, pug, ejs)은 각각에 해당하는 로더가 다 있기 때문에 그걸 사용하시면 됩니다. 역시 import나 require을 하면 알아서 웹팩이 다 해결해줍니다. 웹팩 만세!

용량 관계로 다음 시간에 웹팩의 강력한 기능 중 하나인 코드 스플리팅청크에 대해 알아보겠습니다.

투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

3개의 댓글이 있습니다.
2달 전
감사합니다~ 웹팩은 참 볼때마다 신기하기도하고 감사하기도 하고ㅋㅋㅋ 그런 라이브러리 네요:) url-loader에서 이미지랑 폰트를 인라인화 한다는 건, 이미지나 폰트의 바이너리(?) 코드를 인코딩해서 그대로 html에 포함시킨다는 거겠죠?
2달 전
네네 바이너리를 data-uri로 인코딩해서 포함시키는 거죠.
2달 전
감사합니다!
3달 전
npm i -D style-loader css-loader extract-text-wepback-plugin 부분에 wepback 오타 있습니다 : )
3달 전
감사합니다. 수정했습니다.
일 년 전
강좌 잘 보고 있습니다.~
npm 설치하는데 extract-text-wepback-plugin wepback 으로 되있네요~ㅎ

css 설정 부분에 test 가... text 로...
일 년 전
감사합니다~