SSR 에서 제대로 import 되지 않는 모든 패키지에 참고할 수 있습니다.
Leaflet
과 같은 지도 컴퍼넌트는 현재 보고 있는 화면의 크기 및 위치에 따라 클릭 이벤트 등이 연동되어야 하기 때문에 Client
의 window
를 참고해서 동작한다.
하지만 SSR
(Server Side Rendering) 은 화면 구성과 관련된 javascript 파일을 주지 않고 화면을 이미 렌더링 된 상태로 전달하기 때문에 window
관련 속성에 접근하지 못 해, 일반적인 방법으로 Leaflet 을 Import 하면 window
가 없다는 오류가 발생한다.
위의 문제를 해결하는 방법은 두 가지가 있다.
Leaflet
을 onMount()
를 통해서 import 한다. vite-plugin-iso-import
를 사용한다. 필자는 1 번 방법을 이용해서 개발을 진행했으나, 1번 방법의 경우 Leaflet Plugin 을 사용할 때 또 난관에 부딪히게 된다. (plugin 은 onMount()
에서도 설치가 안 됨… ㅠㅠ)
따라서 2 번 방식을 사용하도록 하자.
참고하기 위해 1 번 방식도 아래에 기술한다.
자세한 사항은 아래 레포 참고
https://github.com/bluwy/vite-plugin-iso-import
npm i -D vite-plugin-iso-import
import { sveltekit } from '@sveltejs/kit/vite';
import { isoImport } from 'vite-plugin-iso-import';
/** @type {import('vite').UserConfig} */
const config = {
plugins: [sveltekit(), isoImport()]
};
export default config;
위는 필자의 샘플인데 isoImport
관련 항목만 업데이트해 주면 된다.
map component 의 script 에서 import 할 때 뒤에 ?client
를 붙여 주자.
여기에 ?server
를 붙여 주면 Server 에서 렌더링함.
import Leaflet from 'leaflet?client';
import 'leaflet.markercluster?client';
?client
와 ?server
를 타입스크립트가 인식하지 못 하기 때문에 별도 작업이 필요하다.
Svelte
나 Vue
가 아닌 경우 tsconfig.json
파일을 아래와 같이 수정하면 된다.
{
"compilerOptions": {
"plugins": [{ "name": "vite-plugin-iso-import" }]
}
}
하지만 Svelte
와 Vue
는 해당 프레임워크가 사용하는 d.ts
파일을 수정해야 함을 참고하자.
svelte 는 app.d.ts
파일이 있다.
해당 파일에 아래의 내용을 입력해 준다.
declare module 'leaflet?client' {
import all from 'leaflet'
export = all
}
declare module '*?client'
declare module '*?server'
위와 같이 입력하면 leaflet?client
를 패키지로 인식함.
일반적으로 Leaflet
을 SvelteKit
에서 사용하기 위한 방법으로 알려져 있는 방식이다.
import { onMount } from 'svelte';
onMount(async () => {
if(browser) {
L = await import('leaflet');
})
이렇게 해 주면 컴퍼넌트가 마운트 되면서 창에 대한 정보를 가져올 수 있어서 정상적으로 import 된다.
💡 plugin 은 같은 방식으로 설치가 안 되니, `vite-plugin-iso-import` 를 사용하자.위 내용의 샘플 소스는 아래 Github repo 를 참고
https://github.com/FrostScent/sveltekit-leaflet