📝

Sveltekitでadapterを切り替える

2021/01/17に公開

2022/02/12 追記

大変ありがたいことに2022年になってもこの記事に「いいね」を頂くことがありますが、SvelteKitは既にパブリックベータになっており、ドキュメントも充実しております。
SvelteKitのadapterの情報はこちらからどうぞ。

https://kit.svelte.jp/docs/adapters

以降は元々の記事です


※2021/1/17現在、Sveltekitはprivate repoで開発されており正式にリリースされていません。
※この記事の内容はすぐに古くなります。

SvelteとSapperとSveltekitの関係についてはここでは触れません。
他の方が書いてくださっている記事や、Svelte公式のブログをご参照ください。

https://svelte.dev/blog/whats-the-deal-with-sveltekit

サマリ

  • Sapperではコマンドを切り替えてビルドを変更できる
    • npm run build もしくは sapper build
      • バックエンドも込みで自己完結した形式
    • npm run export もしくは sapper export
      • Netlifyや任意のバックエンドでホストするための形式
  • Sveltekitではadapterと呼ばれるものを設定ファイルで切り替えてビルドする
  • adapterを切り替えてstaticな形式にビルドし、Goのサンプルサーバーでホストしてみる

背景

Svelteのパフォーマンスの良さ、Sapperのわかりやすさがとても気に入っています。
しかし、諸事情により別の言語のバックエンドを使用しているため、sapper exportをしてstaticな形式にビルドし、別のバックエンドにホストしていたのですが、Sveltekitにはsapper exportに当たるものがぱっと見当たらなかったので調べてみました。

準備

Sveltekitをインストール

公式ブログを参考に、インストールします。

npm init svelte@next my-app

disclaimerが表示されたあと、 TypeScriptを使用するか、CSSはどうするか聞かれますのでお好みでどうぞ。

create-svelte version 2.0.0-next.25

█████████  ███████████    ███████    ███████████  ███
███░░░░░███░█░░░███░░░█  ███░░░░░███ ░░███░░░░░███░███
░███    ░░░ ░   ░███  ░  ███     ░░███ ░███    ░███░███
░░█████████     ░███    ░███      ░███ ░██████████ ░███
░░░░░░░░███    ░███    ░███      ░███ ░███░░░░░░  ░███
███    ░███    ░███    ░░███     ███  ░███        ░░░
░░█████████     █████    ░░░███████░   █████        ███
░░░░░░░░░     ░░░░░       ░░░░░░░    ░░░░░        ░░░

Pump the brakes! A little disclaimer...

svelte@next is not ready for use yet. It definitely can't
run your apps, and it might not run at all.

We haven't yet started accepting community contributions,
and we don't need people to start raising issues yet.

Given these warnings, please feel free to experiment, but
you're on your own for now. We'll have something to show
soon.

✔ Copied project files
✔ Use TypeScript in components? … yes
✔ Added TypeScript support. To use it inside Svelte components, add lang="ts" to the attributes of a script tag.
✔ What do you want to use for writing Styles in Svelte components? › CSS
You can add support for CSS preprocessors like SCSS/Less/PostCSS later.

Next steps:
  1: cd my-app
  2: npm install (or pnpm install, or yarn)
  3: npm run dev -- --open

To close the dev server, hit Ctrl-C

Stuck? Visit us at https://svelte.dev/chat

インストールが終わったら、上記の「Next steps」に従い依存関係をインストールして実行してみます。

cd my-app
npm install
npm run dev -- --open

この画面が表示されます。かっこいいですね。

試しにビルドしてみる

ルートディレクトリにあるpackege.jsonを見てみます。
scriptsにdevbuildstartがあるのは確認できます。

buildを実行すればなにかしらビルドしてくれそうです。
やってみましょう。

npm run build

my-app/.svelte/buildが生成されます。

├── .svelte
│   ├── assets
│   └── build
│       ├── optimized
│       │   ├── client
│       │   └── server
│       └── unoptimized
│           ├── client
│           └── server

optimized・unoptimizedというディレクトリができて、それぞれその配下にclient・serverというディレクトリができ、そこに.jsファイルや.cssファイルが生成されています。

これはこれで良いとして、私がやりたいのはSapperでいうsapper exportです。
上記のアウトプットではそのまま任意のバックエンドにホストしても動いてはくれません。

しかし、package.jsonには他にそれらしきscriptはなさそうです。

adapterとは

ルートディレクトリ直下のReadme.mdを見てみましょう。
Readme.mdの最下部を読むと、大体こんな感じのことが読み取れます。

- Svelteは`adapter`によってビルド出力の形式を変えられます
  - 例えばNetlify向け、Vercel向けなど
  - あなたに必要な`adapter`を自作することもできます
- デフォルトでは、`npm run build`を実行すると`node build`で実行できるNode appが生成されます。
- 他の`adapter`を使う場合はそれをインストールして`svelte.config.js`を更新してください。公式からは以下の`adapter`がご利用頂けます。
  - @sveltejs/adapter-node
  - @sveltejs/adapter-static
  - @sveltejs/adapter-netlify
  - ...

※内容を適当に間引いて意訳したものです。正確に知りたい方は実際に確認してください。
※まだこのドキュメントも準備中のはずなのでご注意ください。

なるほど、Sveltekitではそれぞれの環境向けにビルド出力を切り替えられるよう、こういったプラグインのような機構を持っているようです。
実際いろいろな環境にホスティングするためにちまちまスクリプトを書いたりすることがあるので、これは大変ありがたいですね。

adapter-staticを使用する

私のやりたいことは@sveltejs/adapter-staticでできそうです。
これをインストールしてsvelte.config.jsに書けば良さそう。

Svelteの作者であるRich HarrisさんがSveltekitを発表した際に、その手順を実践してくれています。
※15:04~

実際にやってみましょう。
adapterをインストールして

npm install -D @sveltejs/adapter-static

svelte.config.jsを書き換えます。

		// adapter: '@sveltejs/adapter-node',
		adapter: '@sveltejs/adapter-static',

では再びビルドしてみましょう。

npm run build

おや?my-app/.svelte/buildを見てもstaticな形式にはなっていない、というかadapterを変更する前と結果が変わっていなそうです。
また、特に新しいディレクトリが生成されたわけでもないようです。

これは困りました。どうやって調べたものか。
こういうときはとりあえずなにかしら--helpを叩いてみるものです。
npm run buildで実際に実行されているのはsvelte-kitなので、それに対して--helpを実行してみましょう。

./node_modules/@sveltejs/kit/svelte-kit --help

  Usage
    $ svelte <command> [options]

  Available Commands
    dev      Start a development server
    build    Create a production build of your app
    start    Serve an already-built app
    adapt    Customise your production build for different platforms

  For more info, run any command with the `--help` flag
    $ svelte dev --help
    $ svelte build --help

  Options
    -v, --version    Displays current version
    -h, --help       Displays this message

おや?なにやらadaptというコマンドがありますね。
試しに実行してみましょう。まず他のコマンドと同じようにpackage.jsonに追記します。

	"scripts": {
		"dev": "svelte-kit dev",
		"build": "svelte-kit build",
		"start": "svelte-kit start",
		"adapt": "svelte-kit adapt"
	},

実行してみます。

npm run adapt

ルートディレクトリ直下にbuildディレクトリが生成され、そこに望んでいた形式で出力されました。

├── build
│   ├── _app
│   │   ├── (いくつかの.jsファイルや.cssファイル)
│   │
│   ├── favicon.ico
│   ├── index.html
│   └── robots.txt

実際に他のバックエンドでホストしてみる

どんな言語でも構わないのですが、ここはGoを使ってみましょう。
※Goのインストールなどは割愛します。

シンプルにbuildディレクトリにあるファイルをサーブするだけにします。
このファイルをルートディレクトリ直下に置きます。
main.go

package main

import (
	"log"
	"net/http"
)
  
func main() {
	fs := http.FileServer(http.Dir("./build"))
	http.Handle("/", fs)
  
	err := http.ListenAndServe(":4000", nil)
	if err != nil {
		log.Fatal(err)
	}
}

実行します。

go run main.go

http://localhost:4000 にアクセスします。

ちゃんと見れるようです。
画面遷移などを試してみたいですが、それはまた別の機会に。

感想

Sveltekitでもstatic出力できるようです。
adapterという興味深い仕組みがあることもわかりました。
また、この記事では触れていませんがホットリロードが本当に速いです。

まだprivateで開発が進められていますが、もうそろそろパブリックベータが出るそうなのでわくわくしますね。
https://twitter.com/Rich_Harris/status/1349522198193700872?s=20

この記事で実施した内容はこちらのリポジトリに置いてあります。
https://github.com/tomoam/dogfooding-sveltekit-20200116

Discussion