🧊

Svelte/Sapperを静的サイトジェネレーター(SPA)として使う

最近ひさしぶりにペライチの静的なサイトを作る機会があって、何で作ろうかなーと考えた。

Nextの`export`や、Nuxtの`generate`があるなら、Svelte/SapperにもそういうSSGの機能があるのでは?というのがきっかけ。

https://sapper.svelte.dev/docs#Exporting

もちろんあった。

使い方

sapper export --legacy

以上。

`--legacy`をつけると、

  • モダンなブラウザ向け
  • Babelが必要なレガシー環境向け

というように2つ実行ファイルとしての`.js`が吐き出される。(どっちを使うかは動的に判断されるし、その判断コードもデフォルトで用意される)

無事に出力されたら、`__sapper__/export`ディレクトリ配下にあるものを、ホスティングすればよい。

最低限のファイルたち

.
├── README.md
├── package.json
├── rollup.config.js
├── src
│   ├── client.js
│   ├── components
│   │   ├── foo.svelte
│   │   └── bar.svelte
│   ├── routes
│   │   └── index.svelte
│   ├── server.js
│   └── template.html
└── static
    ├── global.css
    └── image
        └── sample.jpg

というように、`client.js`と`routes/index.svelte`と`template.html`だけあればよい。

注: `server.js`も必須

SSRしないなら、サーバー側のエンドポイントなんかいらんのでは?と思って消したら動かなくなった。

これには理由があって、Sapperの`export`コマンドはこんな感じで動くから。

  • 最初に`build`コマンドを叩いてサーバーを起動
  • ルートからたどれる全ページをクローリングして
  • 出会ったページを静的に出力する

なので、最低限のコードだけ書いた`server.js`が必要というわけらしい。

import sirv from "sirv";
import polka from "polka";
import * as sapper from "@sapper/server";

const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === "development";

polka() // You can also use Express
  .use(sirv("static", { dev }), sapper.middleware())
  .listen(PORT, (err) => {
    if (err) console.log("error", err);
  });

公式のテンプレートで用意されるコードから不要な処理を削っていって、残ったのがこれだけ。
Webサーバーは`express`でも`fastify`でももちろんよくて、`sapper`と静的ファイルを返すミドルウェアさえあればいい。

で、この使い方はいわゆるSPAモードというもの(言われてみれば確かに)で、対応中のIssueはこちら。

SPA mode · Issue #383 · sveltejs/sapper · GitHub

`ssrEnabled`というオプションが生えるらしい。

まとめ

Svelteのランタイムの小ささに取り憑かれた勢として、こういう使い方もできるのは思わぬ収穫だった。

ペライチみたいにSEOを意識するユースケースはもちろん採用するけど、完全なSPAを作るにしても、Svelte単体よりよいのでは・・?と思うくらいには簡単だった。