바닐라 TypeScript 프로젝트 환경 세팅

jiseong·2022년 6월 11일
0

T I Learned

목록 보기
267/291
post-custom-banner

typescript, css에 초점을 맞춘 프로젝트 환경 세팅 방법이다.

웹팩 관련

$ npm i -D webpack webpack-cli webpack-dev-server webpack-merge

webpack-merge: 웹팩설정파일을 prod, dev에 따라 분리시키기 위해서

웹팩 플러그인, 로더 관련

$ npm i -D html-webpack-plugin style-loader css-loader mini-css-extract-plugin

mini-css-extract-plugin: prod에서 css를 별도의 파일로 추출하기 위해서
style-loader: dev에서는 css를 여러 번 수정하더라도 style 태그에 주입하는 것이 훨씬 빨리 작동하기 때문에 style-loader를 사용

바벨 관련

$ npm i -D @babel/core babel-loader

오래된 브라우저에서도 자바스크립트 코드가 실행되어야 하는가?
$ npm i -D @babel/preset-env

타입스크립트 관련

타입스크립트를 적용하는 방법은 크게 babel7 + @babel/preset-typescript 방식과 ts-loader 방식으로 나뉜다. 나의 경우에는 babel7 + @babel/preset-typescript 방식을 사용하는데 매번 타입체킹을 해주면 빌드나 컴파일이 그만큼 느려지기 때문에 필요할때만 타입체킹을 하도록 스크립트로 분리시킬 수 있고 VScode에서 제공하는 기능만으로도 충분히 타입에러들을 잡을 수 있기 때문이다.

$ npm i -D typescript @babel/preset-typescript

$ npm i -D ts-loader fork-ts-checker-webpack-plugin

fork-ts-checker-webpack-plugin
타입 체킹하는 역할은 다른 프로세스로 분리시켜 빠르게 빌드나 컴파일을 해줄 수 있는 플러그인

웹팩 설정파일 작성

이제 dev, prod에 따라 웹팩설정파일을 작성해주면 되는데 공통되는 부분은 공통설정에 작성하고 나머지 각각의 환경에 필요한 부분은 따로 따로 작성해서 webpack-merge를 사용하여 합치면 된다.

나의 경우에는 루트경로에 config 폴더를 만들고 그 안에 작성한다.

공통 설정

// config/webpack.common.js

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

module.exports = {
  entry: {
    main: './src/index.ts',
  },
  output: {
    publicPath: '/',
    path: path.resolve(__dirname, '../dist'),
    filename: '[name].[contenthash].js',
    clean: true,
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx|js|jsx)$/,
        loader: 'babel-loader',
        options: {
          presets: [
            '@babel/preset-typescript',
          ],
        },
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html',
    }),
  ],
};

dev

// config/webpack.dev.js
const { merge } = require("webpack-merge");
const webpackCommon = require("./webpack.common");

module.exports =  merge(webpackCommon, {
  mode: 'development',
  devtool: "inline-source-map",
  devServer: {
    historyApiFallback: true,
    hot: true,
    open: true,
    port: 9000,
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"]
      },
    ]
  },
});

prod

// config/webpack.prod.js
const { merge } = require("webpack-merge");
const webpackCommon = require("./webpack.common");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports =  merge(webpackCommon, {
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"]
      },
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
});

package.json 스크립트 작성

작성한 웹팩설정에 기반하여 프로젝트를 시작하고 빌드하기 위한 스크립트를 작성해줘야 한다.

"scripts": {
    "start": "webpack serve --config ./config/webpack.dev.js",
    "build": "webpack --config ./config/webpack.prod.js",
    "type-check": "tsc --noEmit" // 타입 체킹용
},

tsconfig.json 생성

마지막으로 tsconfig.json을 생성해줘야 한다.

$ ./node_modules/.bin/tsc --init

명령어

개발서버 시작

$ npm run start

빌드

$ npm run build

타입 체크

$ npm run type-check

Eslint와 Prettier 적용

여기까지만 적용시켜도 코드를 실행시키는데 문제없지만 코드 포매팅과 문법적 오류를 잡기위해서 Eslint와 Prettier도 추가 적용시켜주면 좋다.

VSCode Extensions에서 ESLint와 Prettier 설치

VSCode를 사용하고 있다면 우선, Eslint, Prettier 확장 설치

Eslint 관련

npm i -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

@typescript-eslint/parser: ESLint가 타입스크립트 코드를 lint 할 수 있도록 하는 플러그인

@typescript-eslint/eslint-plugin: 타입스크립트에 대한 lint 규칙들을 제공하는 플러그인

.eslintrc 파일 설정

{
  "parser": "@typescript-eslint/parser",
  "plugins": [
    "@typescript-eslint"
  ],
  "extends": ["plugin:@typescript-eslint/recommended"],
  "parserOptions": { "project": ["./tsconfig.json"] }
}

parser: '@typescript-eslint/parser' 은 ESLint에게 설치한 @typescript-eslint/parser를 사용하도록

plugins: ['@typescript-eslint']은 설치한 @typescript-eslint/eslint-plugin를 로드하도록

vscode 설정

cmd(control) + , 를 눌러 settings을 킨 뒤 User 또는 Workspace 공간에서 셋팅한다.

workspace에서 설정했을 경우

{  
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
}

Prettier 관련

npm i --D prettier eslint-plugin-prettier eslint-config-prettier

eslint-config-prettier: prettier와 겹치는 ESLint의 formatting 규칙을 비활성화하기 위해서 설치한다.

eslint-plugin-prettier: eslint에 prettier의 규칙을 추가하기 위해서 설치한다.
(prettier에서 인식하는 코드상의 포맷 오류를 ESLint 오류로 출력해주기 위해)

결국 두가지는 Prettier와 Eslint의 충돌방지를 위해서 설치해주는 것

.eslintrc.json 설정 수정

{
  // 생략...
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:prettier/recommended" // 새롭게 추가
  ]
}

plugin:prettier/recommended: prettier 규칙을 eslint 규칙에 추가하고 prettier와 충돌하는 eslint 규칙을 끄는 역할

결국 eslint-config-prettier와 eslint-plugin-prettier를 적용하기 위해서 작성한 것

.prettierrc 파일 설정

마지막으로 prettier 설정파일을 생성하면 되는데 이 부분은 팀에 맞는 prettier 옵션을 가져와 사용하면 된다.

// .prettierrc
{
  "singleQuote": true,
  "semi": true,
  "useTabs": false,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80
}

마무리

프로젝트 성향에 따라서 scss, style-components, react 등이 사용된다면 웹팩 설정파일에 추가적으로 작성해줘야하는 부분들이 존재한다.

그리고 assets 관련하여 설정된게 아무것도 없기 때문에 오류가 발생할텐데
https://webpack.js.org/guides/asset-modules/
를 참고하면 된다.

ERROR in ./src/xxx.jpg 1:0
Module parse failed: Unexpected character '�'

간단히 언급하자면 webpack 5 부터는 이전에 사용했던 file-loader, url-loader등을 추가로 설치하지 않아도 assets 파일들을 사용할 수 있도록 해준다.

file-loader -> asset/resource
url-loader -> asset/inline

두 로더를 하나의 설정으로 하고 싶다면 -> asset
asset사용 시 따로 설정을 해주지 않으면 크기가 8kb 미만인 파일은 inline 모듈로 처리되고 그렇지 않으면 resource 모듈로 처리

추가적으로 svg, png, jpg등을 import할때 타입스크립트 관련해서 발생하는 오류는 typescript declare module 키워드를 참고하면 된다.

Cannot find module './xxx.jpg' or its corresponding type declarations.ts(2307)

xxx.d.ts 파일은, TypeScript를 지원하지 않는 서드파티 라이브러리를 사용할 때 타입을 직접 선언해주어 컴파일러에게 타입 정보를 알려주기 위한 목적을 가진 파일이다.

post-custom-banner

0개의 댓글