$ npm i -D vercel
vercel.json
{}
export default async function (req, res) {
res.status(200).json({
name: '0seo'
})
}
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"vercel": "vercel dev"
},
"netlify": "netlify dev"
라고 되어 있던 부분을 지우고 "vercel": "vercel dev"
를 작성해줍니다.$ npm run vercel
버셀의 내 계정에 아래와 같이 생겼는지 확인을 합니다.
http://localhost:3000로 접근하면 아래와 같이 뜹니다.
import { VercelRequest, VercelResponse } from '@vercel/node'
export default async function (req, res) {
res.status(200).json({
name: '0seo'
})
}
import { VercelRequest, VercelResponse } from '@vercel/node'
를 가져와야합니다. vite.config.ts
server: {
proxy: {
'/api' : {target: 'http://localhost:2999'}
}
},
package.json
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"vercel": "vercel dev --listen 2999" //✅
},
async function request(options: RequestOptions) {
const { id = '', method, body } = options
const res = await fetch('/api/workspaces', { //✅
method: 'POST',
body: JSON.stringify({
id,
method,
data: body
})
})
return res.json()
}
주소를 api/workspaces로 바꿔줍니다.
import axios from 'axios'
import { VercelRequest, VercelResponse } from '@vercel/node'
const { APIKEY, USERNAME } = process.env
export default async function handler(request: VercelRequest, response: VercelResponse) {
const { id, method, data } = JSON.parse(request.body as string)
const { data: returnValue } = await axios({
url: `https://asia-northeast3-heropy-api.cloudfunctions.net/api/notion/workspaces/${id}`,
method,
headers: {
'content-type': 'application/json',
'apikey': APIKEY as string,
'username': USERNAME as string
},
data
})
response
.status(200)
.json(returnValue)
}
APIKEY=FcKdtJs202204
USERNAME=ParkYoungWoong
//hosting
npm run dev
//추가
npm run vercel
이렇게 터미널 두개를 통해 두개를 동시에 돌려야 3000번 서버가 2999서버를 가로채서 쓸 수가 있습니다.
두개 명령을 동시에 돌리는 것은 불편하기 때문에 한번에 띄울 수 있도록 수정해보도록 하겠습니다.
$ npm i -D concurrently
package.json
"scripts": {
"dev": "concurrently npm:watch-*",
"watch-dev": "vite",
"watch-vercel": "vercel dev --listen 2999",
}
concurrently패키지가 watch가 붙어있는 dev와 vercel을 동시에 돌립니다. 꼭 watch가 아니라 원하는 이름으로 해도 괜찮습니다.
현재의 저장소를 버셀에 바로 올릴 수도 있지만, 이런 경우 프로젝트가 날아가는 순간 날아가버리기 떄문에 원격저장소에 올린후 배포를 해보도록 하겠습니다.
$ rm -rf .git
$ git init
$ git add *
$ git commit -m ""
$ 원격저장소 연결
...
$ npm run vercel:depoly
api폴더 내에 edge.ts파일을 만들어줍니다.
import axios from 'axios'
import isbot from 'isbot'
import { VercelRequest, VercelResponse } from '@vercel/node' //1. 타입을 가져옵니다.
// Check .env file!
const { APIKEY, USERNAME, MODE } = process.env
export default async function handler(request: VercelRequest, response: VercelResponse) {
const userAgent = request.headers['user-agent'] //2. ✅
const id = (request.url as string).split('/').filter(p => p).reverse()[0].split('?')[0]
let data = {
title: 'Heropy가 운영하는 노션',
content: '안녕하세요! 반갑습니다! Heropy가 운영하는 노션 클론 예제입니다!',
poster: 'https://heropy.blog/css/images/logo.png'
}
if (isbot(userAgent) && id) {
console.log('Bot!!')
const res = await axios({
url: `https://asia-northeast3-heropy-api.cloudfunctions.net/api/notion/workspaces/${id}`,
method: 'GET',
headers: {
'content-type': 'application/json',
'apikey': APIKEY as string,
'username': USERNAME as string
}
})
data = res.data
}
const { title, content, poster } = data
response
.setHeader('content-type', 'text/html')
.status(200)
.send(/* html */ `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Heropy's Notion</title>
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Notion Clone!" />
<meta property="og:title" content="${title}" />
<meta property="og:description" content="${content}" />
<meta property="og:image" content="${poster}" />
<meta property="og:url" content="https://notion-vite-vue3-ts.vercel.app/workspaces/${id}" />
<meta property="twitter:card" content="summary" />
<meta property="twitter:site" content="Notion Clone!" />
<meta property="twitter:title" content="${title}" />
<meta property="twitter:description" content="${content}" />
<meta property="twitter:image" content="${poster}" />
<meta property="twitter:url" content="https://notion-vite-vue3-ts.vercel.app/workspaces/${id}" />
<link rel="icon" href="https://heropy.blog/css/images/logo.png">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reset-css@5.0.1/reset.min.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
${
MODE === 'development'
? '<script defer type="module" src="/src/main.ts"></script>'
: '<script type="module" crossorigin src="/assets/index.js"></script><link rel="stylesheet" href="/assets/index.css">'
}
</head>
<body>
<div id="app"></div>
</body>
</html>`)
}
{
"rewrites": [
{ "source": "/:path*", "destination": "/api/edge" }
]
}