티스토리 뷰

728x90
SMALL

배경

저번에 글을 한번 올렸었는데 설정이 조금 바뀐것들이 있어서 다시 글을 쓴다. 청크라던가 코드스플리팅은 아직 적용하지 않았다. 너무 어렵다. 진짜... 쉬운게없네... 간단하게 코드와 설명만 적겠다. 개념은 저번글을 참고하면 된다.

버전

package.json

  "dependencies": {
    "@babel/cli": "^7.14.8",
    "@babel/core": "^7.15.0",
    "@babel/preset-env": "^7.15.0",
    "babel-cli": "^6.26.0",
    "babel-loader": "^8.2.2",
    "compression-webpack-plugin": "^9.0.0",
    "core-js-pure": "^3.16.1",
    "css-loader": "^6.2.0",
    "css-minimizer-webpack-plugin": "^3.0.2",
    "html-webpack-plugin": "^5.3.2",
    "mini-css-extract-plugin": "^2.2.0",
    "style-loader": "^3.2.1",
    "terser-webpack-plugin": "^5.1.4",
    "webpack": "^5.49.0",
    "webpack-cli": "^4.7.2",
    "webpack-dev-server": "^3.11.2",
    "webpack-merge": "^5.8.0"
  },

코드 작성

사실 파일하나에서 관리해도 되는데 나눠서 관리하면 좀 깔끔한 느낌이 있는것같기도?? 하다.

webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, '../dist'),
    clean: true,
    assetModuleFilename: 'assets/[hash][ext][query]',
  },
  resolve: {
    modules: ['node_modules'],
    extensions: ['.js'],
  },
  module: {
    rules: [
      {
        test: /\.(js)$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-env',
                {
                  targets: '> 1%, not dead',
                  useBuiltIns: 'usage',
                  corejs: { version: '3.16' },
                },
              ],
            ],
          },
        },
        exclude: /(node_modules)/,
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif|ico)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      // favicon: './public/favicon.png',
    }),
    new CompressionPlugin(),
  ],
};

url loader, file loader 대신에 webpack5부터는 기본 기능에 포함되서 위와 같이 사용하면 된다.
그 외에는 플러그인만 간단하게 설명한다.
HtmlWebpackPlugin은 HTML 파일을 후처리하는데 사용되며 빌드 타임의 값을 넣거나 코드를 압축한다.
CompressionPlugin은 gzip파일로 압축한다.

webpack.dev.js

const path = require('path');
const { merge } = require('webpack-merge');
const common = require('./webpack.common');

module.exports = merge(common, {
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
        exclude: /node_modules/,
      },
    ],
  },
  devtool: 'inline-source-map',
  devServer: {
    contentBase: path.resolve(__dirname, '../dist'),
    index: 'index.html',
    overlay: true,
    port: 9000,
    writeToDisk: true,
    hot: true,
    historyApiFallback: true,
    proxy: {
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
      },
    },
  },
});

devServer만 조금 살펴보자
overlay가 true이면 오류를 화면에 띄워준다.
hot을 true로 하면 변경된 모듈만 바꿔준다. 그래서 저장할때마다 화면이 저절로 바뀌는 것이다. 참고로 style-loader가 핫로딩을 지원한다.
writeToDisk가 true이면 파일을 실제로 생성한다. 마치 build한것처럼 말이다.
추가로 historyApiFallback이 true이면 spa를 이용할 때 not found page라면 메인페이지로 리다이렉트 시켜준다. 나는 라우터에서 notfound 처리를 해서 상관없지만 필요하다면 사용하면 좋을 것 같다.

잘못알고 있었다. 경로를 기준으로 판단한다. devserver에서는 켜놔야 한다. 끄면 새로고침시에 그 url에 해당하는 파일을 불러온다. spa라면 당연히 없는 페이지가 뜬다. 실제 배포시에도 처리를 해줘야한다. nginx설정에 적어놨다.또 추가로 proxy의 changeOrigin이 true이면 cross origin을 허용해준다.

webpack.prod.js

const { merge } = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const common = require('./webpack.common');

module.exports = merge(common, {
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
        exclude: /node_modules/,
      },
    ],
  },
  devtool: 'source-map',
  optimization: {
    minimize: true,
    minimizer: [new CssMinimizerPlugin(), new TerserPlugin()],
  },
  plugins: [new MiniCssExtractPlugin()],
});

TerserPlugin은 사실 세부 옵션을 적용하지 않는다면 굳이 저렇게 npm 설치해서 적어줄 필요가 없다.
CssMinimizerPlugin : This plugin uses cssnano to optimize and minify your CSS.
MiniCssExtractPlugin : This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.

추가로 적용할 것

트리 쉐이킹, 청크, 코드스플리팅, 레이지로딩...

728x90
LIST
댓글
공지사항