자바스크립트 정적 사이트 생성 (SSG) 완전 정복! 🚀
안녕하세요, 여러분! 오늘은 정말 핫한 주제로 찾아왔어요. 바로 '자바스크립트 정적 사이트 생성(SSG)'에 대해 깊이 파헤쳐볼 거예요. 이 주제, 어렵게 들리시나요? 걱정 마세요! 제가 쉽고 재미있게 설명해드릴게요. 마치 친구와 카톡 채팅하듯이 편하게 읽어주세요. ㅋㅋㅋ
먼저, SSG가 뭔지 아시나요? 'Static Site Generation'의 약자로, 말 그대로 '정적 사이트를 생성한다'는 뜻이에요. 근데 이게 왜 중요하냐고요? 요즘 웹 개발 트렌드에서 SSG는 완전 핫해요! 속도 빠르고, 보안성 좋고, SEO(검색엔진 최적화)에도 강하거든요. 마치 웹 개발계의 '엄친아' 같은 존재랄까요? 😎
그럼 이제부터 SSG의 세계로 함께 떠나볼까요? 준비되셨나요? 자, 출발~! 🚗💨
SSG, 도대체 뭐길래? 🤔
SSG는 말 그대로 '정적 사이트'를 '생성'하는 거예요. 근데 여기서 '정적'이라는 게 무슨 뜻일까요? 쉽게 말해서, 변하지 않는 사이트를 말해요. 마치 책처럼요! 책은 한 번 인쇄되면 내용이 바뀌지 않잖아요? 그것처럼 SSG로 만든 사이트도 한 번 만들어지면 그 내용이 고정돼요.
반대로 '동적 사이트'는 뭘까요? 이건 실시간으로 변하는 사이트를 말해요. 예를 들어, 페이스북 같은 SNS 사이트는 계속해서 새로운 게시물이 올라오고 댓글이 달리죠? 이런 게 바로 동적 사이트예요.
SSG는 이 '정적'인 특성 때문에 몇 가지 큰 장점을 가지고 있어요:
- 🚀 빠른 로딩 속도: 미리 만들어진 페이지라 로딩이 엄청 빨라요!
- 🔒 높은 보안성: 서버와 데이터베이스 연결이 필요 없어서 해킹 위험이 줄어들어요.
- 🔍 SEO 친화적: 검색엔진이 사이트 내용을 쉽게 읽을 수 있어요.
- 💰 저렴한 호스팅 비용: 단순한 파일들이라 호스팅 비용이 적게 들어요.
이런 장점들 때문에 요즘 개발자들 사이에서 SSG가 대세로 떠오르고 있어요. 마치 '재능넷'처럼 다양한 재능을 가진 사람들이 모이는 것처럼, SSG도 여러 장점들이 모여 있는 거죠! 😉
💡 재능넷 TMI: 재능넷(https://www.jaenung.net)은 다양한 재능을 가진 사람들이 모여 서로의 능력을 공유하고 거래하는 플랫폼이에요. SSG처럼 여러 장점을 가진 사람들이 한데 모여 있죠!
자, 이제 SSG가 뭔지 대충 감이 오시나요? 그럼 이제 본격적으로 자바스크립트로 SSG를 어떻게 만드는지 알아볼까요? 준비되셨나요? Let's go! 🏃♂️💨
자바스크립트로 SSG 만들기: 기초부터 차근차근! 👨💻
자, 이제 본격적으로 자바스크립트로 SSG를 만들어볼 거예요. 걱정 마세요, 어렵지 않아요! 마치 레고 블록 쌓듯이 하나씩 차근차근 해볼게요.
1. 개발 환경 세팅하기 🛠️
먼저 개발 환경을 세팅해야 해요. Node.js가 설치되어 있다고 가정할게요. 없다면 Node.js 공식 사이트에서 다운받아 설치해주세요!
그 다음, 새 프로젝트 폴더를 만들고 그 안에서 터미널을 열어주세요. 그리고 다음 명령어를 입력해주세요:
npm init -y
npm install fs path marked
이렇게 하면 package.json 파일이 생성되고, 필요한 패키지들이 설치돼요. 'fs'는 파일 시스템을 다루는 Node.js의 내장 모듈이고, 'path'는 파일 경로를 다루는 모듈이에요. 'marked'는 마크다운을 HTML로 변환해주는 라이브러리예요.
2. 폴더 구조 만들기 📁
이제 다음과 같은 폴더 구조를 만들어볼게요:
my-ssg-project/
├── src/
│ ├── content/
│ │ └── (여기에 마크다운 파일들을 넣을 거예요)
│ └── templates/
│ └── (여기에 HTML 템플릿 파일을 넣을 거예요)
├── public/
│ └── (여기에 생성된 HTML 파일들이 저장될 거예요)
└── build.js (SSG 스크립트)
이 구조는 마치 재능넷에서 다양한 재능들이 체계적으로 분류되어 있는 것처럼, 우리의 SSG 프로젝트도 잘 정리된 구조를 가지게 될 거예요! 😊
3. HTML 템플릿 만들기 🖼️
src/templates 폴더에 template.html 파일을 만들고 다음과 같이 작성해주세요:
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
</head>
<body>
<header>
<h1>{{title}}</h1>
</header>
<main>
{{content}}
</main>
<footer>
<p>© 2023 My SSG Blog</p>
</footer>
</body>
</html>
여기서 {{title}}과 {{content}}는 나중에 실제 내용으로 대체될 거예요.
4. 마크다운 컨텐츠 만들기 ✍️
src/content 폴더에 마크다운 파일들을 만들어주세요. 예를 들어, hello-world.md 파일을 다음과 같이 작성할 수 있어요:
---
title: Hello, SSG World!
---
# 안녕하세요, SSG 세계에 오신 것을 환영합니다!
이것은 제 첫 번째 SSG 블로그 포스트입니다.
자바스크립트로 SSG를 만드는 건 정말 재미있어요!
파일 상단의 --- 사이에 있는 부분을 'frontmatter'라고 해요. 여기에 제목이나 날짜 같은 메타데이터를 넣을 수 있어요.
5. SSG 스크립트 작성하기 🖥️
이제 진짜 중요한 부분이에요! build.js 파일을 만들고 다음과 같이 작성해주세요:
const fs = require('fs');
const path = require('path');
const marked = require('marked');
const sourceDir = './src/content';
const templatePath = './src/templates/template.html';
const outputDir = './public';
// 템플릿 읽기
const template = fs.readFileSync(templatePath, 'utf-8');
// 출력 디렉토리 생성
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir);
}
// 마크다운 파일 처리
fs.readdirSync(sourceDir).forEach(file => {
if (path.extname(file) === '.md') {
const filePath = path.join(sourceDir, file);
const content = fs.readFileSync(filePath, 'utf-8');
// frontmatter 파싱
const [, frontmatter, markdown] = content.split('---');
const metadata = {};
frontmatter.split('\n').forEach(line => {
const [key, value] = line.split(':');
if (key && value) {
metadata[key.trim()] = value.trim();
}
});
// 마크다운을 HTML로 변환
const htmlContent = marked(markdown);
// 템플릿에 내용 삽입
let html = template.replace('{{title}}', metadata.title || 'Untitled')
.replace('{{content}}', htmlContent);
// HTML 파일 저장
const outputPath = path.join(outputDir, `${path.parse(file).name}.html`);
fs.writeFileSync(outputPath, html);
console.log(`Generated: ${outputPath}`);
}
});
console.log('Static site generation complete!');
우와, 좀 길죠? 하지만 걱정 마세요. 하나씩 설명해드릴게요!
- 필요한 모듈들을 불러와요.
- 소스 디렉토리, 템플릿 경로, 출력 디렉토리를 지정해요.
- HTML 템플릿을 읽어와요.
- 출력 디렉토리가 없으면 만들어요.
- 소스 디렉토리의 모든 마크다운 파일을 처리해요:
- 파일 내용을 읽어와요.
- frontmatter를 파싱해서 메타데이터를 추출해요.
- 마크다운을 HTML로 변환해요.
- 템플릿에 제목과 내용을 삽입해요.
- 생성된 HTML을 파일로 저장해요.
이 스크립트는 마치 재능넷에서 다양한 재능을 가진 사람들이 모여 하나의 멋진 프로젝트를 완성하는 것처럼, 여러 단계를 거쳐 최종적으로 정적 사이트를 생성해내는 거예요! 😄
6. SSG 실행하기 🏃♂️
자, 이제 모든 준비가 끝났어요! 터미널에서 다음 명령어를 실행해보세요:
node build.js
짜잔~ 🎉 public 폴더에 HTML 파일들이 생성되었을 거예요. 브라우저에서 이 파일들을 열어보면 여러분의 첫 SSG 사이트를 볼 수 있어요!
축하드려요! 여러분은 방금 자바스크립트로 간단한 SSG를 만들었어요. 이제 여러분도 SSG 마스터의 길에 한 발짝 다가섰네요!
다음 섹션에서는 이 기본적인 SSG를 어떻게 발전시킬 수 있는지 알아볼 거예요. 계속 따라와주세요! 💪
SSG 업그레이드하기: 더 멋진 기능들! 🚀
자, 이제 기본적인 SSG를 만들어봤으니 좀 더 고급 기능들을 추가해볼까요? 마치 재능넷에서 기본 재능에 새로운 스킬을 추가하는 것처럼요! 😉
1. 코드 하이라이팅 추가하기 🌈
블로그에 코드를 예쁘게 표시하고 싶다면 코드 하이라이팅을 추가할 수 있어요. 'highlight.js' 라이브러리를 사용해볼게요.
먼저, 필요한 패키지를 설치해주세요:
npm install highlight.js
그리고 build.js 파일을 다음과 같이 수정해주세요:
const fs = require('fs');
const path = require('path');
const marked = require('marked');
const hljs = require('highlight.js');
// ... (이전 코드는 그대로 유지)
// marked 설정 추가
marked.setOptions({
highlight: function(code, lang) {
if (lang && hljs.getLanguage(lang)) {
return hljs.highlight(lang, code).value;
} else {
return hljs.highlightAuto(code).value;
}
}
});
// ... (이후 코드는 그대로 유지)
그리고 template.html 파일의 <head> 섹션에 highlight.js CSS를 추가해주세요:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/default.min.css">
이제 마크다운 파일에 코드 블록을 추가하면 예쁘게 하이라이팅 될 거예요! 👨💻
2. 목차(Table of Contents) 자동 생성하기 📑
긴 글에는 목차가 있으면 좋겠죠? marked 라이브러리의 렌더러를 커스터마이징해서 목차를 자동으로 생성해볼게요.
build.js 파일에 다음 코드를 추가해주세요:
const renderer = new marked.Renderer();
const toc = [];
renderer.heading = function(text, level) {
const slug = text.toLowerCase().replace(/[^\w]+/g, '-');
toc.push({
level: level,
slug: slug,
title: text
});
return `<h${level} id="${slug}">${text}</h${level}>`;
};
marked.setOptions({ renderer });
// ... (마크다운 처리 부분에서)
const htmlContent = marked(markdown);
// 목차 HTML 생성
let tocHtml = '<ul>';
toc.forEach(item => {
tocHtml += `<li style="margin-left: ${(item.level - 1) * 20}px"><a href="#${item.slug}">${item.title}</a></li>`;
});
tocHtml += '</ul>';
// 템플릿에 목차와 내용 삽입
let html = template.replace('{{title}}', metadata.title || 'Untitled')
.replace('{{toc}}', tocHtml)
.replace('{{content}}', htmlContent);
그리고 template.html 파일에 {{toc}} 플레이스홀더를 추가해주세요:
<body>
<header>
<h1>{{title}}</h1>
</header>
<nav>
<h2>목차</h2>
{{toc}}
</nav>
<main>
{{content}}
</main>
...
</body>
이제 각 페이지에 자동으로 목차가 생성될 거예요! 😎
3. 태그 시스템 추가하기 🏷️
블로그 포스트에 태그를 추가하고 싶다면 어떻게 해야 할까요? frontmatter에 태그를 추가하고, 이를 처리하는 로직을 만들어볼게요.
먼저, 마크다운 파일의 frontmatter에 태그를 추가해주세요:
---
title: Hello, SSG World!
tags: SSG, JavaScript, Web Development
---
# 안녕하세요, SSG 세계에 오신 것을 환영합니다!
...
그리고 build.js 파일에 태그를 처리하는 로직을 추가해주세요:
// ... (이전 코드는 그대로 유지)
// 전역 태그 맵 추가
const tagMap = new Map();
// 마크다운 파일 처리 부분에서
const tags = metadata.tags ? metadata.tags.split(',').map(tag => tag.trim()) : [];
tags.forEach(tag => {
if (!tagMap.has(tag)) {
tagMap.set(tag, []);
}
tagMap.get(tag).push({
title: metadata.title,
file: path.parse(file).name + '.html'
});
});
// 태그 HTML 생성
const tagHtml = tags.map(tag => `<a href="/tags/${tag}.html" style="margin-right: 10px;">#${tag}</a>`).join('');
// 템플릿에 태그 삽입
let html = template.replace('{{title}}', metadata.title || 'Untitled')
.replace('{{tags}}', tagHtml)
.replace('{{toc}}', tocHtml)
.replace('{{content}}', htmlContent);
// ... (이후 코드는 그대로 유지)
// 모든 마크다운 파일 처리 후
tagMap.forEach((posts, tag) => {
let tagContent = `<h1>Tag: ${tag}</h1><ul>`;
posts.forEach(post => {
tagContent += `<li><a href="/${post.file}">${post.title}</a></li>`;
});
tagContent += '</ul>';
const tagHtml = template.replace('{{title}}', `Tag: ${tag}`)
.replace('{{content}}', tagContent);
const tagPath = path.join(outputDir, 'tags', `${tag}.html`);
fs.mkdirSync(path.dirname(tagPath), { recursive: true });
fs.writeFileSync(tagPath, tagHtml);
console.log(`Generated tag page: ${tagPath}`);
});
마지막으로 template.html 파일에 {{tags}} 플레이스홀더를 추가해주세요:
<header>
<h1>{{title}}</h1>
<div>{{tags}}</div>
</header>
이제 각 포스트에 태그가 표시되고, 태그별 페이지도 생성될 거예요! 👏
4. RSS 피드 생성하기 📡
블로그 구독자들을 위해 RSS 피드를 제공하면 어떨까요? 'feed' 라이브러리를 사용해서 RSS 피드를 생성해볼게요.
먼저, 필요한 패키지를 설치해주세요:
npm install feed
그리고 build.js 파일에 다음 코드를 추가해주세요:
const { Feed } = require('feed');
// ... (이전 코드는 그대로 유지)
// Feed 객체 생성
const feed = new Feed({
title: "My SSG Blog",
description: "This is my SSG blog",
id: "http://example.com/",
link: "http://example.com/",
language: "ko",
image: "http://example.com/image.png",
favicon: "http://example.com/favicon.ico",
copyright: "All rights reserved 2023, John Doe",
updated: new Date(),
generator: "My Awesome SSG",
feedLinks: {
json: "http://example.com/json",
atom: "http://example.com/atom"
},
author: {
name: "John Doe",
email: "johndoe@example.com",
link: "https://example.com/johndoe"
}
});
// 마크다운 파일 처리 부분에서
feed.addItem({
title: metadata.title,
id: `http://example.com/${path.parse(file).name}.html`,
link: `http://example.com/${path.parse(file).name}.html`,
description: metadata.description,
content: htmlContent,
author: [
{
name: "John Doe",
email: "johndoe@example.com",
link: "https://example.com/johndoe"
}
],
date: new Date(metadata.date),
image: metadata.image
});
// ... (이후 코드는 그대로 유지)
// 모든 마크다운 파일 처리 후
fs.writeFileSync(path.join(outputDir, 'rss.xml'), feed.rss2());
fs.writeFileSync(path.join(outputDir, 'atom.xml'), feed.atom1());
fs.writeFileSync(path.join(outputDir, 'feed.json'), feed.json1());
console.log('Generated RSS feeds');
이제 rss.xml, atom.xml, feed.json 파일이 생성될 거예요. 이 파일들의 링크를 블로그 템플릿에 추가해주면 됩니다! 🎉
와우! 이제 우리의 SSG가 훨씬 더 강력해졌어요. 코드 하이라이팅, 목차, 태그 시스템, RSS 피드까지 갖춘 멋진 블로그를 만들 수 있게 되었죠.
이런 식으로 계속해서 새로운 기능들을 추가할 수 있어요. 마치 재능넷에서 다양한 재능을 가진 사람들이 모여 더 큰 가치를 만들어내는 것처럼, 우리도 SSG에 다양한 기능을 추가해 더 멋진 사이트를 만들 수 있답니다! 😊
다음 섹션에서는 이 SSG를 실제로 배포하는 방법에 대해 알아볼게요. 기대되지 않나요? 계속 따라와주세요! 🚀
SSG 사이트 배포하기: 세상에 선보이자! 🌍
자, 이제 우리의 멋진 SSG 사이트를 만들었으니 세상에 선보일 차례예요! 어떻게 하면 될까요? 여러 가지 방법이 있지만, 오늘은 가장 간단하고 무료인 방법을 소개해드릴게요. 바로 GitHub Pages를 이용한 배포예요! 😎
1. GitHub 레포지토리 만들기 📁
- GitHub에 로그인하 고 새 레포지토리를 만들어주세요. 이름은 원하는 대로 지어도 되지만, 'username.github.io'로 만들면 특별한 GitHub Pages 주소를 사용할 수 있어요.
- 로컬 프로젝트를 이 레포지토리에 연결해주세요.
2. .gitignore 파일 만들기 🙈
프로젝트 루트 디렉토리에 .gitignore 파일을 만들고 다음 내용을 추가해주세요:
node_modules/
.DS_Store
*.log
이렇게 하면 불필요한 파일들이 GitHub에 올라가는 것을 방지할 수 있어요.
3. package.json 스크립트 추가하기 📝
package.json 파일을 열고 "scripts" 부분에 다음 내용을 추가해주세요:
"scripts": {
"build": "node build.js",
"deploy": "npm run build && gh-pages -d public"
}
이 스크립트들은 사이트를 빌드하고 배포하는 데 사용될 거예요.
4. gh-pages 패키지 설치하기 📦
터미널에서 다음 명령어를 실행해주세요:
npm install gh-pages --save-dev
이 패키지는 GitHub Pages에 쉽게 배포할 수 있게 도와줄 거예요.
5. 사이트 빌드하고 배포하기 🚀
이제 모든 준비가 끝났어요! 터미널에서 다음 명령어를 실행해주세요:
npm run deploy
이 명령어는 사이트를 빌드하고 GitHub Pages에 배포할 거예요. 잠시 기다리면... 짜잔! 🎉 여러분의 사이트가 온라인에 올라갔어요!
6. GitHub Pages 설정하기 ⚙️
- GitHub 레포지토리 페이지로 가서 'Settings' 탭을 클릭하세요.
- 'Pages' 섹션으로 스크롤해서 내려가세요.
- 'Source' 드롭다운에서 'gh-pages' 브랜치를 선택하세요.
- 'Save' 버튼을 클릭하세요.
이제 여러분의 사이트는 'https://username.github.io' 또는 'https://username.github.io/repository-name'에서 볼 수 있어요!
7. 커스텀 도메인 설정하기 (선택사항) 🌐
만약 자신만의 도메인을 사용하고 싶다면:
- 도메인 제공업체에서 도메인을 구입하세요.
- GitHub 레포지토리의 'Settings' > 'Pages' 섹션에서 'Custom domain' 필드에 여러분의 도메인을 입력하세요.
- 도메인 제공업체의 DNS 설정에서 GitHub Pages IP 주소로 A 레코드를 추가하세요.
- 변경사항이 적용되기까지 최대 24시간 정도 기다려야 할 수도 있어요.
축하드려요! 🎊 이제 여러분의 SSG 사이트가 전 세계에 공개되었어요. 마치 재능넷에서 여러분의 재능을 세상에 선보이는 것처럼, 여러분의 SSG 사이트도 이제 전 세계 사람들이 볼 수 있게 되었죠!
추가 팁: 자동 배포 설정하기 🤖
매번 수동으로 배포하는 게 귀찮다면, GitHub Actions를 사용해 자동 배포를 설정할 수 있어요. 프로젝트 루트에 .github/workflows/deploy.yml 파일을 만들고 다음 내용을 추가해주세요:
name: Deploy to GitHub Pages
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '14'
- run: npm ci
- run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./public
이렇게 하면 main 브랜치에 push할 때마다 자동으로 사이트가 빌드되고 배포돼요. 완전 편리하죠? 😉
자, 이제 여러분은 자바스크립트로 SSG를 만들고, 기능을 추가하고, 배포까지 하는 방법을 모두 배웠어요. 이제 여러분만의 멋진 블로그나 포트폴리오 사이트를 만들 수 있겠죠?
SSG의 세계는 정말 넓고 깊어요. 여기서 배운 것을 기반으로 계속해서 새로운 것을 배우고 시도해보세요. 마치 재능넷에서 계속해서 새로운 재능을 개발하고 공유하는 것처럼요! 🚀
여러분의 SSG 여정이 즐겁고 보람찼으면 좋겠어요. 언제든 질문이 있다면 물어보세요. 화이팅! 💪😄