const id = event.path.split('/').filter(p => p).reverse()[0]
변경 전 render.ts
const { data } = await axios({ //2.
url: '/.netlify/functions/workspace',
method: 'POST',
data: {
id,
method: 'GET'
}
})
const { title, content, poster } = data //3.
}
변경 후 render.ts
const { APIKEY, USERNAME } = process.env
const handler: Handler = async event => {
const id = event.path.split('/').filter(p => p).reverse()[0]
const { data } = 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
}
})
const { title, content, poster } = data
**vite.config.ts
server: {
port: 2999
},
build: { ✅
rollupOptions: {
output: {
entryFileNames: 'assets/[name].js',
chunkFileNames: 'assets/[name].js',
assetFileNames: 'assets/[name].[ext]' //정적파일
}
}
}
})
<script defer type="module" src="/src/main.ts"></script>
부분도 가져가야합니다.<script defer type="module" src="/src/main.ts"></script>
부분은 <div id="app"></div>
다음에 작성이 되어 있습니다.<script type="module" src="/src/main.ts"></script>
<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" />
<script defer type="module" src="/src/main.ts"></script>
env
APIKEY=FckdtJs202204
USERNAME=ParkYoungWoong
MODE=development ✅
# PUBLIC_URL=https://enchanting-bublanina-4dd5c6.netlify.app
PUBLIC_URL=http://localhost:3000
<script defer type="module" src="/src/main.ts"></script>
가 돌아갈 수 있도록 만들 것입니다.➕PUBLIC_URL
- 기본 도메인 주소의 경우에도 바뀔 수가 있기 때문에 환경변수로 설정해도 좋습니다.)
- 이렇게 추가한
PUBLIC_URL
을 netlify의 환경변수에도 추가를 해줍니다.
render.ts
const { APIKEY , USERNAME, MODE} = process.env //✅
<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">'
}//배포모드, 한줄이 아니면 에러가 나니 한줄로 작성해줍니다.
배포를 할 때 id가 제대로 들어가지 않는 경우 닫히게 됩니다. 실제로 render함수의 경우 넷니파이에서는 그렇게 필요하지 않습니다.
따라서 workspaces안의 주소부분에서만 렌더함수를 사용할 수 있도록 redirects를 하나 더 만들어 분기시켜줍니다.
'/workspaces/*'
의 *이 아이디값이기 때문에 충분히 아이디를 추출할 수 있습니다.//netlify.toml
[dev]
targetPort = 2999 # 연결할 프로젝트 개발 서버의 포트를 지정합니다.
port = 3000 # 출력할 Netlify 서버의 포트를 지정합니다.
[[redirects]]
from = '/workspaces/*'
to = '/.netlify/functions/render'
status = 200
[[redirects]]
from = '/*'
to = '/index.html'
status = 200
$ npm run netlify
$ git push origin main
배포를 해보면 정상적으로 잘 배포가 되는 것을 확인할 수 있습니다.
카카오톡은 트위터카드에 조금 더 최적화되어 있습니다. 트위터카드도 설정해보도록 하겠습니다.
<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://enchanting-bublanina-4dd5c6.netlify.app/workspaces/${id}" />
- 엣지 함수가 도입되면 더이상 render.ts는 필요하지 않습니다.
- 서버함수가 실행 약 30초정도 걸린다면 엣지함수는 약 1~2초로 매우 빠릅니다.
- 엣지함수는 사용자에 맞게 리전을 선택합니다
- 처리를 해야하는 무거운 함수는 엣지함수에 넣을 수가 없습니다. 따라서 분기처리를 해줘야합니다.(봇인지 사용자인지 구분)
디노란?
디노 자바스크립트와 타입스크립트로 동작하는 노드제이에서 환경중 하나입니다. node.js를 만든 사람이 노드제이에스의 문제점을 보완해 만든 것이 바로 디노입니다.
(환경 자체가 노드제이에스가 아닙니다)노드제이에스의 문제점은?
- node-modules
- 실제로 프로젝트를 구성해서 작업을 하다보면 npm i로 패키지를 설치하게 됩니다. 또한 그 패키지가 동작하기 위해 내부적으로 패키지를 설치하게 됩니다. 이패키지를 작성한 코드에 맞게 빌드해서 그 빌드된 결과를 가지고 브라우저에 출력을 하게 됩니다.
- 그런데 코드 한글자만 바꿨음에도 그바뀐 글자를 위해 또 다시 빌드를 해야하는 것입니다.
- 이경우 프로젝트 규모가 크면 클수록 한글자 바꾸고 화면에서 확인하는데 1분~4분~10분까지도 걸리게 됩니다.
- 그래서 나온게 스노우팩, 더확정된 것이 vite.js입니다.(빌드과정을 최소화)
- 빌드과정은 완벽히 똑같지만 개발할 때는 다 모듈화시켜서 직접 브라우저에서 돌립니다.
- 결국 디노는 노드모듈수가 너무 무거워서 나오게 된것입니다.
- 디노는 모두 CDN방식을 사용합니다.
- 즉, 디노는 인터넷이 안되면 개발할 수 없습니다.
import { Context } from 'netlify:edge' //2
export default async (request: Request, context: Context) => {//1
console.log('user-agent ::', request.headers.get('user-agent') //3
console.log('request.url', request.url)
return await context.next() //4. 다음으로 넘겨줍니다.
}
import { Context } from 'netlify:edge'
해와야합니다.(request는 전역으로 가지고 있는 Request를 사용하면 됩니다.)[dev]
targetPort = 2999 # 연결할 프로젝트 개발 서버의 포트를 지정합니다.
port = 3000 # 출력할 Netlify 서버의 포트를 지정합니다.
# [[redirects]] //✅
# from = '/workspaces/*'
# to = '/.netlify/functions/render'
# status = 200
[[edge_functions]] //✅
path = "/workspaces/*"
function = "workspaces"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
http://localhost:3000/.netlify/edge/sorkspaces로 접근 해 특정 페이지에 접근 한 후 새로고침을 한 후 콘솔을 확인해봅니다.
user-agent의 경우 맥과 윈도우가 다르게 출력될 것입니다.
reqeust_url은 사용자가 접속한 그 해당하는 주소입니다.
접근하는 유저 에이전트가 봇인지, 일반사용자인지 구분을 하는 용도로 사용되는 패키지 입니다.
skypack으로 접근을 해 코드를 가져옵니다.
import isbot from 'https://cdn.skypack.dev/isbot' ✅ //1
const APIKEY = Deno.env.get('APIKEY') as string
const USERNAME = Deno.env.get('USERNAME') as string
export default async (request: Request, context: Context) => {
const userAgent = request.headers.get('user-agent') ✅//1
const id = request.url.split('/').filter(p => p).reverse()[0]
if (isbot(userAgent) && id) { ✅ //1
const res = await fetch(`https://asia-northeast3-heropy-api.cloudfunctions.net/api/notion/workspaces/${id}`, {
method: 'GET',
headers: {
'content-type': 'application/json',
'apikey': APIKEY,
'username': USERNAME
}
})
const { title, content, poster } = await res.json()
return new Response(
/* html */ `
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<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://charming-moonbeam-67283c.netlify.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://charming-moonbeam-67283c.netlify.app/workspaces/${id}" />
</head>
<body></body>
</html>
`,
{
headers: { 'content-type': 'text/html' }
}
)
}
return await context.next()
}
https://asia-northeast3-heropy-api.cloudfunctions.net/api/notion/workspaces/${id}
Deno.env.get('APIKEY')
return await context.next()
를 통해 일반사용자인경우 그냥 지나가게 합니다.const id = request.url.split('/').filter(p => p).reverse()[0]
{headers: { 'content-type': 'text/html' }}
$ npm run netlify