Hello! JAMstack!
김태희
목차
- JAMstack이란 무엇인가
- 적용경험
- Headless CMS
JAMstack?
대충_잼이_쌓여있는_사진.png
JAMstack?
대충_잼이_쌓여있는_사진.png
JAMstack
-
JavaScript
JAMstack
-
JavaScript
-
APIs
JAMstack
-
JavaScript
-
APIs
-
Markup
-
JavaScript
-
APIs
-
Markup
Fast and secure sites and apps delivered by pre-rendering files and serving them directly from a CDN, removing the requirement to manage or run web servers.
쉽게 말해서
- 별도의 웹서버를 통해 컨텐츠를 동적으로 렌더링하는 게 아니라
쉽게 말해서
- 별도의 웹서버를 통해 컨텐츠를 동적으로 렌더링하는 게 아니라
- 데이터에 따라 대응하는 컨텐츠 페이지를 정적으로 렌더링
쉽게 말해서
- 별도의 웹서버를 통해 컨텐츠를 동적으로 렌더링하는 게 아니라
- 데이터에 따라 대응하는 컨텐츠 페이지를 정적으로 렌더링
- 렌더링 된 결과물(HTML, JS, CSS)을 Static hosting을 통해 서비스
- server side의 CMS를 통해 제공되는 사이트
WordPress, Drupal, Joomla 등
JAMstack이 아닌 것
- server side의 CMS를 통해 제공되는 사이트
WordPress, Drupal, Joomla 등 - 특정 backend 언어 기반의 웹 서버 앱이 있고,
해당 앱을 통해 사이트를 받는 경우
JAMstack이 아닌 것
- server side의 CMS를 통해 제공되는 사이트
WordPress, Drupal, Joomla 등 - 특정 backend 언어 기반의 웹 서버 앱이 있고,
해당 앱을 통해 사이트를 받는 경우 - SPA앱이지만 rendering 되는 시점에 서버를
거쳐서 추가적인 렌더링을 하는 경우
예를 들면 odc-frontend(aws lambda edge 사용)
JAMstack이 아닌 것
JAMstack의 장점
- pre-render된 HTML을 static hosting을 통해
서빙 받기 때문에 배포가 매우 간편하고 성능에도 큰 잇점이 있음
JAMstack의 장점
- pre-render된 HTML을 static hosting을 통해
서빙 받기 때문에 배포가 매우 간편하고 성능에도 큰 잇점이 있음 - 이미 pre-render된 컨텐츠이기 때문에 SSR의 장점을 누릴 수 있음
- 컨텐츠 페이지별 meta tag 생성
- 빠른 초기 렌더링
JAMstack의 장점
- pre-render된 HTML을 static hosting을 통해
서빙 받기 때문에 배포가 매우 간편하고 성능에도 큰 잇점이 있음 - 이미 pre-render된 컨텐츠이기 때문에 SSR의 장점을 누릴 수 있음
- 컨텐츠 페이지별 meta tag 생성
- 빠른 초기 렌더링
- Scaling의 용이성
- 트래픽이 몰린다고 서버를 증설할 필요 없음
호스팅 서비스가 알아서 해줄꺼야
- 트래픽이 몰린다고 서버를 증설할 필요 없음
Tools
....and many more
실제로 좀 써본 것
실제로 좀 써본 것
실제로 좀 써본 것
gatsby의 아키텍쳐
- 데이터를 markdown, yaml, json 등의 정적인 파일로 표현
- 외부 API를 통해 데이터를 표현
- HTML/CSS/React를 이용해
컨텐츠를 pre-rendering - graphql을 통해 데이터 소스에서
데이터를 불러옴
- 데이터를 markdown, yaml, json 등의 정적인 파일로 표현
- 외부 API를 통해 데이터를 표현
- pre-rendering의 결과를
Static hosting service에 배포
- 데이터를 markdown, yaml, json 등의 정적인 파일로 표현
- 외부 API를 통해 데이터를 표현
- HTML/CSS/React를 이용해
컨텐츠를 pre-rendering - graphql을 통해 데이터 소스에서
데이터를 불러옴
저는 이걸로
밴드 홈페이지를 만들었어요.
멜론에서 이디어츠를 검색하세요
gatsby에 대한 간략한 소개
Routing 방식
/contact
/discography
/
/live
/movies
/photos
src/pages 아래에 있는 컴포넌트의
확장자를 제외한 파일명이 url이 됩니다.
md 파일 + yaml을 이용한 컨텐츠 표현
Text
...
{
resolve: `gatsby-source-filesystem`,
options: {
name: 'src',
path: `${__dirname}/src/`,
},
},
'gatsby-transformer-remark',
...
md 파일을 데이터로 사용하는 법
- gatsby-source-filesystem: path 아래에 있는 파일들을 읽어와 graphql로 조회할 수 있도록 만들어줌
- gatsby-transformer-remark: md 파일을 파싱
---
type: 'live'
title: '2020 PUNK Marathon'
posterUrl: ''
posterUrls:
[
{
src: '/images/posters/2020-02/82191077_479553396078214_6170799798740844544_o.jpg',
alt: '2020 펑크마라톤 공식 포스터',
width: 680,
height: 960,
},
{
src: '/images/posters/2020-02/goinmul.jpg',
alt: '2020 펑크마라톤 포스터',
width: 1926,
height: 1926,
},
]
place: '고인물'
date: '2020.02.22'
teams: ['링고포레스트', '노앤써', '오버헤드', '코인클래식']
priceInfos:
[
'예매 5일권: 50,000원 (full pass) (50% 할인) + 1일권 게스트 티켓 2매 증정',
'예매 4일권: 45,000원 (4-day pass)(44% 할인) + 1일권 게스트 티켓 1매 증정',
'예매 3일권: 35,000원 (3-day pass)(42% 할인)',
'예매 2일권: 25,000원 (2-day pass)(37% 할인)',
'예매 1일권: 15,000원 (1-day pass)(25% 할인)',
'당일 현매: 20,000원',
]
eventLink: 'https://www.facebook.com/hippytokki/posts/479149026118651'
ticketLink: 'https://docs.google.com/forms/d/e/1FAIpQLSeh6-iz-uWGq2LB8uvcSG6Wtm4QAAuBTmWy4hSU-WKa19Bd9w/viewform?vc=0&c=0&w=1&fbclid=IwAR0ajB3k7KoW-QwAzET_UBUEPWIBONWar7ZN1DdCOFecboytpY3fY2bMqfw'
---
test
src/pages/live/2020-punk-marathon.md
md 파일 path를 url으로 사용합니다.
/live/2020-punk-marathon/
graphql로 markdown 조회하기
{
allMarkdownRemark(
filter: { frontmatter: { type: { eq: "live" } } }
sort: { fields: [frontmatter___date], order: DESC }
) {
edges {
node {
id
frontmatter {
date
title
}
fields {
slug
}
}
}
}
}
graphql로 markdown 조회하기
{
"data": {
"allMarkdownRemark": {
"edges": [
{
"node": {
"id": "9cf14b80-b26a-5a37-a280-5e2881fb8b00",
"frontmatter": {
"date": "2020.2.22",
"title": "2020 PUNK Marathon"
},
"fields": {
"slug": "/live/2020-punk-marathon/"
}
}
},
{
"node": {
"id": "b7d7fd44-9f6b-5941-adf2-d1739e2df65a",
"frontmatter": {
"date": "2020.01.09",
"title": "오롯한 라이브와 함께"
},
"fields": {
"slug": "/live/o-rot-han-live/"
}
}
},
{
"node": {
"id": "35a154ac-53b2-5cf5-b74a-c505da1e06c0",
"frontmatter": {
"date": "2019.12.12",
"title": "LIVE in DEC 2019"
},
"fields": {
"slug": "/live/live-in-dec-2019/"
}
}
},
{
"node": {
"id": "aaadce5a-9584-51f2-95ef-389166a62bc3",
"frontmatter": {
"date": "2019.11.28",
"title": "LIVE in NOV 2019"
},
"fields": {
"slug": "/live/live-in-nov-2019/"
}
}
},
{
"node": {
"id": "3117ad79-83d6-53dd-bf05-01d4e0d65ced",
"frontmatter": {
"date": "2019.1.29",
"title": "이디어츠 1st EP 발매기념 공연"
},
"fields": {
"slug": "/live/idiots-1st-ep/"
}
}
}
]
}
}
}
live md 파일로 공연 페이지 빌드하기
// gatsby-node.js
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
}
// graphql로 type이 live인 md 파일만 가져옴
// slug는 src를 기준으로 폴더명과 파일명
const result = await graphql(`
{
allMarkdownRemark(filter: {frontmatter: {type: {eq: "live"}}}) {
edges {
node {
fields {
slug
}
}
}
}
}`)
// 위에서 가져온 md 파일로 slug에 해당하는 파잉 생성
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve('./src/components/LiveDetail.tsx'),
context: {
slug: node.fields.slug,
},
})
console.log(`${node.fields.slug} created,`)
})
}
빌드 결과
gatsby-node.js 에서 createPage한 페이지들이
pre-rendering 되고, slug 경로에 맞게
pre-rendering 된 결과물이 index.html로 생성
/live/2020-03-20-for-the-new-kids/
/live/2020-03-bbang/
/live/idiots-1st-ep/
createPage로 정의하지 않은 모든 url
배포하기
생성된 static resources만 배포하면 끝!
...and many more
static hosting만 필요하기 때문에,
별도로 관리해야하는 웹서버가 필요🙅♂️
- github repository가 변경되면 알아서
npm run build 해주고 빌드된 파일들 hosting 해줌 - repo 연동 후 content md 파일을 추가하거나 수정하고 commit + push하면 자동으로 빌드해서 배포까지 끝남
- 클릭 몇번으로 배포가 끝나는 신세계를 경험할 수 있습니다.
- pr이나 branch 별로 preview 서버를 띄워주는 기능
- front-end가 완전히 독립적이기 때문에 쉽게 가능
그외 자세한 내용은
outsider님의 블로그 https://blog.outsider.ne.kr/1426 를 참고하시면 됩니다.
빌드된 결과물 한번 볼까요?
SPA에서 단골로 등장하는 meta 태그 생성 문제를
pre-render로 해결가능합니다.
pre-render된 html이기 때문에 렌더링 속도가 정말 빠릅니다.
SSR 신경 안 써도 됩니다!
그외에도 많은 장점이 있습니다.
그런데 말입니다...
공연섭외 잘 안 될 땐
md 파일 만들고
커밋하는 거 할만했는데
공연이 점점 자주 잡히니까
상당히 귀찮아지더라구요..
그래서 CMS를 만들까 했습니다.
제가 어드민은 기깔나게 만들거든요.
그러다 알게 된 Headless CMS
Headless CMS
- 컨텐츠를 관리하는 어드민만 있고, 해당 컨텐츠를 노출하는 Front-end가 없는 것
- 쉽게 말해서 컨텐츠 관리기능만 있는 툴
사실 headless cms를 안 쓰고
wordpress 등에서 cms 기능만 써도
되긴 합니다.
Headless CMS
...and many more
요 친구를 써봤습니다.
트위터 친구분이 추천해주심
- 잘 만들어진 어드민 화면
- 데이터 모델링을 코드 수정 없이 가능함
- 모델 정의만 하면 해당 모델의 REST API 생성됨
- graphql 연동 쉬움
- 클릭 한번으로 끝남
- gatsby 연동 쉬움
- 플러그인 설치로 끝남
- 다양한 DB 지원
strapi로 공연 정보 받기
REST API 형태
strapi로 공연 정보 받기
graphql 형태
gatsby와 연동하기
// gatsby-config.js
...
{
resolve: 'gatsby-source-strapi',
options: {
apiURL: 'https://admin.idiots.band',
contentTypes: [
// List of the Content Types you want to be able to request from Gatsby.
'albums',
'lives',
'home-content',
],
queryLimit: 1000,
},
},
...
자동으로 gatsby의 graphql에 통합됨
webhook 연동
- 컨텐츠에 변경이 있는 경우 호출
- 해당 url이 호출되면, netlify build + deploy
아직 보완해봐야 하는 것
개별 빌드 및 배포
- 지금은 컨텐츠가 변경될 때마다 전체를 빌드하고 생성하고
배포해야 하는 구조 - 변경된 컨텐츠만 pre-rendering을 다시 하고, 해당 결과만
배포할 수 있도록 하는 것을 테스트 해볼 예정