All Articles

JAMstack Toronto Meetup 후기 + Demo

드디어 캐나다 온지 1개월, 여기와서 처음으로 개발관련 meetup을 나가보았습니다.

그 동안 갔던 meetup이라고는 Coffee & Code 라는 한국의 모각코(모여서 각자 코딩하는 모임)과 비슷한 모임이 있었는데 그 곳만 한 4번 정도 간 것 같네요. 여기서 작업하는 동안은 집중력 향상이 아주 잘 되어서 집에서 하는 것보다 생산성이 좋았기 때문에 처음 참석한 이래로 꾸준히 계속 가게 되었는데요, 사실 개인적으로 생각하는 가장 큰 이점은 바로 안전하게 작업을 할 수 있다는 것입니다. 이게 뭔 소리야..? 라는 생각이 드실텐데 한국과 달리 캐나다, 특히 여기 토론토에서는 카페를 혼자 간 다음에 가방을 두고 화장실을 가게 되면 도난 맞을 확률이 상당하다고 해서 가방도 같이 가지고 가야 한다고 합니다. 그래서 그 동안 사실 혼자 카페를 잘 못 가다가 이 모임에서는 그런 걱정없이 맘편히 화장실도 다녀올 수 있어서 너무 편했습니다..ㅎㅎ

coffee and code meetup

본론으로 들어가서, 최근에 JAMstack Toronto 라는 meetup이 새로 생겼는데 NetlifyGatsby의 개발자들이 와서 간단한 발표를 한다고 하더군요. 마침 gatsby로 현재 이 블로그를 만드는 작업(결국 디자인이 어떻게 해결이 안되서 이 블로그는 gatsby-starter-lumen를 통해 만들었습니다)을 하기 위해 관련 영상을 보던 중이라 주저없이 Going!

jamstack toronto meetup

JAMstack Toronto의 첫번째 meetup행사여서 그런지 PagerDuty라는 회사의 프레젠테이션을 할 수 있는 장비가 갖춰진 floor 하나를 전체 빌렸는데 엄청 넓은 건 아니었지만 꽤 괜찮았고 Netlify에서는 간단한 스티커랑 티셔츠!!를 가져와서 나눠주었는데, Netlify를 애정하는 1인으로서 개인적으로 티셔츠가 너무 마음에 들었습니다.ㅎㅎ

jamstack toronto place

netlify tshirts

행사 진행은 Netlify > Cloudinary > Gatsby 순으로 진행되었는데요, 사실 cloudinary는 처음 일정에는 없다가 갑작스럽게 추가되었는데, 아마 자사의 서비스 뿐만 아니라 MDE(Media Developer Experts) 프로그램을 홍보하기 위해서 참여한 것 같습니다.

Netlify에서는 Phil HawksworthGetting stuck in to JAMstack 이라는 주제로 발표를 진행하였는데 다른 발표들도 마찬가지였지만 주어진 시간이 그리 여유롭지 않아서 그런지 굉장히 빠른 호흡으로 진행되었습니다. 이 부분이 살짝 아쉽긴 했지만 그래도 JAMstack이란 무엇인지와 기존의 전통적인 stack과의 비교, 그리고 Netlify를 이용해서 얼마나 쉽고 빠르게 static한 웹사이트를 배포할 수 있는지를 간단하게 보여주면서 군더더기 없이 깔끔하게 설명해주었습니다.

phil hawksworth

중간에 쏟아지는 갑작스러운 질문들에도 차분하게 설명을 잘 해주던 Phil이 가장 당황했던 순간은 마지막에 Netlify의 CMS 툴을 보여주려고 접속하는데 사이트가 뜨지 않던 상황이었습니다. unpkg가 다운되었다고 누가 소리질렀는데 정말 밑에 Waiting for unpkg.com…인 상태로 계속 멈춰있는 상태였고 몇 번을 시도했으나 결국 야속하게도 unpkg는 우리에게 끝까지 Netlify CMS를 허락하지 않았습니다…

Cludinary의 세션은 애초에 예상치 못했던 일정이라 처음에 Kahoot을 통해 prize 게임을 진행하는 파트 이외에는 솔직히 집중해서 듣지는 않았습니다. 주로 Cloudinary 서비스를 써 본 사람이 맞출 수 있는 퀴즈를 통해 가장 점수를 많이 쌓은 사람에게 무려 urBeats 이어폰(잘 몰랐는 데 비싼 이어폰이라고..)을 prize로 주었습니다. 이후 발표는 Cloudinary의 CTO인 Colin BendellTimirah James가 각각 자사의 서비스를 이용한 asset management에 대한 소개와 Media Developer Experts 프로그램을 홍보하는 것으로 진행되었습니다.

colin and timirah

마지막으로 Gatsby는 Jason LengstorfLive Coding of Quick Gatsby site wih Netlify를 준비하였는데, 사실 이 포스트의 목적이 바로 여기서 Jason이 보여준 demo를 그대로 재연하기 위함이었습니다..! 정말 거의 10분도 채 안되는 짧은 시간 동안 아주 빠르게 The Rick and Morty API를 통해서 Rick이라는 이름을 가진 이미지들만 보여주는 사이트 하나를 뚝딱 만들어 내는데 정말 Gatsby와 Netlify의 강력한 콜라보 파워를 느낄 수 있는 세션이었습니다.

jason lengstorf

Warning: 지금부터 진행하는 demo는 철저하게 제 기억에 의존해서 기록하는 것이기 때문에 실제 진행된 demo와 일부 다른 부분이 있을수도 있습니다. 또한 gatsby, graphql 등에 대한 자세한 내용은 공식 홈페이지에서 보는 것이 정확하고 더 다양한 예제와 옵션들이 있기에 자세한 설명은 생략하고 demo 그 자체를 똑같이 재연하는 데에 집중했습니다.

먼저 간단하게 gatsby-demo라는 git 프로젝트를 생성합니다.

~/gatsby-demo
$ git init
$ git create

Jason이 사용한 덕분에 이번에 처음 알게 되었는데, hub이라는 서비스를 통해 github repository를 간단하게 cli로 생성이 가능하다는 것을 알았습니다. 기존에 이미 사용 중이 아닌 분들이라면 단순 설치 뿐만 아니라 사용 중인 환경에 따른 bash 설정 등 추가로 세팅해주어야 하는 부분들이 있으니 매끄러운 과정을 위해 현재 여기서는 github 사이트에서 GUI를 통해 생성하시는 것을 권장드립니다.

이렇게 생성한 프로젝트에서 yarn init을 통해 package.json을 생성한 후, react, react-dom 그리고 gatsby를 추가해줍니다.

$ yarn init
$ yarn add react react-dom gatsby

* npm 이던 yarn이던 본인이 선호하는 package manager를 쓰시면 됩니다. 저는 demo에서 yarn을 사용했기 때문에 그대로 yarn으로 가겠습니다.

이제 demo가 진행될 파일을 생성할 차례인데요, 실제 demo에선 IDE상에서 바로 파일을 생성해 주었습니다만, cli로 생성할 경우의 명령어는 아래와 같습니다.

$ mkdir src; cd src; mkdir pages; cd pages; touch index.js

생성된 index.js 파일에서 다음과 같은 작업을 해줍니다.

src/pages/index.js
import React from 'react';
import { graphql } from 'gatsby';

export const query = graphql`
  query {
    // graphql query!
  }
`;

const Index = () => <div>Hello Gatsby!</div>;

export default Index;

순서대로 보면, 일단 Gatsby가 react 기반 프레임워크이기 때문에 react를 불러와주고, graphql를 이용해서 api에서 원하는 data를 담을 query를 작성할 예정이기 때문에 마찬가지로 import합니다.

Gatsby에서 graphql query를 이용해 third-party graphql api에서 data를 가져오려면 어떻게 해야할까요? 답은 플러그인입니다. 사실 지금까지 공부하면서 개인적으로 느끼기에 gatsby는 플러그인이 다했다..! 라고 해도 과언이 아닐 정도로 플러그인의 활용도나 중요도가 정말 높습니다.

플러그인을 사용하기 위해선 해당 플러그인 패키지를 설치해주어야 하는데요, 여기서 필요한 플러그인은 gatsby-source-graphql로 third-party graphql api를 gatsby의 graphql에서 쓸 수 있게 해주는 기능을 제공합니다.

$ yarn add gatsby-source-graphql

설치한 플러그인 기능을 사용하기 위해 프로젝트 최상단 디렉토리에서 gatsby-config.js 파일을 만들고 아래와 같이 설정을 해줍니다.

gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: 'gatsby-source-graphql',
      options: {
        // This type will contain remote schema Query type
        typeName: 'RickAndMorty',
        // This is field under which it's accessible
        fieldName: 'rickAndMorty',
        // Url to query from
        url: 'https://rickandmortyapi.com/graphql',
      },
    },
  ],
};

설정이 끝났으면 이제 query만 작성하면 될 것 같은데.. 이 query를 작성하기 위한 field 값은 어떻게 알 수 있을까요? 방법은 크게 2가지가 있는데요, 일단 가장 먼저 설정에 넣어놓은 url, rick and morty에서 제공하는 graphql api를 통해 GraphiQL 이라는 인터페이스에 접근할 수 있습니다.

아래와 같이 schema를 확인할 수 있고 각각의 필드명과 타입이 상세하게 나와 있어 필요한 data를 확인하기가 매우 편리합니다.

rickandmorty graphql

뿐만 아니라 원하는 data의 필드값으로 query를 작성해서 화면의 재생 버튼? 처럼 보이는 것을 클릭하거나 cmd + Enter를 통해 직접 그 결과값을 바로 호출해서 확인할 수 있습니다. 여기서는 demo에서 진행한 대로 모든 캐릭터 중에 이름에 “Rick”이 포함되는 캐릭터들만 필터링해서 그 id와 name, image의 값을 가져오는 query를 작성했습니다.

rickandmorty graphql query

이제 작성된 query를 그대로 옮겨와서 아까 비워놓은 query를 채워줍니다.

src/pages/index.js
import React from 'react';
import { graphql } from 'gatsby';

export const query = graphql`
  query {    rickAndMorty {      characters(filter: { name: "Rick" }) {        results {          id          name          image        }      }    }  }`;

const Index = () => <div>Hello Gatsby!</div>;

export default Index;

앞서 query의 필드값을 확인하는 방법이 2가지가 있다고 했는데 나머지 하나가 바로 로컬서버에서 직접 확인하는 방법입니다.

터미널에서 gatsby develop 커맨드를 실행하면 아래와 같이 localhost:8000/___graphql로 접속해서 GraphiQL을 쓸 수 있다고 나옵니다.

gatsby prompt

브라우저에서 해당 url로 접속하면 아래와 같이 왼쪽 사이드의 explorer 탭에서 클릭 몇번으로 훨씬 더 편하게 query를 구성할 수 있고 이전에 https://rickandmortyapi.com/graphql에서와 마찬가지로 결과값을 바로 확인할 수 있습니다.

local graphiql screenshot

이미 어떤 구성으로 data를 받게 될 지 알고 있기 때문에 아래와 같이 Index 컴포넌트에서 원하는 형태로 data를 뿌려줍니다.

src/pages/index.js
import React from 'react';
import { graphql } from 'gatsby';

export const query = graphql`
  query {
    rickAndMorty {
      characters(filter: { name: "Rick" }) {
        results {
          id
          name
          image
        }
      }
    }
  }
`;

const Index = ({ data }) => (  <section>    {data.rickAndMorty.characters.results.map(rick => (      <figure key={rick.id}>        <img src={rick.image} alt={rick.name} />        <figcaption>{rick.name}</figcaption>      </figure>    ))}  </section>);
export default Index;

query의 결과값은 자동으로 같은 파일의 React 컴포넌트에 data prop으로 넘겨집니다. GraphQL과 Gatsby가 우리가 요청한 data를 즉시 쓸 수 있도록 아주 편리하게 이미 세팅을 다 해놓았기 때문이죠.

이때 localhost를 통해 출력되는 결과물을 확인해보면 별로 보기에 썩 좋지 않은 모습인데요, demo에서와 같이 css grid를 이용해서 간단히 수정해보겠습니다.

css grid generator

CSS Grid Generator를 통해 아주 간단하게 원하는 형태의 css grid 코드를 만들 수 있는데요, 아래와 같이 생성된 코드를 가지고 layout.css라는 파일을 만들어서 그대로 붙여넣겠습니다.

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr;
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

.image {
  margin: 0;
}

.image img {
  max-width: 100%;
}

생성된 css 코드에 class 이름만 살짝 수정해주고 이미지에도 조금 스타일을 변경해주었습니다. 이제 해당 class를 적용시켜주기만 하면 됩니다.

src/pages/index.js
const Index = ({ data }) => (
  <section className='grid'>    {data.rickAndMorty.characters.results.map(rick => (
      <figure key={rick.id} className='image'>        <img src={rick.image} alt={rick.name} />
        <figcaption>{rick.name}</figcaption>
      </figure>
    ))}
  </section>
);

짜잔! 드디어 우리가 원하던 대로 필터된 Rick의 이미지들만 그리드 형태로 화면에 뿌려지고 있는 걸 확인하실 수 있습니다!

rick and morty grid

실제 demo에서는 여기까지 하는데 5분도 채 안걸린 것 같은데요, 여기서 끝이 아니라 이제 Netlify를 통해 바로 배포시켜서 이 Rick들?을 세상에 내보낼 겁니다.

그 전에 간단하게 적용해 볼 수 있는 다른 플러그인을 하나 더 사용해 보도록 하겠습니다. 바로 gatsby-source-instagram 플러그인 입니다.

이름에서 알 수 있듯이 인스타그램과 관련된 뭔가를 하는 것 같은데… 그렇습니다! 이 플러그인을 쓰면 인스타그램의 유저프로필이나 해쉬태그 페이지, 게시물 등을 가져올 수 있습니다.

demo에서는 간단하게 해당 플러그인에서 제공하는 public scraping method를 통해 public account의 게시물을 가져오는 것을 구현했습니다.

먼저 플러그인을 설치해줍니다.

$ yarn add gatsby-source-instagram

public account의 posts를 가져오기 위해 gatsby-config.js 파일에서 아래와 같이 plugins 옵션에 설정을 추가해줍니다.

gatsby-config.js
plugins: [
  {
    resolve: 'gatsby-source-graphql',
    options: {
      // This type will contain remote schema Query type
      typeName: 'RickAndMorty',
      // This is field under which it's accessible
      fieldName: 'rickAndMorty',
      // Url to query from
      url: 'https://rickandmortyapi.com/graphql',
    },
  },
  {    resolve: `gatsby-source-instagram`,    options: {      username: 'rickandmorty',    },  },];

설정에서 보이는 것처럼 options의 username에서 대상 계정의 이름을 써주기만 하면 되는데요, 정말 간단하지 않나요? rickandmorty의 인스타그램 public account의 게시물을 가져오도록 설정해주었습니다.

그러면 이제 플러그인이 잘 설정되었는지 보기 위해 다시 localhost:8000/__graphql로 가서 확인을 해줍니다.

local graphiql instagram

allInstaNode 라는 필드가 추가된 부분이 보이시나요? 이전과 마찬가지로 간단하게 explorer에서 필요한 정보들만 콕콕 집어서 query를 구성합니다. 위에서 이미 만들어진 query를 기존에 사용하고 있던 query에 추가해주고 동시에 인스타그램 data를 보여줄 화면도 마찬가지로 css grid를 통해서 같이 구성해줍니다.

src/pages/index.js
import React from 'react';
import { graphql } from 'gatsby';

export const query = graphql`
  query {
    rickAndMorty {
      characters(filter: { name: "Rick" }) {
        results {
          id
          name
          image
        }
      }
    }
    allInstaNode {      nodes {        id        thumbnails {          src        }        caption      }    }  }
`;

const Index = ({ data }) => (
  <>
    <section>
      {data.rickAndMorty.characters.results.map(rick => (
        <figure key={rick.id}>
          <img src={rick.image} alt={rick.name} />
          <figcaption>{rick.name}</figcaption>
        </figure>
      ))}
    </section>
    <h2>More on Instragram</h2>    <section className='grid'>      {data.allInstaNode.nodes.map(insta => (        <figure key={insta.id} className='image'>          <img src={insta.thumbnails[1].src} alt={insta.caption} />          <figcaption>{insta.caption}</figcaption>        </figure>      ))}    </section>  </>
);

export default Index;

자 이제 localhost:8000에서 확인해보면 아래처럼 인스타그램 게시물 역시 잘 불러와진 것을 보실 수 있습니다!

rickandmorty instagram

마침내 대망의 Netlify와의 콜라보를 진행해볼 차례인데요, 먼저 알아두셔야할 점은 Netlify를 통해 사이트를 배포 및 호스팅하기 위해선 당연하게도? Netlify의 계정이 있어야 합니다.

Netlify에 처음 가입을 하시는 경우, github 연동을 통해 가입하시면 Netlify가 알아서 내 github 계정의 레포지토리 목록을 가져와서 거기서 배포하려는 프로젝트의 선택이 가능합니다.

그럼 Netlify를 통한 배포 이전에 여기서는 아까 초반에 만들어 놓은 gatsby-demo 레포지토리에 지금까지 작업한 결과물을 커밋 푸시를 먼저 진행하도록 하겠습니다.

git status를 통해 확인해보면 node_modules, .cache/, public/과 같이 github에 보내주면 안되는 녀석들이 눈에 띄는데요, 잊지말고 .gitignore 파일을 프로젝트 최상단 디렉토리에 생성해서 저 친구들을 무시해?줍시다.

git status screenshot

$ printf "node_modules\n.cache\npublic\n" >> .gitignore

.gitignore 파일을 열었을 때 아래와 같이 표시되면 위의 커맨드라인이 잘 실행되었다는 의미입니다.

.gitignore
node_modules
.cache
public

이제 변경사항들을 저장 및 커밋 후에 푸시를 하도록 하겠습니다.

$ git add .
$ git commit -am 'this is all demo files'
$ git push origin master

Jason이 I made a demo! 라는 커밋을 쓰면서 커밋 메세지 이렇게 작성하지 말라고 했었는데 여기서도 마찬가지입니다.. 저렇게 쓰지 마세요ㅋㅋㅋ

이번에는 진짜 Netlify에서 사이트를 업로드할 차례입니다!

…그런데 그전에 정말 딱 하나 더 해야할 일이 있는데요, 바로 build script를 작성해주는 일입니다! 사실 demo할 당시에도 이걸 깜빡해서 사이트가 처음에 제대로 안 떴었는데 저도 지금까지 까먹고 있었네요 하하

그럼 바로 package.json에 scripts에 build 커맨드 gatsby build를 추가해줍니다.

package.json
{
  "name": "gatsby-demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {    "build": "gatsby build"  },  "dependencies": {
    "gatsby": "^2.11.6",
    "gatsby-source-graphql": "^2.1.0",
    "gatsby-source-instagram": "^0.5.1",
    "react": "^16.8.6",
    "react-dom": "^16.8.6"
  }
}

기다리고 기다리던.. netlify로 갈 차례입니다. netlify에서 계정을 만드셨거나, 혹은 이미 계정이 있으시다면 sites 탭의 대시보드에서 아래와 같이 New site from Git이라는 버튼을 클릭해줍니다.

netlify new site button

첫번째 단계로 Git provider를 선택하는 옵션이 있는데 github repo에 올려놓았으니 고민없이 GitHub을 선택합니다.

connect git provider

그 다음엔 레포지토리를 고를 순서인데요, gatsby-demo를 선택하면 Netlify에서 github과의 인증과정을 진행하고 마지막 단계로 넘어갑니다.

netlify create new site

파이널 스텝은 Deploy setting과 main branch 설정입니다. build 커맨드를 설정해놓아서 자동으로 이미 해당 필드가 채워져 있는데요, 혹여나 저 부분이 비어있다고 해서 문제될 것은 하나도 없습니다! 직접 쓰면 되거든요 ㅎㅎ 그리고 지금 당장 설정하지 않더라도 이후에 언제든지 Deploy settings에서 수정할 수 있습니다.

netlify build command

이렇게 모든 설정을 마치고 Deploy site 버튼을 누르고 나면 바로 배포로그 화면으로 넘어가게 됩니다. 아래와 같이 Site is live 라는 메세지가 뜨고 나면 성공적으로 배포가 완료되서 Netlify에서 생성해준 요상한 이름의 사이트(물론 이 이름도 바꿀 수 있습니다!)로 접속해서 로컬 서버에서 보던 결과물이 똑같이 뜨는 것을 확인하실 수 있습니다.

deploy-log-monitor

netlify site dashboard
뭔가 충격적이었는지 이름에 shock..이 들어갔네요 ㅋㅋㅋ

netlify hosting site

References