React intro

younghyun·2022년 2월 20일
0

Web Application의 발전

규모가 커지고 복잡한 애플리케이션을 개발하며 생산성을 향상시키고 많은 양의 데이터 관리와 코드 유지 보수를 더욱 편리하게 하기 위해 다양한 Frontend Framework(Library)가 등장

Frontend Framework(Library)

Angular
2010년 Google에서 개발한 Framework. TypeScript 기반으로 매우 안정적이고 탄탄한 Frontend App 개발이 가능하며 Framework답게 다양한 기능이 내장되어있다. 무겁고 배우기 어렵다는 단점이 있다.

Vue
2014년 Evan You라는 개인이 개발한 Framework. 코드가 깔끔하고 배우기 쉽기 때문에 가장 나중에 생겼지만 성장 속도가 정말 빠르다.

React
지속적으로 데이터가 변화하는 대규모 애플리케이션 구축하는 것” 을 목표로 2013년 Facebook에서 개발한 사용자 인터페이스(UI)를 만들기 위한 JavaScript Library

MVC(Model-View-Controller) Architecture (ex. Angular, Vue)와는 다르게 리액트는 오로지 View만 담당한다. 그만큼 내장되어 있는 기능이 부족해 third-party 라이브러리(ex. React-router, Redux)를 함께 사용한다. 페이스북의 지속적인 관리와 함께 생태계가 활성화 되어 있으며 다양한 자료, 그리고 React Native의 사용으로 인해 사용자가 꾸준히 증가한다.

  • 특징
    선언적
    VirtualDOM
    컴포넌트 사용
    JSX문법

Node.js & npm

Node.js

JavaScript는 웹 브라우저에서 동작하기 위한 언어로 탄생했고, 그렇기 때문에 자바스크립트의 실행환경인 각 브라우저 마다 자바스크립트를 해석할 수 있는 엔진이 있고 크롬의 엔진은 "V8”.
node.js는 자바스크립트가 브라우저 밖(ex.서버)에서도 동작하게 크롬 V8 JavaScript 엔진으로 빌드된 JavaScript 런타임 환경(실행 환경)
2009년 Node.js가 출시된 이후 자바스크립트는 웹 브라우저 영역 외에도 터미널 창, 웹 서버, 모바일 앱, 데스크톱 앱 등에서도 사용할 수 있게 됨.
(즉, 웹 밖에서도 자바스크립트를 이용해 개발을 하고자 하는 수요가 증가하면서 탄생한 것이 Node.js. Node.js를 통해 브라우저 외의 어플리케이션을 제작하는데 다른 언어들을 쓰지않고 JS언어를 이용해서도 가능해진 것.)

React Application은 웹 브라우저에서 실행되는 코드이므로 Node.js와 직접적인 연관은 없음. npm만 설치를 해도 React를 다운 받을 수는 있음.(Facebook에서 npm에 모듈로 React 폴더를 올림.)

하지만, 프로젝트를 개발하는 데 필요한 주요 도구들(ex. 바벨, 웹팩)이 Node.js 기반이기 때문에 반드시 설치해야 함. (바벨, 웹팩 설정이 JavaScript언어로 됨)

React는 JSX문법을 사용함. node.js는 Babel 이라는 컴파일러(트랜스파일러 상위 개념) 도구를 제공해서 JS대신 JSX를 사용 하게 해줌. 또한 ES6문법을 ES5문법으로 변경해줌.

다른 언어와 달리 자바스크립트는 정말 많은 환경에서 실행됨. 웹 브라우저, NodeJS, Deno 등에서 실행됨. 웹 브라우저 또한 각자 다른 자바스크립트 엔진을 통해 자바스크립트 코드를 읽게 됨.(다양한 브라우저에서 리액트를 실행하게 해줌.) 게다가 이렇게 실행되는 환경의 버전에도 자바스크립트는 영향을 받음. 특정 버전 이상에서만 실행되는 코드가 있고(Ex.Chrome도 버전이 있음) 특정 브라우저에서는 실행되지 않는 코드도 있음. 그렇기 때문에 모든 자바스크립트 실행 환경에서 정상적으로 동작할 수 있도록 하려면 바벨이 필요함.

Build Tool Chain

빌드 툴 체인이란 소스를 빌드하는 과정 전반에 걸처 필요한 도구들로써 Bundling 및 Complie 또는 Transpile, Profile, Coverage, Testing 등 상당히 넓은 영역을 가지고 있고 여기서는 그 중에 필수적인 두 가지에 대해서만 먼저 다루게 됨.

Webpack(웹팩)

자바스크립트를 위한 정적 모듈 번들러, 여러 개의 나누어져 있는 파일(js, css, png, jpg 등)들을 하나의 파일로 만들어주는 라이브러리, 의존성이 있는 것들을 찾아서 그룹핑을 해주는 도구

모듈(Module)
일단은 WebPack을 이루는 핵심인 '모듈'을 이해하기위해, 한번 쯤 사용해 본 인스타그램 게시물 페이지를 봄.
다른 사용자의 게시물 페이지의 기능은 대략적으로 아래와 같은 구성요소가 있음.

1-1) 댓글 달기
: 댓글을 작성할 수 있는 레이아웃을 생성하고, 그 레이아웃 내부에 적은 텍스트를 DB에 저장하는 기능.

1-2) 댓글 보기
: '댓글 더 보기' 를 클릭해서 다른 사용자가 작성한 댓글을 DB에서 꺼내와, 사용자 화면에 보여주는 기능.

2) 좋아요 누르기
: 좋아요 버튼을 클릭해서 비어있던 하트 아이콘이 채워짐과 동시에 '눌렀다는 기록'을 DB에 저장하는 기능.

3) 상세 기능( 게시물 우측 상단의 점 세개 ===> ● ● ● )
: 상세기능 버튼을 클릭하여 게시물 삭제, 수정, 공유를 할 수 있는 기능
(더 세부적으로 들어가자면 위의 기능을 제외하고도 몇 가지의 기능들이 더 있겠지만, 큼지막하게 보면 위와 같이 나눌 수 있음.)

위의 저러한 기능들을 만약 한 파일 내부에서 코드로 작성하게 되면 못해도 1000~2000줄에 해당되는 방대한 양의 코드가 될 수도 있음.

뿐만 아니라, 가독성도 안좋아지고 추후에 해당 페이지에 2) 좋아요 기능 이 오류가 나더라도, 그와 관계 없는 다른 기능들의 코드를 전부다 봐야하는 문제가 생길 수도 있음.(즉, 유지보수 관점에서도 좋지 않다 라는 뜻.)

그래서 저러한 기능들을 각각의 파일들로 구성하는 것을 '모듈화' 라고 볼 수 있고, 조금 더 깊게 들어가면 3) 상세기능의 내부에 들어가있는 삭제, 수정, 공유에 대한 기능들도 각각 모듈화 시킬 수도 있기 때문에 단순히 '크기' 라는 것에 초점을 맞추면 안됨.(정말 적게는 함수 한 줄도 모듈이라고 부를 수 있음.)

그래서 이러한 관점의 프로그래밍을 '모듈화 프로그래밍' 이라고 하는데 한번 쯤 프로그래밍을 공부해봤다면 들어봄.

모듈 내부에는 import로 외부모듈의 기능을 가져오고 export로 외부 모듈에서의 접근을 허용하여 모듈의 기능을 내보냄.

하지만, 위에서 설명한 모듈화 프로그래밍도 100% 효율성이 좋다고만은 볼 수 없음.

ES6문법(모듈 간 import/export)를 인식하지 못하는 브라우저도 있음.
소프트웨어가 커지면 커질 수록 각각의 세분화된 모듈 파일이 늘어남.

  • 하나. 여러 개의 파일을 브라우저에서 로딩한다면 네트워크가 그만큼 소모되어 속도가 저하될 수 있음.(서버와의 접속이 많을수록 애플리케이션은 느리게 로딩이 됨. 네트워크 부하 발생)
  • 둘. 모듈 간의 변수 충돌 등의 위험성이 존재함. (서로 다른 패키지들이 서로 같은 변수나 함수를 사용하면서 예상하지 못한 충돌 발생, 스코프 문제)

그래서 이러한 문제들을 바탕으로 나온 것이 웹팩(Webpack)의 번들링(bundling) 개념.

장점(사용이유)
1. 번들링
번들링(Bundling)이란 기본적으로 여러 개로 흩어져 있는 파일들을 압축, 난독화 등을 하여 하나의 파일로 모아주는 역할을 함.
이러한 번들러의 주 역할은 서로 연관(의존성) 있는 여러 JS파일(모듈)들을 하나의 번들(Bundle) 파일로 묶어주는 역할을 함. (import/export 활용)

Node.js는 브라우저 외의 환경에서 Javascript를 동작하게 해주며 Javascript 개발자들은 여러 툴을 만들고, npm을 통해 배포를 하기가 쉬워짐. 이러한 상황에서 번들러라는 소프트웨어가 나옴.
번들러는 브라우저가 script를 부르기전에 미리 하나의 파일로 만들어둠. HTML은 하나의 JS파일만 부르면 됨. 번들링을 사용해 module이라는 스펙을 사용할 수 없는 환경에서도 사용할 수 있게 됨.

번들링 기능을 지원하는 번들러 중에서는 RequireJS, Browserify, Rollup, Parcel 등이 있지만, 대표적으로 현재 가장 많이 사용되어지고 있는 것이 Webpack.

1) 파일이 한번에 많은 요청을 하지 않아도 됨. 번들러가 없다면 JavaScript 모듈이 무수히 많아질 수 있고, 서버에서 이 많은 파일들을 모두 다운 받는다면 네트워크에 무리가 감. ( 웹에서 파일을 다운받을 때 여러 개로 나누어서 다운받는 속도보다 하나로 뭉쳐서 다운받는 것이 훨씬 빠르기 때문에, 작업할 때는 여러 개로 나누어서 작업하고 최종적으로 웹서버에 올릴 때는 하나의 파일로 압축하여 올리는 것이 시초. )
이전에 각 파일들마다 서버에 요청을 하여 자원을 얻어와야했던 반면, 같은 타입(html, css, js 등)의 파일을 묶어서 요청/응답을 받기 때문에 Network cost가 줄게 됨.

2) 이 모듈 시스템(import/export)조차도 사실 ES6(ES2015)에서 본격 표준화 및 지원되기 시작한 문법. 그래서 어떤 브라우저가 ES6을 지원한다고 해도 아직까지 새로 생긴 Module 기능을 온전히 지원하지 않는 경우도 있음.
이처럼 하나의 파일에 포함된 여러 모듈 간의 의존성을 모든 브라우저에서 인식할 수 있게끔 하나의 파일로 묶어 주는 역할을 모듈 번들러 가 하게 됨.

모듈 단위로 개발하여 유지보수성을 높일 수 있음. 한 파일에 코드가 1억줄 있을 경우 한줄 한줄 찾는데만 시간이 너무 걸림. 모듈 단위로 구분하게 된다면 가독성과 유지보수성을 모두 가져갈 수 있음.

3) Webpack 4버전 이상부터는 [ development ], [ production ] 이 두가지의 mode 지원을 하면서, 특히 production 모드로 번들링을 진행할 경우, 코드 난독화, 압축, 최적화(Tree Shaking) 작업을 지원하기도 함. 한마디로 상용화 된 프로그램을 사용자가 느끼기에 더욱 쾌적한 환경 및 보안까지 신경쓰면서 노출시킬 수 있다는 점.
[참고] https://ui.toast.com/fe-guide/ko_BUNDLER/

  1. 코드를 수정할 때마다 웹 브라우저를 리로딩하는 등의 여러 기능.
    (한 글자를 수정해도 번들을 새로 만듦.)

구성요소
1) Entry
자바스크립트(혹은 html, css, png 같은 다른 타입) 파일로 이루어진 여러 모듈들을 포함하고 있는 파일을 정의할 때 사용됨. 만약 어플리케이션이 App.js라는 파일 내부에 선언되어진 여러 모듈들로 실행이 되어진다면, App.js가 웹팩의 Entry 파일.
즉, 각 모듈들이 바라보는 최상위 자바스크립트 파일(App.js)을 중심으로 번들링 되어짐.
( 선언방법은 어플리케이션의 루트 경로에 webpack.config.js 파일을 만들고, 그 내부에 정의. )

//* root(node_modules이 설치된 디렉토리)의 webpack.config.js

module.exports = {

	entry: "./App.js",
	
}

Entry Points

2) Output
말그대로 웹팩의 번들링에 대한 결과물을 어디에 만들어낼 건지, 그리고 어떤 이름을 만들건지 정의하는 요소.

//* Entry를 정의했던 동일한 webpack.config.js
//* 미리 root 디렉토리에 dist 폴더를 만들어두고, bundle.js라는 이름으로 output 지정.

module.exports = {

	entry: './App.js',
    	output: {
        
    		path: './dist',
                filename: 'bundle.js'
    	
        }

}

Output

3) Loader


Webpack의 주요 구성 요소 중 하나인 로더(Babel-Loder)가 일부 브라우저에서 지원이 되지 않는 ES6 형식의 자바스크립트 파일을 ES5로 변환하여 사용가능하게 함. 웹 개발을 진행할 때 크롬과 같은 대중적인 브라우저만 고려하는 것이 아닌, 다른 모든 브라우저에 대해서도 커버가 가능하다는 뜻.
style-loader, css-loader, sass-loader 라는 로더를 사용해 SASS를 CSS로 변환해 사용할 수 있게 함.
(TransPile)

WebPack은 모든 파일을 모듈로 관리함. 자바스크립트 파일 뿐만 아니라 이미지, 폰트, 스타일시트도 전부 모듈로 관리.

위의 빨간색 박스를 보면, 로더는 Webpack이 오직 Javscript & JSON 파일만 이해가능하다고 나와있는데, 우리가 현재 사용하고 있는 대부분의 웹 어플리케이션 같은 경우 js파일이나 json파일 뿐만 아니라 html, css, png와 같은 정적타입의 파일들도 포함고 있는 것이 대부분.

다른 타입 파일(html, css 등)들을 Webpack(javaScript, JSON만 인식)이 이해할 수 있게 해주고, 번들링을 해주는 것이 바로 로더

//* module 내부에서 로더에 대한 정의를 선언.
//* rules 내부의 test는 적용할 파일의 타입을 선언.(정규식 사용 가능)
//* 이어서, use는 test에 선언한 파일타입에 맞는 로더를 정의하면 된다.
//* exclude에는 로더 적용을 제외시킬 파일을 정의
//* (node_modules 디렉토리 내부에 있는 노드모듈까지 굳이 번들링 할 필요는 없기에....)

module.exports = {

	entry: './App.js',
    	output: {
        
    		path: './dist',
                filename: 'bundle.js'
    	
        },
        module: {
        
        	rules: [
            	
                	{
                		test: /\.txt$/,
                    		exclude: /node_modules/, 
                 		use: 'raw-loader'
                 	}
                
            	]
        
        },

}

4) Plugin
로더(Loader)와의 차별점을 두면서 설명이 가능할 것 같음. 로더 같은 경우 위의 로더 선언 코드에서 보듯이, 파일 단위로 작업이 이루어지는 반면, 플러그인(Plugin) 같은 경우 번들링 된 결과물에 대해서 적용할 수 있는 속성.

여러 가지 플러그인들이나 기능들이 더해져서 WebPack이 단순히 파일만 합치는 작업이 아니고
번들링 된 js 파일에 대한 난독화(UglifyJsPlugin 사용), 번들된 css, js 파일들을 html 파일에 주입(html-webpack-plugin 사용) CSS Preprocessing과 이미지 최적화 등 다양하게 확장 됨.

//* 'plugin' 이 아닌 'plugins' 에 주의!
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

	entry: './App.js',
    	output: {
        
    		path: './dist',
                filename: 'bundle.js'
    	
        },
        module: {
        
        	rules: [
            	
                	{
                		test: /\.txt$/,
                    		exclude: /node_modules/, 
                 		use: 'raw-loader'
                 	}
                
            	]
        
        },
        plugins: [
        
        	new HtmlWebpackPlugin(),
        
        ]

}

Babel(바벨)

Transpiler(특정 언어로 작성된 코드를 비슷한 다른 언어로 변환시키는 것)

Complie vs Transpile
Complie이란 작성된 코드를 기계가 이해 할 수 있는 바이너리 코드로 바꾸는 것이고 Transpile이란 언어 대 언어로 변형하는 작업을 의미함.

Complie: 언어 => 기계
Transpile: 언어 => 언어
보통 새로운 문법이 나왔는데 아직 벤더(Vendor)들이 해당 기능을 다 구현하지 못한 경우, 코딩은 신규 문법으로 작성하고 Transpile한 결과는 예전 문법으로 작성해주는 방식.

JavaScript와 같이 표준을 만드는 집단(ECMA International)과 해당 기능을 제공하는 Vendor들(브라우저 제작사: Chrome/Google, Safari/Apple, Firefox/Mozilla, IE/Microsfot등)이 다분화되어 있는 경우, 표준과 Vendor들의 지원 현황이 속도가 맞지 않아서 자주 사용되는 기법.

앞서 설명한 Less, Sass, Stylus > CSS 로 변환하는 것도 Transpile 일종.

Webpack과 Babel
Webpack이 번들링을 해주면서 Babel을 사용해 ES6 문법을 ES5 문법으로 변환하는 등의 기능을 함.
CRA에서는 Webpack, Babel 설정이 되어있지만, CRA를 사용하지 않고, 리액트 프로젝트를 만든다면, Webpack을 설정하면서 babel도 설정해줘야 함.

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

module.exports = {
  mode: "development",
  entry: "./src/index.js",
  output: {
    filename: "bundle.js",
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.s?css$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader",
            options: {
              minimize: true,
            },
          },
        ],
      },
    ],
  },

  devServer: {
    host: "localhost",
    port: 3000,
    open: true,
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: "./index.html",
    }),
  ],
};



다음 테스트를 위한 코드를 작성함.

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
  <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>bundling</title>
  </head>
  <body>
    <h1 class="card-title">Card Title</h1>
    <button class="btn-change">버튼 변경</button>
  </body>
</html>
//src/btn.js
const btnChange = document.querySelector(".btn-change");
export { btnChange };
//src/color.js
const cardTitle = document.querySelector(".card-title");
const changeColor = function (color) {
  cardTitle.style.backgroundColor = color;
};
export { changeColor };
//src/index.js
import "../style.scss";
import { btnChange } from "./btn";
import { changeColor } from "./color";
btnChange.addEventListener("click", function () {
  changeColor("pink");
});
console.log("Hello World");
//style.scss
body {
  background-color: #369fff;
}

이후 build와 start를 실행해보면 정상적으로 작동됨을 확인할 수 있음.

바벨 역할

  1. 트랜스파일러
    바벨은 코드를 재작성해주는 트랜스파일러 프로그램.
    바벨은 개발자의 컴퓨터에서 돌아가는데, 이를 실행하면 기존 코드가 구 표준을 준수하는 코드로 변경됨. 변경된 코드는 웹사이트 형태로 사용자에게 전달됨.
    웹팩(webpack)과 같은 모던 프로젝트 빌드 시스템은 코드가 수정될 때마다 자동으로 트랜스파일러를 동작시켜줌.
    JSX 문법으로 작성된 코드를 브라우저에서 실행 가능한 JavaScript로 변환해줌.
  2. 폴리필 (polyfill)
    새로운 문법을 사용해 코드를 작성하면 트랜스파일러는 이를 구 표준을 준수하는 코드로 변경해줌.
    반면, 새롭게 표준에 추가된 함수는 명세서 내 정의를 읽고 이에 맞게 직접 함수를 구현해야 사용할 수 있음.
    변경된 표준을 준수할 수 있게 기존 함수의 동작 방식을 수정하거나, 새롭게 구현한 함수 스크립트를 "폴리필(polyfill)"이라 부름.
    폴리필(polyfill)은 말 그대로 구현이 누락된 새로운 기능을 메꿔주는(fill in) 역할을 함.

Vite

Vite

npm

Node.js를 설치하면 npm(node package manager) 이 자동으로 설치 되는데 npm을 사용하기 위해서는 노드(Node.js)가 설치되어 있어야 함. 터미널에서 아래의 명령어를 실행 함으로써 Node.js 의 버전을 확인할 수 있음. 노드 버전이 정상적으로 확인되면 설치도 정상적으로 이루어진 것.
$ node -v

Node 기반의 패키지를 사용하려면 npm(node package manager) 이라는 패키지 도구가 필요함. npm 을 통해 다양한 패키지를 설치하고 버전을 관리할 수 있음. 마찬가지로 npm 버전을 확인하는 명령어를 통해 설치가 정상적으로 이루어졌는지 확인해볼 수 있음.
$ npm -v

CRA(Create-React-App)

리액트 프로젝트를 시작하는데 필요한 개발 환경을 세팅 해주는 도구(toolchain)

리액트는 UI 기능만 제공한다. 따라서 개발자가 직접 구축해야하는 것들이 많다. 전반적인 시스템을 직접 구축할 수 있으니 원하는 환경에 맞게 최적화할 수 있지만, 반대로 신경쓸 것이 많기 때문에 처음 시작하는 단계에서는 직접 개발 환경을 구축하기 어려울 수 있다.

리액트 팀에서는 이러한 문제를 해결하기 위해 CRA(Create-React-App)을 만들었다. CRA는 리액트로 웹 애플리케이션을 만들기 위한 환경을 제공한다. CRA를 이용하면 하나의 명령어로 리액트 개발환경을 구축할 수 있다.

CRA에는 바벨과 웹팩과 같이 리액트 애플리케이션 실행에 필요한 다양한 패키지가 포함되어 있으며, 테스트 시스템, ES6+ 문법, CSS 후처리 등 거의 필수라고 할 수 있는 개발 환경도 구축해 준다. 이러한 개발 환경을 직접 구축할 경우 시간이 오래 걸릴 뿐 아니라 유지 보수도 해야한다. CRA를 이용하면 개발 환경 세팅을 해주기 때문에 기존 기능을 개선하거나 새로운 기능을 추가했을 때 패키지 버전만 올리면 된다.

CRA 구성

  • node.modules
    CRA 를 구성하는 모든 패키지 소스 코드가 존재하는 폴더

  • package.json
    CRA 기본 패키지 외 추가로 설치된 라이브러리/패키지 정보(종류, 버전)가 기록되는 파일
    모든 프로젝트마다 package.json 하나씩 존재

    • dependencies : 리액트를 사용하기 위한 모든 패키지 리스트, 버전 확인 가능. 실제 코드는 node.modules 폴더에 존재
      • 새로운 Library(package) 설치 시
        누군가 만든 소스코드를 다운받는 것
        npm으로 설치 (ex. npm install slider)
        설치 시 node modules 에 자동으로 설치됨.
        하지만 package.json - dependencies 에 추가 자동으로 되는 건 아님.
        그래서, npm install slider —-save
        —-save 까지 작성해야 dependencies 에 추가됨
        (npm 버전이 업그레이드 됨에 따라 자동으로 추가되는 경우가 많지만 여전히 불안한 패키지들이 존재하기 때문에 패키지 설치 시 —-save 까지 입력하는 것을 권장합니다.
    • scripts
      • start : 프로젝트를 development mode(개발 모드) 실행을 위한 명령어. npm run start.
      • build : 프로젝트 production mode(배포 모드) 실행을 위한 명령어. 서비스 상용화.
  • .gitignore

    • .gitignore 파일에 github 에 올리고 싶지 않은 폴더와 파일을 작성할 수 있다.
    • push 를 해도 .gitignore 파일에 작성된 폴더와 파일은 올라가지 않는다.
  • src

    • index.js
      React의 시작 (Entry Point)
      • ReactDOM.render( <App /> , document.getElementById('root')) : ReactDOM.render 함수의 인자는 두 개. 첫 번째 인자는 화면에 보여주고 싶은 컴포넌트. 두 번째 인자는 화면에 보여주고 싶은 컴포넌트의 위치 ( 함부로 수정하면 안됨 )
    • App.js
      현재 화면에 보여지고 있는 초기 컴포넌트. Westagram 작업 시 <Login /> 컴포넌트, <Main /> 컴포넌트를 그 자리에 대체하여 작업하면 된다. React Router 를 배운 후에는 <Routes /> 컴포넌트가 최상위 컴포넌트로 그 자리에 위치하게 된다.
  • public폴더
    우리가 웹을 배포한다는 건 특정 폴더를 서버 컴퓨터에 올려두는 것
    그래서 서버랑 연결된 특정 url로 접근하면 해당 폴더의 파일을 요청할 수 있는 것 → 뒤에 따로 추가적인 url을 안붙이면 index.html을 요청한다.
    e.g.) [https://naver.com](https://naver.com)로 접근하면 naver.com에 연결되어있는 서버 컴퓨터의 폴더에 접근해서 index.html을 가져오는 것
    우리가 CRA를 배포했을 때 실제 서버에 배포되는 폴더가 public폴더
    그래서 우리 서버 주소로 접근하면(개발서버의 경우http://localhost:3000) public 폴더에 들어가는 것과 동일하다.
    그래서 우리가 public에 특정 디렉토리, 파일을 만들어두면 서버 url 통해서 접근이 가능하다.
    예시로, public/images/test.png 파일을 만들어두면, 서버에 접속해서 해당 파일에 접근할 수 있다
    실제로, test.png파일을 만들고, http//localhost:3000/images/test.png 을 브라우저 주소창에 입력하면 우리가 작성해둔 파일이 오는것을 볼 수 있다.

참고
https://velog.io/@mingdolacucudas/%EB%B0%8D%EB%B6%80%EC%8A%A423-%EA%B0%80%EB%82%B4%EC%88%98%EA%B3%B5%EC%97%85-CRA%EC%97%90-%EB%8F%84%EC%A0%84%ED%95%B4%EB%B3%B4%EC%95%98%EC%8A%B5%EB%8B%88%EB%8B%A4-%EB%B0%94%EB%B2%A8%EA%B3%BC-%EC%9B%B9%ED%8C%A9%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC

https://velog.io/@ckstn0777/11.2%ED%99%94-TIL-%EC%9B%B9%ED%8C%A9-%EB%8D%B0%EB%B8%8C-%EC%84%9C%EB%B2%84%EC%99%80-%ED%95%AB-%EB%A6%AC%EB%A1%9C%EB%94%A9

https://storycode.tistory.com/419

https://www.daleseo.com/js-babel-node/

https://chanyeong.com/blog/post/27

https://jaroinside.tistory.com/11

https://velog.io/@code_newb/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95-Webpack-Babel

https://developer-talk.tistory.com/550

https://velog.io/@muchogusto/CRA%EB%9E%91-%EC%9B%B9%ED%8C%A9-%EB%B0%94%EB%B2%A8-%EB%B9%8C%EB%93%9C-%EC%B0%A8%EC%9D%B4

https://velog.io/@ckstn0777/11.2%ED%99%94-TIL-%EC%9B%B9%ED%8C%A9-%EB%8D%B0%EB%B8%8C-%EC%84%9C%EB%B2%84%EC%99%80-%ED%95%AB-%EB%A6%AC%EB%A1%9C%EB%94%A9

https://chanhuiseok.github.io/posts/react-3/

https://chanhuiseok.github.io/posts/web-7/

https://oen-blog.tistory.com/53

https://velog.io/@hoje15v/React-Node.js-CRA-JSX

https://velog.io/@cjy0029/%EC%9B%B9%ED%8C%A9-%EB%A1%9C%EB%8D%94

https://velog.io/@ksung1889/%EB%B2%88%EB%93%A4%EB%9F%ACbundler%EB%9E%80

https://velog.io/@muchogusto/CRA%EB%9E%91-%EC%9B%B9%ED%8C%A9-%EB%B0%94%EB%B2%A8-%EB%B9%8C%EB%93%9C-%EC%B0%A8%EC%9D%B4

https://velog.io/@code_newb/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B0%9C%EB%B0%9C-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95-Webpack-Babel

https://humanwater.tistory.com/1?category=914158

https://humanwater.tistory.com/3?category=914158

https://velog.io/@dbsbest10/Webpack-%EA%B3%BC-Babel%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C

https://tech.weperson.com/wedev/frontend/bundling-transpiler/#%E1%84%90%E1%85%B3%E1%84%85%E1%85%A6%E1%86%AB%E1%84%89%E1%85%B3%E1%84%91%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%AF%E1%84%85%E1%85%A5-transpiler

https://rat2.tistory.com/25

https://kangdanne.tistory.com/190

https://baegofda.tistory.com/238

https://jeonghwan-kim.github.io/js/2017/05/15/webpack.html

https://tecoble.techcourse.co.kr/post/2021-07-10-webpack-exercise/

profile
선명한 기억보다 흐릿한 메모

0개의 댓글