[개발PC : MacBook]
Chapter05) 웹사이트 UI 구성하기 : 개츠비
학습 목표 : 개츠비는 정적 웹사이트 개발 프레임워크입니다. 이번 장에서는 개츠비를 이용한 개발 환경을 구축하고, 백엔드에서 데이터를 불러와서 정적 웹사이트를 빌드해봅니다.

- 개츠비(Gatsby)는 다양한 데이터 소스를 이용하여 정적 웹사이트를 빌드하는 리액트 기반 오픈 소스 프레임워크입니다.
리액트의 장점을 그대로 가져오면서 정적 웹사이트를 쉽게 만들 수 있어서 인기가 높습니다.
코로나보드 또한 개츠비를 이용하여 정적 웹사이트 형태로 개발했습니다.
'정적 페이비 빌더' 구현에 개츠비를 이용했습니다.

-
장점 : 정적 웹페이지 방식을 사용하기 때문에 웹사이트 운영 비용이 매우 저렴하고 페이지 로링 속도가 빠름(검색 엔진 최적화에 유리함), 리액트를 이용하여 정적 웹페이지를 개발할 수 있어서 개발 생산성이 좋음
-
단점 : 콘텐츠 내용이 변경될 때마다 다시 빌드하여 배포해야 하는 번거로움, 실시간으로 변경되는 데이터나 게시판 같이 사용자들이 동적으로 만들어내는 콘텐츠를 보여주는 데 최적화되어 있지는 않음
[개츠비]
P181~186
[개츠비 개발 환경 구축하기]
P186~189
<개츠비 프로젝트 구조>
-
/ : 프로젝트 루트 디렉터리입니다.
-
.cache : 개츠비 빌드 과정에서 생성되는 산출물을 캐싱해두는 디렉터리로, 이전 빌드의 산출물을 캐싱하여 다음번 빌드를 더 빠르게 해주는 역할을 합니다. 직접 수정할 일은 없지만 변경된 데이터가 제대로 나오지 않는 다면 gatsby clean 명령으로 삭제하세요.
-
public : 빌드가 완료된 정적 웹사이트의 결과물이 저장된 디렉터리로, 나중에 gatsby build 명령으로 프로덕션용 정적 웹사이트 빌드한 후, 이 디렉더리 안의 모든 파일을 파일 서버나 AWS S3 등에 업로드하여 사용합니다. 역시 gatsby clean 명령으로 청소할 수 있습니다.
-
src/pages : 정적 웹사이트 빌드에 사용할 소스 파일들이 담겨 있는 디렉터리로, 파일 하나가 정적 웹페이지 하나와 1:1 매핑됩니다.
-
static : 웹사이트에 사용될 정적 자원(이미지, 폰트 등)을 넣어둡니다. 이 디렉터리에 존재하는 파일들은 빌드 시 public 디렉터리로 복사됩니다.
-
.gitignore : 깃이 해당 패턴과 일치하는 파일을 저장소에 추가하지 않고 무시합니다.
-
.cache와 public 디렉터리는 빌드 과정에서 자동으로 생성되기 때문에 소스 저장소에 추가하여 관리할 필요가 없으므로 .gitignore 파일에 이미 추가되어 있습니다.
-
.prettierrc : 자바스크립트 코드 포매팅 도구인 프리티어의 설정 파일입니다.
-
.prettierignore : 프리 티어의 설정 파일로, 자동 포매팅에서 제외하고 싶은 파일이 있다면 해당 파일 또는 해당 파일의 패턴을 이곳에 정의해줍니다.
-
gatsby-config.js : 개츠비의 설정 파일입니다. 개츠비 빌드 시 플러그인을 추가하고 설정할 수 있으며, 사이트 제목, 설명, URL 등 사이트의 메타 정보 역시 여기에 정의합니다.
-
package.json : 개츠비 프로젝트 또한 노드JS 패키지 매니저를 사용하고 있기 때문에 이 파일이 존재합니다.
일반적인 노드JS 프로젝트와 동일하게 원하는 의존성을 추가 또는 삭제하면 이 파일이 업데이트됩니다.
이 파일 내용을 살펴보면 개츠비 템플릿을 통해 생성된 프로젝트가 어떤 버전의 개츠비와 리액트를 의존성으로 사용하는지 확인할 수 있습니다.
[리액트 컴포넌트 기본]

- (1) 리액트는 자바스크립트와 HTML을 섞어서 사용할 수 있도록 JSX(Javascript XML)라는 자바스크립트 확장 문법을 사용합니다.
JSX 문법을 사용하려면 리액트를 반드시 임포트해야 합니다.
- (2) 함수 정의로, export 키워드는 이 함수를 다른 파일에서 임포트해서 사용할 수 있도록 합니다.
Slide() 함수의 매개변수에 리액트 컴포넌트는 props라는 매개변수 하나를 받도록 정해져 있습니다.
이 변수를 통해 해당 컴포넌트를 렌더링하는 데 필요한 값들을 부모 컴포넌트로부터 전달받습니다.
-
(3) Slide 컴포넌트도 props를 통해서 title과 children값을 전달받아서 사용하고 있습니다.
-
(4) 마지막으로 반환값을 살펴보면, 컴포넌트가 렌더링할 HTML 요소와 자바스크립트 코드가 섞인 표현식을 반환하고 있습니다.
JSX 문법은 HTML 요소를 자바스크립트 코드 내에서 쉽게 작성할 수 있습니다.
HTML 요소의 태그 속성이나 콘텐츠 내용을 자바스크릅트 변수와 바인딩할 수 있어서 매우 편리합니다.
이번 예에서 title과 children 변수를 각각 h2와 div 요소 내용을 바인딩했다(자바스크립트 변수를 HTML 코드에 삽입할 때는 중괄호로 감싸줍니다.).
이렇게 하면 title과 children 값이 변경될 때마다 Slide 컴포넌트가 자동으로 다시 렌더링되며, 나아가 변경된 값이 UI에 즉시 반영됩니다.
이처럼 특정 변수의 값을 연결된 UI와 동기화시키는 작업을 바인딩(binding)이라고 합니다.
이렇게 반환된 JSX 표현식은 자바스크립트 코드가 아니기 때문에 웹브라우저에서 바로 실행하면 오류가 납니다.
그래서 빌드 과정에서 바벨 컴파일러가 JSX 표현식을 자바스크릅트 코드로 컴파일하며, 웹브라우저는 정상적인 자바스크립트 코드를 받기 됩니다.
!! 클래스 컴포넌트 vs. 함수 컴포넌트
-
리액트에서 컴포넌트를 정의할 때 자바스크립트 클래스를 이용하는 방법이 있고, 앞의 예처럼 함수를 이용하는 방법이 있습니다.
-
함수 컴포넌트가 클래스 컴포넌트보다 간결하고 이해하기 쉬우며 거의 대부분의 기능이 동일하기 때문에 최근에 함수 컴포넌트가 더 많이 사용됩니다.
!!

[CSS로 리액트 컴포넌트에 디자인 입하기]
CSS가 중앙집중적으로 관리되는 방식은 사이트의 전체적인 다자인 일관성을 향상시킵니다.
하지만 반대로 특정 부분의 스타일만 변경하려다가 의도치 않은 부분까지 변경하는 실수가 일어나기 쉽다는 단점이 공존합니다.
이러한 단점을 보완하기 위해 CSS를 리액트 컴포넌트 내부에 바로 정의하는 CSS-in-JS 방식을 많이 사용합니다.
CSS-in-JS를 더 편리하게 사용하도록 도와주는 다양한 오픈 소스 라이브러리가 있는데 emotion은 그 중 하나입니다.
<emotion 라이브러리 설치>
$npm install gatsby-plugin-emotion @emotion/react @emotion/styled
[정적 웹페이지 추가하기]
생성될 페이지를 추가하는 방법은 두 가지입니다.
첫번째는 파일 기반으로 추가하는 방법입니다.
-
원하는 내용으로 채워둔 파일을 수동으로 하나씩 만들어서 src/pages 디렉터리에 넣어둡니다.
-
그러면 개츠비 빌드 과정에서 이 파일들이 정적 웹페이지로 만들어집니다.
두번째는 데이터베이스와 같은 콘텐츠 관리 시스템에서 동적으로 원하는 데이터를 불러온 후, 불로운 데이터 수만큼 정적 페이지를 생성하는 방법입니다.
- 예를 들어 데이터베이스에 저장되어 있는 블로그 글이 20개라면 총 20개 페이지를 생성하는 식입니다.
<파일 기반 페이지 정의하기>
src/pages 하위의 디렉터리와 파일 구조를 그대로 정적 웹페이지로 바꿔줍니다.

!! 파일 이름에 특별한 규틱은 없으나 일반인에게 가독성이 좋은 kebab-case를 권장합니다.
kebab-case란 first-example처럼 단어와 단어 사이를 -로 구분하는 방식을 말합니다.!!
<Node API 기반 페이지 추가하기>
외부에서 데이터를 불러와 페이지를 생성하는 방법입니다.
개츠비가 제공하는 API를 이용해야 하는데, 이번 절에서는 그중 createPages 후크를 이용하는 법을 알아보겠습니다.
!!후크(Hook)
후크란 운영체제나 다른 소프트웨어의 동작을 가로채서 원래 기능을 덧붙이거나 완전히 교체하는 행위.
여기서는 개츠비의 빌드 과정 중 페이지를 생성하는 동작을 가로채서 우리가 원하는 페이지를 추가하도록 기능을 덧붙이는데 사용했습니다.
!!
개츠비는 다양한 API를 제공하며 종류별로 구분해 Link API, Config API, Node API 같은 이름을 붙여놓습니다.
이 중 Node API에서 createPages()라는 후크 함수를 이용할 겁니다.
개츠비가 빌드 과정에서 이 후크 함수를 호출해주는데, 개발자에게 개츠비의 특정 기능을 사용자화할 기회를 주는 함수라고 생각하면 쉽다.
이 후크 함수 안에 코드를 작성하여 원하는 형태로 페이지를 정의할 것입니다.
데이터베이스에서 블로그 글들을 불러운 후 그 개수만큼 createPage() 함수를 호출하면 호출 횟수만큼 정적 페이지가 생성됩니다.
[백엔드 데이터 불어오기]

$npm install axios@0.21.1 date-fns@2.21.1 date-fns-tz@1.1.4 lodash@4.17.20
P204~215
복습 차원에서 정리해보겠습니다.
gatsby develop 명령을 실행하면 개츠비가 다음 과정을 거쳐 정적 웹사이트를 만들어줍니다.
- 정적 웹사이트 빌드
-
createPages 후크 호출(in gatsby-node.js)
-
- getDataSource() 호출(in data-loader.js)
-
-
- 국가 정보 로드 및 가공(from 파일)
-
-
-
- 국가별 코로나19 통계 정보 로드(from API 서버)
-
-
- dataSource를 인수로 건네 createPage() 호출
-
-
- 템플릿(single-page.js)과 데이터(dataSource)를 조합해 정적 웹페이지(.html 파일) 생성
-
- 웹 서버 구동
!!데이터를 불러오는 시점 : 빌드타임 vs. 런타임
런타임이란 웹페이지를 구성하는 HTML, CSS, 자바스크립트가 사용자의 웹브라우저에서 실행되고 있는 시점을 의미합니다.
SPA로 개발된 웹사이트는 보통 런타입에 자바스크립트를 통해 API 등을 호출하여 필요한 데이터를 불러와 가공하여 사용자에게 보여줍니다.
따라서 웹사이트 이용자가 많아질수록 API 호출 횟수가 늘어나고 그 만큼 API 서버의 부담이 커집니다.
대신 항상 최신 데이터를 보여준다는 장점이 있습니다.
한편 빌드타임은 HTML, CSS, 자바스크립트 파일을 배포에 적합한 형태로 패키징(packaging) 또는 번들링(building)하는 시점을 의미합니다.
개츠비에서는 이 시점에 API 통해 필요한 데이터를 불러와 정적 웹페이지 생성에 사용합니다.
빌드 시점에만 API를 호출하기 때문에 웹사이트 이용자가 아무리 많아져도 API 서버의 부담은 증가하지 않습니다.
데이터를 얻는 시점을 꼭 런타임과 빌드타임 중 택일할 필요는 없습니다.
오히려 두 가지를 적절히 섞어 사용하면 더 효율적인 웹사이트를 만들 수 있습니다.
!!