프런트 엔드: 정적 사이트 업데이트에 Gatsby.js 및 Node.js 사용

게시 됨: 2022-03-11

일부 프로젝트 요구 사항의 경우 정적 페이지 생성으로 충분할 뿐만 아니라 속도 및 확장성 면에서 가장 효율적 입니다.

이 시리즈의 전반부에서는 Node.js, Express, MongoDB, cron 및 Heroku를 결합하여 일일 일정에 따라 GitHub의 API를 사용하는 CI 지원 백엔드를 제공했습니다. 이제 Gatsby를 믹스에 추가하여 정적 페이지 생성 프로젝트를 완료할 준비가 되었습니다.

프런트 엔드 개발: Gatsby 웹 사이트 만들기

Gatsby 웹사이트는 React를 기반으로 하기 때문에 React로 웹사이트를 구축하는 방법에 이미 익숙하다면 도움이 됩니다.

스타일링을 위해 Bootstrap, reactstrap 및 react-markdown을 선호했습니다. GitHub의 릴리스 정보는 Markdown 형식으로 저장되므로 변환기가 필요합니다.

정적 웹사이트 프로젝트 구조

파일/폴더 구조는 다음과 같습니다.

빈 공용 폴더와 package.json과 같은 파일용 src 폴더가 있는 표준 프런트 엔드 프로젝트 루트. src 폴더 아래에는 global.css에 대한 스타일 하위 폴더와 all-repositories.js 및 repository.js에 대한 템플릿 하위 폴더가 있습니다.

이 파일은 무엇을 위한 것입니까? 보자:

  • env.developmentenv.production 은 환경 변수 구성 파일입니다.
  • all-repositories.js 템플릿은 리포지토리 목록이 포함된 홈페이지에 사용됩니다.
  • repository.js 템플릿은 주어진 리포지토리에 대한 세부 정보를 표시하는 데 사용됩니다.
  • gatsby-node.js 는 백엔드 엔드포인트를 사용하고 createPage 메소드를 실행하는 곳입니다.
  • package.json 에는 항상 그렇듯이 종속성과 프로젝트 속성이 포함되어 있습니다.
  • global.css 는 기본 스타일 시트 파일입니다.

개츠비 웹사이트 구현

백엔드와 마찬가지로 프론트엔드의 package.json 에 필요한 종속성을 추가한 후 npm install (또는 Yarn이 설치된 경우 yarn )을 실행합니다.

 { // ... "dependencies": { "axios": "^0.18.0", "bootstrap": "^4.3.1", "gatsby": "^2.0.0", "react": "^16.5.1", "react-dom": "^16.5.1", "react-markdown": "^4.0.6", "reactstrap": "^7.1.0" } // ... }

env.developmentenv.production 파일에는 해당 환경에 대한 백엔드 URL만 있습니다. 전자에는 다음이 있습니다.

 API_URL=http://localhost:3000

...생산에는 다음이 포함됩니다.

 API_URL=https://[YOUR_UNIQUE_APP_NAME].herokuapp.com

gatsby-node.js 는 코드를 빌드하는 동안 한 번만 실행됩니다. 따라서 여기에서 백엔드에서 필요한 모든 정보를 수집해야 합니다. 그런 다음 응답은 템플릿과 함께 사용되어 적절한 정적 페이지를 생성합니다.

우리의 경우 all-repositories.js 는 모든 리포지토리가 필요하고 repository.js 는 각 반복마다 해당 리포지토리가 필요합니다. 마지막으로 path 필드의 일부로 저장소 ownername 매개변수를 전달하여 페이지 경로를 동적으로 생성할 수 있습니다.

 const axios = require('axios'); require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }); const getRepositoryData = async () => { console.log(process.env.API_URL); return axios.get(`${process.env.API_URL}/repositories`); }; exports.createPages = async ({ actions: { createPage } }) => { let repositories = await getRepositoryData(); repositories = repositories.data; // Create a page that lists all repositories. createPage({ path: `/`, component: require.resolve('./src/templates/all-repositories.js'), context: { repositories } }); // Create a page for each repository. repositories.forEach(repository => { createPage({ path: `/repository/${repository.owner}/${repository.name}`, component: require.resolve('./src/templates/repository.js'), context: { repository } }); }); };

all-repositories.jsrepository.js 의 경우 스타일 지정을 생략하면 단순히 pageContext 에서 데이터를 수집하고 React에서 매개변수를 사용할 때 이를 사용합니다.

all-repositories.js 에서 다음과 같이 pageContextrepositories 필드를 사용합니다.

 export default ({pageContext: {repositories}}) => ( // ... <ListGroup> {/* Because the repositories parameter is a list, we are iterating over all items and using their fields */} {repositories.map(repository => (repository.tagName && <ListGroupItem className="repository-list-item"> // ... <Row> {`${repository.repositoryDescription}`} </Row> // ... </ListGroupItem> ))} </ListGroup> // ... );

repository.js 의 경우 pageContextrepository 필드를 대신 사용합니다.

 export default ({pageContext: {repository}}) => ( <div className="layout"> {repository.tagName && <ListGroupItem className="repository-list-item"> // ... <h1 className="release-notes">{`Release notes`}</h1> <hr/> {/* This the place where we will use Markdown-formatted release notes */} <ReactMarkdown source={`${repository.releaseDescription}`}/> </ListGroupItem> } // ... </div> );

이제 백엔드가 실행 중인지 확인하십시오. 이 프로젝트에서 http://localhost:3000으로 설정했던 것을 기억할 것입니다.

다음으로 프론트 엔드 프로젝트의 루트에서 gatsby develop 을 실행하고 http://localhost:8000을 엽니다.

백엔드에 일부 리포지토리(소유자/이름)를 추가하고 GitHub-API를 통한 업데이트 기능을 한 번 이상 실행했다면 다음과 같이 표시되어야 합니다.

GitHub 리포지토리 샘플에 대한 기본 정보를 보여주는 앱의 홈 페이지를 나열하는 리포지토리

저장소 중 하나를 클릭하면 다음과 같은 내용이 표시됩니다.

facebook/react GitHub 리포지토리에 대한 추가 정보를 보여주는 샘플 리포지토리 세부 정보 페이지

위의 변경 사항 후에 프론트 엔드 구현이 완료됩니다.

엄청난! 이제 배포만 하면 됩니다.

프런트 엔드 배포

이 부분에서 프런트 엔드 애플리케이션을 변경할 필요가 없습니다. Netlify에 배포하기만 하면 됩니다. 거기에 계정이 필요합니다.

하지만 먼저 GitHub, GitLab 또는 Bitbucket에 코드를 배포해야 합니다. 백엔드와 마찬가지로 GitHub에 코드를 배포했습니다.

그런 다음 Netlify에 로그인하고 대시보드에서 "Git의 새 사이트" 버튼을 클릭합니다. 화면의 단계에 따라 Git 공급자를 선택하고 저장소를 찾습니다.

마지막 단계에서 코드를 올바르게 구성했다면 Netlify는 자동으로 빌드 명령을 설정하고 다음과 같이 디렉터리를 올바르게 게시합니다.

Netlify의 빌드 옵션에 대한 올바른 설정: 마스터를 배포하고 "gatsby build"를 빌드 명령으로 사용하고 "public/" 디렉토리에 게시합니다.

그런 다음 "사이트 배포"를 클릭합니다. 무작위로 생성된 Netlify 하위 도메인에 사이트를 배포하지만 언제든지 변경할 수 있습니다. 배포를 https://sample-create-page-api-gatsby.netlify.com으로 변경했습니다. 여기에서 라이브 데모를 찾을 수 있습니다. 완성된 앱의

여태까지는 그런대로 잘됐다. 그러나 정적 페이지 응용 프로그램이므로 최신 상태로 유지하려면 매일 다시 빌드해야 합니다.

빌드 후크를 사용한 일일 업데이트

Netlify의 빌드 후크는 빌드 트리거로 작동하므로 cron 작업이 완료된 후 백엔드에서 트리거할 수 있습니다. 그러기 위해서는 먼저 Netlify에서 빌드 후크를 생성합니다.

"빌드 및 배포 → 지속적인 배포" 섹션에서 "빌드 후크"를 찾을 수 있습니다. "빌드 후크 추가"를 클릭합니다.

Netlify에서 빌드 후크를 찾을 수 있는 위치

이름을 지정하고 저장합니다. (나는 build-from-backend 라고 불렀다.) 그런 다음 생성하는 링크를 복사합니다.

이제 백엔드 프로젝트를 열고 cron.controller.js 파일에 이 몇 줄을 추가해 보겠습니다. 우리는 단순히 Netlify의 빌드 후크 URL에 POST 요청을 보내고 있습니다.

 const Axios = require('axios'); const Config = require('../config/env.config'); const NETLIFY_BUILD_HOOK_URI = Config.netlifyEndpoint; function updateGatsby() { if (NETLIFY_BUILD_HOOK_URI) { console.log('Gatsby build request will be send'); Axios.post(NETLIFY_BUILD_HOOK_URI).then(() => { console.log('Gatsby build request was successful'); }); } }

그런 다음 updateDaily 함수를 업데이트합니다.

 function updateDaily() { RepositoryController.updateRepositories().then(() => { updateGatsby(); }); }

마지막으로, 환경 변수에서 수집할 netlifyEndpoint 속성을 설정하도록 env.config.js 파일을 업데이트합니다.

 "netlifyEndpoint": process.env.NETLIFY_BUILD_HOOK || ""

이제 잠시 전에 Netlify에서 복사한 NETLIFY_BUILD_HOOK 환경 변수를 설정해야 합니다. Heroku에서는 애플리케이션의 "설정" 섹션에서 환경 변수를 설정할 수 있습니다.

커밋을 푸시한 후 백엔드 애플리케이션은 Netlify에 빌드 요청을 보내고 cron 작업이 끝날 때 페이지가 매일 업데이트됩니다. 백엔드 리포지토리 및 프론트엔드 리포지토리의 최종 버전과 함께 빌드 후크 기능을 추가한 리포지토리의 모습은 다음과 같습니다.

프로젝트를 마무리하면서 매일 업데이트할 때마다 백엔드를 깨우는 AWS CloudWatch에 의해 트리거되는 AWS Lambda 함수를 사용하는 방법을 보여드리겠습니다.

AWS Lambda 및 AWS CloudWatch 단순 요청

AWS Lambda는 서버리스 컴퓨팅 플랫폼입니다. 여기에서는 우리의 목적을 위해 이 플랫폼의 아주 기본적인 것만 필요합니다. AWS 계정이 필요합니다.

먼저 계정으로 AWS에 로그인하고 Lambda 관리 콘솔을 찾습니다. 예를 들어 us-east-2 의 경우 https://us-east-2.console.aws.amazon.com/lambda/home에서 찾을 수 있습니다.

아직 선택하지 않은 경우 "기능" 섹션으로 이동합니다.

AWS Lambda "함수" 섹션

여기에서 "함수 생성"을 클릭하여 처음부터 함수를 생성합니다. 설명적인 이름을 지정해 보겠습니다. 우리는 Node.js를 런타임 언어로 사용할 것입니다. 그런 다음 다음 "함수 생성"을 클릭하여 완료합니다.

Node.js 런타임 및 기본 Lambda 권한이 있는 새 역할을 사용하여 create triggerMyBackendAtUTCMidnight에 작성된 AWS Lambda의 "함수 생성" 페이지

index.js 에 코드를 작성할 수 있는 새 함수 페이지로 리디렉션됩니다.

첫 번째 람다 함수를 구현해 보겠습니다. 타사 종속성이 없기 때문에 Node.js의 핵심 모듈을 사용해야 합니다. (대신 타사 종속성을 활성화하려면 AWS의 이 안내서를 따르십시오.)

내보낸 메서드 이름(이 경우 handler )이 페이지의 "Handler" 매개변수와 일치하는지 확인합니다.

값이 "index.handler"인 Handler 매개변수

나머지는 백엔드에 대한 간단한 GET 요청입니다.

 const https = require('https'); exports.handler = async (event) => { return new Promise((resolve, reject) => { https.get(process.env.HEROKU_APP_URL, (resp) => { let data = ''; resp.on('data', (chunk) => { data += chunk; }); resp.on('end', () => { resolve(JSON.parse(data)); }); }).on("error", (err) => { reject("Error: " + err.message); }); }); };

페이지에서 HEROKU_APP_URL 환경 변수를 설정했는지 확인하고 구성을 저장합니다.

AWS Lambda에서 필요한 환경 변수를 설정합니다. 표시된 값은 https://sample-github-api-consumer-nod.herokuapp.com/repositories입니다.

마지막 단계는 매일 업데이트되기 10분 전에 이 기능을 실행하는 CloudWatch 트리거 규칙을 추가하는 것입니다. 이 기사 시리즈에서는 23:50까지 작동합니다.

트리거 규칙을 추가하도록 CloudWatch 이벤트 구성

CloudWatch 트리거 규칙 유형은 "Schedule expression"이고 허용되는 형식에 따라 cron 표현식은 cron(50 23 * * ? *) 입니다.

AWS CloudWatch "트리거 구성" 페이지는 위에 제공된 표현식과 활성화된 트리거를 사용하여 cronDailyUpdate라는 새 규칙을 생성하도록 설정되었습니다.

이제 CloudWatch 규칙에 의해 트리거되도록 AWS Lambda 함수를 구성했습니다.

이제 정적 웹 페이지를 강화합니다: Gatsby/React 및 Netlify

AWS Lambda/CloudWatch가 Node.js/MongoDB/Heroku 백엔드에 추가되고 Gatsby와 Netlify가 프런트엔드를 생성 및 호스팅하여 앱이 완성되었습니다!

이전에 라이브 데모 링크를 공유했지만 내 프로토타입의 향상된 버전을 자유롭게 확인하십시오. 여기에는 몇 가지 추가 변경 사항이 포함되어 있습니다.

이것을 유사한 프로젝트의 청사진으로 사용할 수 있습니다. 이 기사가 더 빠르고 비용 효율적인 방법으로 앱을 프로토타입하는 데 도움이 되기를 바랍니다. 읽어 주셔서 감사합니다!

Toptal은 고급 AWS 컨설팅 파트너입니다.