Webpack 설정

김윤진·2022년 8월 10일
0
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  entry: './src/index.tsx',
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        use: ['babel-loader', 'ts-loader'],
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'assets/images/[name].[ext]',
            },
          },
        ],
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: 'assets/fonts/[name].[ext]',
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  resolve: {
    modules: [path.resolve(__dirname, './src'), 'node_modules'],
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/',
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    hot: true,
    compress: true,
    port: 3000,
    historyApiFallback: true,
  },
  plugins: [
		new Dotenv(),
		new HtmlWebpackPlugin({ template: 'public/index.html' }), 
		new CleanWebpackPlugin(),
		new webpack.EnvironmentPlugin({
      SERVICE_URI: 'http://localhost:3000',
    }),
	],
};

Module

이미지, 폰트 build

file-loader를 통해 이미지와 폰트를 build 할 수 있다.

test에는 build할 파일의 확장자를 작성하고

option에 name으로 build할 파일 이름과 디렉토리를 설정할 수 있다.

file-loader | webpack


Resolve

resolve 옵션은 모듈을 해결하는 방법을 변경합니다.

resolve.alias

특정 모듈을 더 쉽게 가져오거나 필요로 하는 별칭을 만든다.

resolve: {
    alias: {
      Utilities: path.resolve(__dirname, 'src/utilities/'),
    },

before

import Utility from '../../utilities/utility';

after

import Utility from 'Utilities/utility';

resolve.modules

module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
  },
};

모듈을 확인할 때 어떤 디렉토리를 검색해야 하는지 웹팩에 알려준다.

절대 경로와 상대 경로를 모두 사용할 수 있지만 조금 다르게 작동한다는 것을 알고 있어야 한다.

상대 경로는 노드가 노드 모듈을 검색하는 방식과 유사하게 현재 디렉토리와 그 조상(즉, 조상)을 통해 스캔된다. ./node_modules, ../node_modules, and on)이다.

절대 경로를 사용하면 지정된 디렉토리에서만 검색됩니다.

build할 때 이 옵션을 지정해주어야 절대 경로로 지정된 파일들을 build 할 수 있다.

Resolve | webpack


devtool

Avoid inline-***
 and eval-***
 use in production as they can increase bundle size and reduce the overall performance.

inline- 및 eval-은 번들 크기를 늘리고 전체 성능을 저하시킬 수 있으므로 프로덕션 환경에서 사용하지 않는 것이 좋다.

Devtool | webpack


환경 분리

Production | webpack

EnvironmentPlugin

process.evn 키에 DefinePlugin을 적용할 수 있다.

DefinePlugin 을 사용하면 컴파일 타임에 구성할 수 있는 전역 상수를 만들 수 있다.

new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']);

위와 동일하게 동작한다.

new webpack.DefinePlugin({
  'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
  'process.env.DEBUG': JSON.stringify(process.env.DEBUG),
});

그러나 local에서 dotenv를 통해 환경 변수를 설정하면 배포 환경에서는 이 환경 변수를 알 수 없다.

왜냐하면 dotenv 파일은 보통 gitignore에 추가하여 github에 올라가지 않도록 한다.

이를 해결하기 위해서는 dotenv 파일도 github에 올리거나 EnvironmentPlugin 에 default value를 추가하는 방법이 있다. 이외에도 private repo에서 환경 변수 파일을 만드는 방법이 있지만 프로젝트가 모노레포라는 이 방식을 차용하기는 힘들다.

그리고 환경 변수의 목적은 은닉화가 아닌 환경 분리이기 때문에 EnvironmentPlugin default value를 추가하는 방식을 차용했다.

		new webpack.EnvironmentPlugin({
      SERVICE_URI: 'http://localhost:3000',
    }),

환경이 추가될 때마다 webpack 파일도 늘어나기 때문에 환경변수를 webpack파일에 적어준다면 쉽게 환경을 분리할 수 있다.


entry

https://github.com/webpack/webpack-cli/issues/1843


merge

local 서버에서는 dev server나 hot reload와 같은 기능이 필요하다.

그러나 배포하는 서버에서는 최적화된 파일을 통해 로드 시간을 줄이기 위해 위에 해당하는 기능들이 같이 배포하는 것을 지향해야 한다. 그래서 환경마다 webpack 설정을 분리하여 작성하는 것이 좋다.

local과 production을 분리하더라도 공통된 부분은 존재할 수 밖에 없다. 그래서 공통된 설정들은 하나의 webpack 파일에 위치하면 환경에 따라 webpack 파일이 추가되더라도 같은 코드를 복사할 필요는 없다. 이러한 공통된 설정을 합치기 위해 webpack-merge 유틸리티를 사용할 수 있다.

Webpack Merge | 웹팩 핸드북

Production | 웹팩

0개의 댓글