webpack + React + Typescript 개발환경 설정

박세진·2023년 7월 12일
0

Typescript exercise를 풀어보고 이론에 대한 부분도 봤지만 역시 무언가를 만들어보며 학습하는 게 좋겠다 싶어서 기본적인 Todo list를 만들어보고자 했다.

일단 Todo list를 만들기 전 webpack을 이용하여 개발환경설정을 해야 된다.
(npm을 이용하였음)

기본적인 개발환경설정

$ npm init -y

init을 통해서 package.json 파일이 생성되고, -y를 붙이면 모두 yes라고 작성한 것이다. 프로젝트에서 따로 더 설정해줄 필요가 없었기 때문에 yes로 진행했다.

$ npm install --save-dev webpack webpack-cli webpack-dev-server

webpack, webpack-cli, webpack-dev-server를 dev dependency로 설치해준다.

$ npm install --save-dev babel-loader
$ npm install --save-dev @babel-core
$ npm install --save-dev @babel/preset-env @babel/preset-react @babel/preset-typescript

webpack에서 babel을 쓸 수 있도록 babel-loader와 설정을 잡아주는 것들을 설치해준다.

// webpack.config.js
const path = require('path');

module.exports = {
  mode: 'development',
  // __dirname은 현재 디렉토리에서를 의미함
  entry: path.resolve(__dirname, './src/index.tsx'),
  output: {
    path: path.join(__dirname, '/dist'),
    filename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: ['babel-loader', 'ts-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
  },
  devServer: {
    historyApiFallback: {
      index: 'index.html',
    },
  },
};
// babel.config.js
module.exports = {
    presets: [
        [
            '@babel/preset-env',
            {
                targets: {
                    node: 'current',
                },
            },
        ],
        '@babel/preset-react',
      	'@babel/preset-typescript'
    ]
}

webpack.config.js 파일과 babel.config.js 파일을 만들어서 설정해준다.

$ npm i react react-dom
$ npm i -D typescript @types/react @types/react-dom ts-loader

react, typescript, ts-loader를 설치해준다.

npx tsc --init

위 명령어를 입력하면 tsconfig.json 파일이 자동으로 생성된다.

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "allowJs": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "jsx": "react",
    "noEmit": false,
    "isolatedModules": true,
    "noImplicitAny": true,
    "outDir": "dist",
    "rootDir": "src"
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"],
  "exclude": ["node_modules"]
}

tsconfig.json 파일에 옵션은 굉장히 많으니까 프로젝트에 필요한 부분만 넣어주면 된다.

<!doctype html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Todo-app</title>
  </head>
  <body>
    <div id="app"></div>
    <script src="/main.js"></script>
  </body>
</html>

public 폴더를 만들어서 하위에 index.html 파일을 만든다.

import React from 'react';
import ReactDOM from 'react-dom/client';

import App from './App';

const root = ReactDOM.createRoot(document.getElementById('app') as HTMLElement);

root.render(<App />);

src 폴더를 만들고 하위에 index.tsx 파일을 만들고, App.tsx 파일도 만들어줬다.

// package.json 파일

"scripts": {
    "start": "webpack serve --mode development",
    "build": "webpack",
    "format": "prettier --cache --write .",
    "lint": "eslint --cache ."
  },

scripts 부분에 "start" : "webpack serve --mode development"를 추가해주면 npm start 명령어를 입력했을 때, local에서 확인하며 작업할 수 있다.

eslint, prettier 설정

$ npm i -D eslint

$ npm i -D prettier

$ npm i -D eslint-config-prettier

여기다가 추가적으로 typescript eslint도 설치해줬다. typescript eslint는 standard로 선택했다.

$ npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint typescript
// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ['plugin:react/recommended', 'plugin:@typescript-eslint/recommended'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    parser: '@typescript-eslint/parser',
    project: './tsconfig.json',
  },
  settings: {
    react: {
      version: 'detect',
    },
  },
  plugins: ['react', '@typescript-eslint'],
  rules: {
    eqeqeq: 'error',
    'no-unused-vars': 'error',
    'no-alert': 'error',
    'no-var': 'error',
    'no-multiple-empty-lines': 'error',
    'no-console': ['warn', { allow: ['warn', 'error'] }],
    '@typescript-eslint/semi': 'off',
    '@typescript-eslint/member-delimiter-style': 'off',
    'no-unused-vars': 'off',
    '@typescript-eslint/no-unused-vars': ['error'],
  },
};
// .prettierrc
{
  "printWidth": 100,
  "singleQuote": true,
  "semi": true,
  "tabWidth": 2,
  "trailingComma": "all"
}

이렇게 각 .eslintrc.js.prettierrc 파일을 설정해줬다.

개발환경설정 파일까지 eslint 적용이 되기 때문에 ignore 처리해주는 게 필요하다.

webpack.config.js

.eslintrc.js

babel.config.js

이렇게 .eslintignore 파일을 만들어서 설정해주면 적용이 되지 않는다. 또는 package.json 파일에서 eslintIgnore을 설정해줘도 된다.

{
  "eslintIgnore": [
    	".eslintrc.js",
    	"babel.config.js",
    	"webpack.config.js"
  ],
}

개발환경설정 중 발생한 문제

(위 과정에 올려놓은 개발환경설정에 대한 내용은 시행착오를 겪고 로컬 환경 브라우저에서 동작하는 것까지 확인하고 올려놓은 것이다.)

처음에 개발환경설정을 한 다음 확인하려고 로컬 브라우저에서 열어봤을 때 아래 에러가 발생했다.

에러 코드를 검색해보니 stackoverflow 에 동일한 문제를 겪은 사람이 있었고, 다행히 해결방법을 찾을 수 있었다.

tsconfig.json 파일에 noEmit 옵션이 true 값이어서 생긴 문제였다. noEmit은 JavaScript 소스 코드, 소스 맵 또는 선언과 같은 컴파일러 출력 파일을 내보내지 않는 옵션이다. default 값은 false라는데 왜 true로 설정이 되어 있었는지 모르겠다. noEmitfalse 값으로 설정했더니 로컬 환경에서 잘 출력되는 것을 확인할 수 있었다.


개발환경설정은 자주 하는 게 아니어서 그런가 할 때마다 기억이 잘 나지 않아서 찾아보면서 할 수밖에 없는 것 같다. 그래도 또 똑같은 문제를 겪으면 안되니까 적어놔야지...
Next.js는 번들링, 컴파일 같이 개발환경설정이 자동으로 돼서 시간을 절약할 수 있다던데, 나중에는 Next.js도 공부해봐야지...!


이 블로그도 쓰고, TODO 앱을 만들면서 로컬에서는 잘 되고 있었는데, commit을 올리고 push를 하려고 하니 error가 발생해서 push가 안되는 상황이 발생했다. (husky를 이용해서 에러가 발생한 경우 push를 못하게 막아놓음)

You are linting ".", but all of the files matching the glob pattern "." are ignored.

계속 이런 에러가 뜨고, 계속 directory에 파일을 찾을 수 없다고 하고, 고치면 고칠수록 빠져나올 수 없게 되어버렸다. 이것때문에 하루동안 고생했다. 느낌에는 parser를 설정을 제대로 안 해줘서 생겼던 문제일 것 같다.
진짜 husky, eslint 다 버리고 싶었다. 하지만 협업을 할 때, 가장 필수적인 것들에서 에러가 났다고 해서 버리고 포기하면 안되지! 하는 생각에 계속 한 건데, 진짜 힘들었다. 힘들어...
(느낀 점은 설정해봤는데 아니면 다시 원래 설정으로 되돌리고 하자... 계속 더하고 더하고 더했더니 에러가 크게 불어나니까...)

profile
경험한 것을 기록

0개의 댓글