"Life is Full of Possibilities" - Soul, 2020

IT (프론트엔드)

Webpack 적용기

m2ndy 2024. 7. 6. 23:09

 

 

 

React 프로젝트의 번들러로 Webpack을 사용하기 위해 공부한 내용을 정리해보았다.

 

 

 

1. webpack 설치

npm install -D webpack webpack-cli webpack-dev-server html-webpack-plugin

 

install 하게 되면 package.json, package-lock.json, node-modules가 생성된다

 

- html-webpack-plugin : Webpack의 플러그인 중 하나로, Webpack으로 번들링한 자바스크립트 파일을 자동으로 HTML 파일에 삽입해주는 역할을 한다. 이를 통해 수동으로 HTML 파일을 수정할 필요 없이, 번들링된 파일이 HTML 파일에 자동으로 포함되도록 할 수 있다.

 

1-1. scripts 추가

// package.json
  
{
  "name": "project-test",
  "version": "0.0.1",
  "description": "webpack 테스트입니다",
  "main": "./src/index.tsx",
  "scripts": {
    "build": "webpack",
    "start": "webpack serve --mode development"
  },
  "devDependencies": {
  	...
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  }
}

실행을 위한 스크립트를 추가해준다

 

 

1-2. src/index.html 생성

- src 하위에 엔트리 포인트가 될 index.html을 생성한다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Webpack Test</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

 

1-3. src/index.tsx 작성

import ReactDOM from 'react-dom/client';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(<App />);

 

1-4. src/App.tsx 작성

function App() {
  return <div>App</div>;
}

export default App;

 

 

 

 

2. typescript 및 ts-loader 설치

npm install -D typescript ts-loader @types/react @types/react-dom

 

 

3. webpack.config.js 생성

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

module.exports = {
  entry: './src/index.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'webpack-test.bundle.js',
    clean: true, // 새 빌드 생성 전 기존 파일 삭제
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],
  devServer: {
    static: path.join(__dirname, 'dist'),
    hot: true,
    open: true,
  },
};

 

 

 

4. tsconfig.json 작성

- tsconfig.json : 타입스크립트 컴파일러의 동작 방식을 정의하는 파일. `npx tsc --init` 명령어로 파일을 생성할 수 있다.

 

- 주요 기능들을 위주로 컴파일러 옵션을 추가했다.

{
  "compilerOptions": {
    "target": "ES2020",
    // "useDefineForClassFields": true, // 클래스 필드 선언 시 ECMAScript 표준 따르도록 할 지
    // "lib": ["ES2020", "DOM", "DOM.Iterable"], // 컴파일러가 포함할 라이브러리 파일을 지정
    "module": "ESNext",
    "skipLibCheck": true, // 라이브러리 파일의 타입 검사를 생략할지 - 생략(true)하면 컴파일 속도 높임

    /* Bundler mode */
    "moduleResolution": "bundler", // 모듈 해석 방법 설정 (bundler와 호환되는 모듈 해석 방식으로 설정)
    // "allowImportingTsExtensions": true, //  TypeScript 파일 확장자를 포함한 import를 허용 (.ts, .tsx)
    "resolveJsonModule": true, // json 파일의 import 허용 - 추후 테스트에 사용될 mock data에 적용할 듯 하다
    "isolatedModules": true, // 각 파일을 독립적으로 트랜스파일 => 빠른 빌드, 트랜스파일 오류 방지
    // "noEmit": true, // 타입스크립트를 컴파일했을 때 JavaScript 변환 파일을 만들어 내지 않도록 하는 설정. 타입스크립트를 에디터 통합 기능을 제공하기 위한 도구 혹은 소스 코드 타입 체커로만 사용하게 됨
    "jsx": "react-jsx", // React의 최신 JSX 변환 방식을 사용

    /* Linting */
    "strict": true, // 엄격한 타입-체킹 옵션을 활성화
    "noUnusedLocals": true, // 사용되지 않는 지역 변수가 있다면 컴파일 오류 발생 시킴
    "noUnusedParameters": true, // 사용되지 않는 매개 변수가 있다면 컴파일 오류를 발생 시킴
    "noFallthroughCasesInSwitch": true // switch 문에서 의도하지 않은 fallthrough를 방지
  },
  "include": ["src", "webpack.config.js"]
}

기존 미션에서 사용하던 코드를 바탕으로 추가 혹은 삭제해봤는데,

 

- useDefineForClassFields : 클래스 필드 선언 시 ECMAScript 표준을 따르도록 할 지에 대한 설정. react 18 버전이므로 클래스를 사용하지 않을 것 같아 삭제

- lib : 컴파일러가 포함할 라이브러리 파일을 지정. target 설정에 따라 자동으로 지정되므로 안해도 될 듯 하다.

 

4-1. moduleResolution

- 어떤 해석 방식을 사용할 것인지에 대한 옵션을 설정한다.

 

옵션 1. node

"moduleResolution": "node"

- Node.js 방식으로 모듈을 해석한다. 구 문법인 CommonJS를 기반으로 한다.

 

옵션 2. classic

"moduleResolution": "classic"

- Typescript 1.0과 호환되는 모듈을 해석한다. 

 

옵션 3. bundler

"moduleResolution": "bundler"

- 번들러와 호환되는 모듈을 해석한다. 주로 모듈 번들러 (Webpack, Rollup, Vite)와 함께 사용된다.

 

 

 

 

 

 

이 때, 번들러가 index.tsx를 읽지 못해서 오류가 발생했다.

 

noEmit: true 옵션을 true로 설정해두었는데, 컴파일 시 js파일을 생성하지 않도록 하는 옵션이다. 이는 ts-loader와 함께 사용할 때 문제가 될 수도 있다고 한다.

 

따라서 noEmit와 세트로 작동하는  allowImportingTsExtensions 까지 제거했다.

 

- allowImportingTsExtensions : TypeScript 파일 확장자를 포함한 import를 허용 (.ts, .tsx)

 

 

4-2. tsconfig.node.json

- tsconfig.node.json : TypeScript 프로젝트에서 Node.js 관련 설정 파일, 빌드 도구 설정 파일, 테스트 설정 파일 등을 컴파일할 때 사용된다. tsconfig.json과 분리된 설정을 적용할 수 있는데, 현재는 분리할 설정이 없어 추가하지 않기로 했다.

 

 

5. 실행

- npm start를 입력해 실행한다

성공!

 

 

6. 빌드

 

빌드도 잘 되는지 테스트 해보기 위해 npm run build 명령어로 빌드해보았다.

 

빌드는 잘 되지만, 다음과 같은 경고 메세지가 출력된다.

 

이는 웹팩 설정에서 mode를 추가해야 한다는 메세지인데, 종류로는 development나 production이 있다.

webpack.config.json의 module.exports 내에 mode를 넣거나

package.json의 scripts에 mode를 추가하면 된다.

// webpack.config.js

module.exports = {
  mode: 'development',
};
  // package.json
  
  "scripts": {
    "build": "webpack --mode development",
    "start": "webpack serve --mode development"
  },

 

공식 문서에서는 mode의 타입을 아래와 같이 설명했고,

string = 'production': 'none' | 'development' | 'production'

 

아직 테스트 단계라 개발과 프로덕션을 구분하지 않았으나 추후 본격적인 개발에 들어갈 때 구분해보려 한다.

 

 

 

https://webpack.js.org/configuration/mode/

 

Mode | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org