CRA 없이 webpack으로 boilerplate 만들어보기

ShallWeDance·2022년 4월 7일
0

webpack

목록 보기
2/2
post-custom-banner

개발환경 구축하기

1. 폴더 생성 및 초기화

# 폴더 생성
mkdir webpack-babel-react-boilerplate

# webpack-babel-react-boilerplate 폴더로 이동
cd webpack-babel-react-boilerplate

# package.json 초기화
yarn set version berry
yarn init -2

# 기본 master branch일 경우
git checkout -b main

2. 기본 폴더 생성

# public, src, dist 폴더 생성
mkdir public src dist

# public 폴더로 이동
cd public

# index.html 파일 만들기
touch index.html

폴더 생성 후 index.html에 루트 <div> 를 만든다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>webpack-babel-react-boilerplate</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

3. react, typescript 설정

# react 패키지 설치
yarn add react react-dom

# typescript 사용을 위해 devDependencies에 패키지 설치
yarn add typescript@4.5.5 @types/react @types/react-dom -D

설치 후 타입스크립트가 전역으로 설치되어 있다면 바로 tsc -init으로 tsconfig.json 파일을 만들어준다. 나는 다음과 같이 tsconfig.json을 구성했다.

{
  "compilerOptions": {
    "target": "es5",
    "module": "es6",
    "strict": true,
    "jsx": "react",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "lib": ["es6","dom"],
    "outDir": "./dist",
  },
  "include": ["./src/**/*"],
  "exclude": ["./dist"]
}
# ZipFS extenstion 설치 후
# vscode에서 yarn pnp을 사용할 수 있도록 설정
yarn dlx @yarnpkg/sdks vscode

# typescript를 사용할 것이기 때문에 플러그인을 설치해준다.
yarn plugin import typescript

아마 여기에서 tsconfig.json 파일에 오류가 생길텐데 아직 typescript 로 작성한 파일이 없어서 오류가 날 것이다.

따라서 ts로 작성한 파일을 만들어 준다.

src/index.tsx

import React from "react";
import * as ReactDOMClient from "react-dom/client";
import App from "./App";

const rootElement = document.getElementById("root") as HTMLElement;
const root = ReactDOMClient.createRoot(rootElement);
root.render(<App />);
src/App.tsx

import React from "react";

const App = () => {
  return <>App</>;
};

export default App;

현재 나는 typescript v4.5.5으로 설치했는데 v4.6.3 버전을 사용할 경우 자꾸 오류가 났다. 원인을 찾아봤지만 typescript가 업데이트 된지 얼마 안 되어서 yarn pnp랑 호환이 잘 안되는 것으로 추정했다. react18 때문일 수도 있다. 때문에 v4.5.5 를 사용했다

또한 이제 vscode에서 workspace 별로 타입스크립트 버전을 선택 할 수 있는데 만약 오류가 있을 경우 그 부분을 살펴보는걸 추천한다.

command + shift + p > select typescript version > use workspace version

4. babel 설정

yarn add babel-loader @babel/cli @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript @babel/runtime @babel/plugin-transform-runtime -D

바벨 설정을 위해서 관련된 모듈을 설치한 뒤

babel.config.js

module.exports = {
  presets: [
    "@babel/preset-env",
    [
      "@babel/preset-react",
      {
        runtime: "automatic", // defaults to classic
		// automatic auto imports the functions that JSX transpiles to.
	  }
    ],
    "@babel/preset-typescript",
  ],
  plugins: ["@babel/plugin-transform-runtime"]
};

다음과 같이 설정한다.

5. webpack 설정

# webpack, webpack-cli, webpack-dev-server를 기본으로 설치하고 필요한 플러그인 설치
yarn add webpack webpack-cli webpack-dev-server webpack-bundle-analyzer html-webpack-plugin clean-webpack-plugin -D

# for typesciprt
yarn add @types/webpack @types/webpack-bundle-analyzer @types/clean-webpack-plugin -D

설치 후 webpack.config.js 파일을 만든다.

// webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const BundleAnalyzerPlugin =
  require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const prod = process.env.NODE_ENV === "production";

module.exports = {
  mode: prod ? "production" : "development",  // 개발용, 배포용 설정
  devtool: prod ? "cheap-module-source-map" : "eval",  // source-map을 설정하는 부분
  entry: path.resolve(__dirname, "./src/index.tsx"),  // 웹팩을 실행할 대상 파일
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },  // 확장자나 경로를 알아서 처리할 수 있도록 설정하는 옵션
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].[chunkhash].js",
  },  // 번들화 된 파일을 export할 경로와 파일명을 설정
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "./public/index.html"),
    }),  // template은 번들링 파일을 주입하고 번들링 폴더로 복사할 대상 HTML 파일을 명시하는 옵션
    new BundleAnalyzerPlugin({
      analyzerMode: "static",
      reportFilename: "bundle-report.html",
      openAnalyzer: false,
      generateStatsFile: true,
      statsFilename: "bundle-status.json",
    }),  // 번들 사이즈 시각화
    new CleanWebpackPlugin(),  // 성공적으로 다시 빌드 한 후 webpack의 output.path 디렉토리에있는 모든 파일과 사용하지 않는 모든 웹팩 자산을 제거
  ],
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        include: path.resolve(__dirname, "src"),
        use: ["babel-loader"],
      },
    ],
  },  // 모듈에 적용할 로더들과 그 옵션들을 설정
  devServer: {
    open: true,
    port: 3000,
    hot: true,
  },  // webpack-dev-server의 옵션
};

그 후 package.json 파일에 scripts를 추가한다.

"scripts": {
    "dev": "webpack serve --mode development",  // webpack-dev-server 의 모드가 개발모드 일 때,
    "start": "webpack serve --mode production",  // webpack-dev-server의 모드가 운영모드 일 때
    "build": "webpack --mode production",  // webpack 모드가 운영모드 일 때
    "build:report": "webpack-bundle-analyzer --port 8888 dist/bundle-status.json"  // report를 보기위한 옵션
  },

결과물은 여기서 확인해 볼 수 있다!
추가로 eslint, prettier, husky 같은 세팅도 필요하지만 기본적인 세팅은 여기까지 하고 마무리 해보려한다.

Ref

혹시나 틀린 부분이 있다면 말씀해주시면 감사드리겠습니다. 🙇

post-custom-banner

0개의 댓글