치악산 복숭아

CRA 없이 리액트 개발환경 구축하기(feat. typescript, webpack, babel) 본문

FE/React

CRA 없이 리액트 개발환경 구축하기(feat. typescript, webpack, babel)

Juliie 2022. 4. 5. 00:45

1. 개발이 진행될 폴더를 만들어준다

cd 폴더를 만드려는 경로
mkdir 폴더 이름

2. npm init으로 package.json을 생성해서 초기화 해준다

(y 옵션을 붙여주면 별다른 질문(version, description ...) 없이 생성된다

npm init [-y]

3. 리액트를 설치한다

npm i react react-dom

4. 프로젝트의 시작점이 될 파일 위치를 잡는다

나의 경우는 프로젝트 루트 경로에 index.html을 생성한 뒤, src 폴더를 만들어서 그 안에 App.tsxindex.tsx 파일을 생성했다

<!-- index.html -->
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Typescript practice</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
// src/App.tsx

function App() {
  const test = (str: string) => {
    return str;
  };
  return <div>{test("hello")}</div>;
}
export default App;
// src/index.tsx

import ReactDOM from "react-dom";
import App from "./App";

const rootElement = document.getElementById("root");

ReactDOM.render(<App />, rootElement);

5. typescript 설치 및 환경 설정

npm i -D typescript @types/react @types/react-dom
여기서 잠깐 !

😮 왜 -D 옵션을 붙이지 ?
-D 를 안붙이면 -> 그냥 dependencies에 포함: 여기는 프로젝트를 실행시키는데 필수적인 라이브러리들이 포함되는 곳
-D를 붙여서 설치하면 -> devDependencies에 포함: 여기는 현재 프로젝트를 개발하고 테스트하는데 사용되지만 실제 런타임에서는 필요없는 라이브러리들이 포함되는 곳

🤔 라이브러리 앞에 붙은 @types는 뭐지 ?
@어쩌구 -> scoped packages
npm 라이브러리 중 타입 선언이 포함되어 있지 않는 것들도 있는데(ex: 리액트), definitelyTyped에서 유지보수 되고 있는 타입 정의가 있는지 확인할 수 있다. 만약 있다면 @types 를 붙여서 npm으로 설치가 가능하다. @types 라이브러리는 타입 정의만 있기 때문에(구현 x) 원본 라이브러리도 설치해줘야함!

😯 --save 옵션을 따로 붙여주는 사람들도 있던데 ?
npm5 부터는 --save 옵션을 기본으로 적용되어서 안 써줘도 되지만! 예전에는 이 옵션을 안 써주면 node_modules에는 들어가지만 package.json의 dependencies에는 추가가 안됐다고 한다 (22.04.02 오늘의 나는 npm 7.5.4 버전을 쓰고 있다)

설치가 끝났다면 tsconfig.json 파일을 생성해서 typescript 환경 설정을 해준다

//tsconfig.json
{
  "exclude": ["node_modules"], // 1
  "include": ["**/*.ts", "**/*.tsx"], // 2
  "compilerOptions": { // 3
    "target": "es5",
    "module": "commonjs",
    "noImplicitAny": true,
    "strictNullChecks": true,
    "jsx": "react-jsx",
    "esModuleInterop": true
  }
}

1) exclude: 컴파일 제외할 대상 지정

2) include: 컴파일 할 대상 지정

3) compileOptions: 컴파일 할때 옵션들을 세세하게 정할 수 있음

  • target: 어떤 JS 버전으로 컴파일할지
  • module: 어떤 모듈 시스템을 사용할지
  • noImplicitAny: any 타입 허용 X
  • strictNullChecks: undefined 또는 null값 참조 방지
  • jsx: jsx 파일이 어떻게 만들어질지
  • esModuleInterop: 파일 가져오기에 대한 CommonJS와 ES 모듈 간의 상호 운용성을 제공

* esModuleInterop에 대해 조금 이해가 간 stackoverflow 답변 링크

https://stackoverflow.com/questions/56238356/understanding-esmoduleinterop-in-tsconfig-file

 

Understanding esModuleInterop in tsconfig file

I was checking out someone .tsconfig file and there I spotted --esModuleInterop This is his .tsconfig file { "compilerOptions": { "moduleResolution": "node", ...

stackoverflow.com

 

5. webpack 설치 및 환경 설정

npm i -D webpack webpack-cli webpack-dev-server babel-loader html-webpack-plugin

webpack.config.js 파일을 생성해서 환경 설정을 진행해준다

//webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
const webpack = require("webpack");

module.exports = {
  mode: "development", // 1
  entry: "./src/index.tsx", // 2

  resolve: { // 3
    extensions: [".js", ".jsx", ".ts", ".tsx"],
  },

  module: { // 4
    rules: [
      {
        test: /\.tsx?$/,
        use: ["babel-loader"],
      },
    ],
  },

  output: { // 5
    path: path.join(__dirname, "/dist"),
    filename: "bundle.js",
  },

  plugins: [ // 6
    new webpack.ProvidePlugin({
      React: "react",
    }),
    new HtmlWebpackPlugin({
      template: "./index.html",
    }),
  ],
};

1) mode: 번들링 환경을 설정, 이에 따라 번들링 결과물의 파일 크기가 달라진다 

2) entry: 번들링의 시작점이 될 파일

3) resolve

  • extensions: 나열된 확장자를 순서대로 해석, extensions을 설정해주면 import 할때 확장자 생략이 가능하다!
  • modules: 절대경로 설정 가능

4) module: 자바스크립트로 작성되지 않은 파일들을 변환시켜 준다 - test 정규식의 조건에 맞는 파일들이 use에 나열된 로더들에 의해 변환되며, 만약 한개만 있다면 loader로 대체 가능 !

5) output: 번들링 결과물이 저장될 위치 지정

6) plugin: 번들링된 결과물을 처리

  • html-webpack-plugin: html을 동적으로 생성, html 파일에서 js 파일을 불러오는 부분이 빠져도 된다
  • provide-plugin: 자주 쓰이는 모듈을 등록해놓으면 import 하지 않아도 인식한다
  • 더 많은 공식 플러그인은 여기

6. babel 설치 및 환경 설정

npm i -D @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript

babel은 최신 문법을 지원하지 않는 브라우저들에 대응하기 위해 사용하는 라이브러리다. 최신문법을 사용해서 특정 브라우저가 이해하지 못하는 부분을 babel이 이해할 수 있도록 변환해주는 것!

babel의 빌드 과정 중 실제 코드 변환 작업들은 플러그인들이 하는데, 이 플러그인들은 기능별로 분리되어 있어서 하나하나씩 설정해주기에는 넘모 번거롭다🥲(let, arrow function ... 등등 아주 많다)

 

Babel · The compiler for next generation JavaScript

The compiler for next generation JavaScript

babeljs.io

그래서 사용하려는 목적에 맞는 플러그인들을 모아놔서 한 번에 설정할 수 있도록 한게 preset이다

난 preset을 사용해서 프로젝트 루트 경로에 babel 환경설정 파일(.babelrc)을 만들어줬다

// .babelrc
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@babel/preset-typescript"
  ]
}

여기까지 진행했다면 파일 구조가 이렇게 구성되어 있을 것이다 ⬇️

이후 프로젝트 폴더에서 아래 명령어를 실행시켜주면 ~~~ !

별도의 설정을 하지 않았다면 http://localhost:8080/ 에서 내 프로젝트를 볼 수 있다 🎉

npx webpack-dev-server --mode development

package.json의 scripts에 등록해놓으면 더 편하게 사용할 수 있음 !

덩그러니...

CRA 없이 개발환경 구축하기 끝 ~

Comments