webpack 두렵지 않아요 - webpack.config.js 상세

Hoony·2022년 7월 6일
1

mode, entry, output에 대해서 알아보았는데 3개의 option만 있는것은 아니다.
entry, output, module, plugins, resolve와 같은 옵션들을 좀 더 자세하게 알아보자.

entry

앞의 글에서 설명한 것 처럼, entry는 bundle을 하기 위한 진입점이다.
가장 먼저 호출되는 javascript가 진입점이 된다고 보면 된다.
entry는 일반적으로는 하나이지만, multiple entry도 가능하다.

multiple entry를 구성해보진 않아서 가능하다는 것만 이야기하고 생략한다.
아래와 같은 usecase가 있다.
https://developpaper.com/practice-of-multi-entry-configuration-of-webpack-by-hand/

output

번들링 된 파일에 대한 설정이다.
일반적으로 설정시에는 path와 filename을 분리하여 설정한다.
이 설정에서는 브라우저의 캐싱을 회피하기 위한 설정방법이 있다.
(cache와 관련되어서는 더 알아봐야 한다.)

브라우저 캐시
브라우저는 응답속도를 높이기 위해 이전에 불렀던 리소스들을 재활용하는 방법을 쓴다.
a.png를 처음 호출하면 HTTP를 통해 받아와 브라우저의 캐시 스토리지에 저장한다.
다음에 똑같은 페이지가 호출되면 브라우저는 첫 a.png를 받아오면서 알게된 만료시간전까지는
a.png를 캐시 스토리지에 저장하고있는 것을 렌더링함으로써 request를 줄여 브라우저 속도를 높인다.
같은 리소스인지를 비교하는 방법은 이름으로 비교를 한다.
만약 서버에서 a.png 파일을 변경했다 하더라도 만료기간이 남아있고
파일의 이름이 같기 때문에 브라우저는 변화된 이미지를 렌더하지 못할 수 있다.

  • contenthash 파일의 content를 기반으로 hash값 생성
  • chunkhash entry 기반으로 hash 생성

아래와 같이 설정하면, build시 매번 js의 이름이 변경되어
브라우저가 항상 최신의 build 파일을 받아오도록 할 수 있다.

    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.[chunkhash].js'
    }, // bunlde.asdf3dsff.js 와 같이 생김

module

모듈은 javascript가 아닌 리소스들을 javascript로 번들하기 위해
리소스를 어떻게 해석하는지 알려주기 위해 사용된다.

예를 들어, css 파일을 import하면 webpack은 어떻게 해석해야될지 몰라 error를 뱉는다.
이 해석을 돕는 것이, loader들이다.

css와 scss를 해석하기 위해 아래의 loader를 설치하자.
loader는 https://webpack.kr/loaders/ 공식 webpack 사이트에서 잘 정리해두었다.

npm install -D style-loader, css-loader, sass-loader

webpack.config.js의 module부분을 아래와 같이 설정한다.
그러면, webpack이 loader가 제시하는 방향대로 해석하여
javascript에 잘 번들링시켜준다.

// scss 예제
{
	module: {
		rules: [
			{
				test: /\.(sc|c)ss$/,
				use: ['style-loader', 'css-loader', 'sass-loader']
			}
		]
	}
}

loader channing
loader는 어떠한 순서로 들어가냐에 따라서 해석이 달라진다.
만약, styled-loader와 css-loader의 순서가 바뀐다면 정상동작 하지 않는다.
먼저 해석되었으면 하는 loader를 배열의 뒤쪽으로 위치시키면 된다.

plugins

plugins은 bunling한 결과의 포맷에 영향을 줄때,
webpack을 쓰면서 도움되는 기능들을 쓰고 싶을때 사용한다.

대표적인 HtmlWebpackPlugin은 아래와 같이 사용되었을 때
/src/index.html에 bundle된 파일을 자동으로 mapping 시켜준다.
앞에서처럼 script를 직접 넣어주지 않아도 plugin이 알아서 해준다는 말이다.

plugin들도 https://webpack.kr/loaders/ 공식 홈페이지에 많이 정리되어 있다.
필요한 plugin을 설치하고 instance화 하여 사용하면 된다.

    plugins: [
        new HtmlWebpackPlugin({ template: "./src/index.html"}),
        new CleanWebpackPlugin(),
    ]

resolve

resolve에서 많이 사용하는 옵션은 alias와 extensions이라는 하위 옵션이 있다.
더 다양한 옵션들은 똑같이 공식문서에서 확인하자.

alias

공식 문서에 따르면 alias는 말 그대로 별칭 옵션인데 아래와 같이 사용한다고 한다.

const path = require('path');

module.exports = {
  //...
  resolve: {
    alias: {
      Utilities: path.resolve(__dirname, 'src/utilities/'),
      Templates: path.resolve(__dirname, 'src/templates/'),
    },
  },
};
import Utility from '../../utilities/utility'; 
// 위 처럼 사용하는 것을 아래로 대체할 수 있음
import Utiltiy from 'Utiltiy/utility'

extensions

확장자를 해석하는 방법에 대한 옵션이다.

아래와 같이 설정하고

module.exports = {
  //...
  resolve: {
    extensions: ['.js', '.json', '.wasm'],
  },
};

'a.js'라는 파일을 import할 때 확장자를 생략할 수 있다.

import AAA from 'a'

webpack.conifg.js example

지금까지 정리한 내용을 기반으로 해석이 된다면
webpack을 어느정도 알게 되었다고 할 수 있다.

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/index.tsx', // Root File
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'bundle.[chunkhash].js'
    },
    module: {
        rules: [
            {
                test: /\.(ts|js)x?$/,
                use: 'babel-loader',
                exclude: /node_modules/,
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"]
            },
            {
                test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
                use: "file-loader"
            }
        ]
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js" ]
    },
    plugins: [
        new HtmlWebpackPlugin({ template: "./src/index.html"}),
        new CleanWebpackPlugin(),
    ]
}
profile
아는 만큼 보인다

0개의 댓글