[Sapper] export로 완전 정적 사이트 만들기 [Svelte]
(Sapper 강한 헬로 월드 화면)
앞으로 온다든지 오지 않는다든가, 해외에서는 이미 오고 있다고 말해지고 있는 web 프런트 엔드 JS 의 프레임워크(컴파일러)의 Svelte.
이번은 그 Svelte를 웹 애플리케이션 제작 용도로 확장하는 프레임워크, Sapper의 이야기.
{참고}
정적 생성
SSR 메인 프레임워크로 만든 사이트를 Netlify 등의 정적 파일 호스팅 서비스로 운용한다.
Nuxt.js로 말하면 nuxt generate
, Next.js로 말하면 next export
가 해당한다.
Sapper에서는 sapper export
가 그에 해당한다.
문제점 : 페이지 전환 시 API 요청이 실행됨
※오류 핸들링은 생략
/src/routes/example.svelte
<script context="module">
export async function preload() {
const res = await this.fetch('https://your-api-endpoint-here.com/');
const data = await res.json();
if (res.status === 200) {
return { post: data };
}
}
</script>
<script>
export let post;
</script>
{@html post.content}
위와 같은 svelte 를 sapper export
해, 톱 페이지에 액세스 후 이 svelte 에 대응하는 페이지 (/example )에 a 태그 천이 해 보면, 클라이언트측으로부터 API 서버에의 fetch 가 발생해 버린다.
즉, preload
함수 (Nuxt.js asyncData
/Next.js getInitialProps
)가 그대로 클라이언트 측에서 실행됩니다.
※ Sapper 에서는 a 태그는 디폴트로 History API 를 사용한 천이가 된다
API 서버가 그다지 강하지 않을 때나, 리밋트가 마련되고 있는 등, 이 사양은 받을 수 없는, 완전 정적으로 하고 싶다고 느끼었을 때에 다음의 방법으로 해결할 수 있다.
솔루션 : API 통신에 프록시 준비
this.fetch
대상을 갑자기 API 서버로 만드는 대신 로컬로 향합니다.
/src/routes/example.svelte<script context="module">
export async function preload() {
//ここでいきなり https://~~ ではなく、ローカルを参照する
const res = await this.fetch('api.json');
const data = await res.json();
if (res.status === 200) {
return { post: data };
}
}
</script>
그리고이 지역을 향한 곳
/src/routes/api.json.js
import fetch from 'node-fetch'
export async function get(req, res) {
fetch(`https://your-api-endpoint-here.com/`)
.then(response => response.json())
.then(json => {
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify(json))
})
}
그리고 API 서버와 통신하여 내용을 반환하는 js를 설치한다.
(통신 라이브러리에 node-fetch를 사용하고 있지만, 비슷한 것이라면 무엇이든 좋다고 생각한다)
이 상태에서 sapper export
하면, API 서버로부터의 응답 내용이 정적 파일( json )로서 확실히 써내져 페이지 천이시도 이 로컬 json 를 참조하게 된다.
왜
sapper export
때의 메커니즘
Docs • Sapper #How it works
※오류 핸들링은 생략
/src/routes/example.svelte
<script context="module">
export async function preload() {
const res = await this.fetch('https://your-api-endpoint-here.com/');
const data = await res.json();
if (res.status === 200) {
return { post: data };
}
}
</script>
<script>
export let post;
</script>
{@html post.content}
위와 같은 svelte 를
sapper export
해, 톱 페이지에 액세스 후 이 svelte 에 대응하는 페이지 (/example )에 a 태그 천이 해 보면, 클라이언트측으로부터 API 서버에의 fetch 가 발생해 버린다.즉,
preload
함수 (Nuxt.js asyncData
/Next.js getInitialProps
)가 그대로 클라이언트 측에서 실행됩니다.※ Sapper 에서는 a 태그는 디폴트로 History API 를 사용한 천이가 된다
API 서버가 그다지 강하지 않을 때나, 리밋트가 마련되고 있는 등, 이 사양은 받을 수 없는, 완전 정적으로 하고 싶다고 느끼었을 때에 다음의 방법으로 해결할 수 있다.
솔루션 : API 통신에 프록시 준비
this.fetch
대상을 갑자기 API 서버로 만드는 대신 로컬로 향합니다.
/src/routes/example.svelte<script context="module">
export async function preload() {
//ここでいきなり https://~~ ではなく、ローカルを参照する
const res = await this.fetch('api.json');
const data = await res.json();
if (res.status === 200) {
return { post: data };
}
}
</script>
그리고이 지역을 향한 곳
/src/routes/api.json.js
import fetch from 'node-fetch'
export async function get(req, res) {
fetch(`https://your-api-endpoint-here.com/`)
.then(response => response.json())
.then(json => {
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify(json))
})
}
그리고 API 서버와 통신하여 내용을 반환하는 js를 설치한다.
(통신 라이브러리에 node-fetch를 사용하고 있지만, 비슷한 것이라면 무엇이든 좋다고 생각한다)
이 상태에서 sapper export
하면, API 서버로부터의 응답 내용이 정적 파일( json )로서 확실히 써내져 페이지 천이시도 이 로컬 json 를 참조하게 된다.
왜
sapper export
때의 메커니즘
Docs • Sapper #How it works
<script context="module">
export async function preload() {
//ここでいきなり https://~~ ではなく、ローカルを参照する
const res = await this.fetch('api.json');
const data = await res.json();
if (res.status === 200) {
return { post: data };
}
}
</script>
import fetch from 'node-fetch'
export async function get(req, res) {
fetch(`https://your-api-endpoint-here.com/`)
.then(response => response.json())
.then(json => {
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify(json))
})
}
sapper export
때의 메커니즘Docs • Sapper #How it works
sapper build
생성 된 프로덕션 파일 (이 단계에서는 여전히 SSR)을 크롤링하고 루트에서 모든 a 태그를 캡처하여 정적 파일로 만듭니다. preload
함수의 this.fetch
끝도 캡처하여 정적 파일로 만듭니다. 그러나
Is it possible to run preload once for completely static html generate when "sapper export" was used? · Issue #972 · sveltejs/sapper
If preload is calling this.fetch and that's getting a file at a local path, that response will also be saved when export is crawling the site. If the data is coming from a remote server, you can make a local endpoint that proxies to the remote endpoint, and have this.fetch request that.
정적 파일로 하는 것은 로컬 패스만.
그래서
this.fetch
에 리모트 패스를 직접 쓰는 것이 아니라, 일단 로컬 패스로 해, 프록시 하면, 프록시 한 내용을 캡쳐 해 정적 파일이 생성된다, 하는 구조.☕
이 Svelte/Sapper는 Vue/Nuxt를 한 적이있는 사람이라면 꽤 붙어 쉽다고 느꼈습니다.
학습면에서 말하면 공식 튜토리얼이 충실한 것도 매력입니다.
개인적으로 Sapper의 a 태그를 역기능으로 전력 캡쳐하는 구조는 마음에 들었습니다.
루트 지정하지 않아도 좋기 때문에 편합니다.
$Thank$ $You$.
Reference
이 문제에 관하여([Sapper] export로 완전 정적 사이트 만들기 [Svelte]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/the_fukui/items/642c155f44349474c2eb
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여([Sapper] export로 완전 정적 사이트 만들기 [Svelte]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/the_fukui/items/642c155f44349474c2eb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)