Closed7

【SvelteKit】svelte configのadapterを調査

komenzarkomenzar

最近さわっているsveltekitのアダプターの仕組みが気になったのでソースコードを読んでみる。

komenzarkomenzar

/adapter-vercel/index.jsの中を見てみると、export default plugin; とあります。そしてこのpluginの定義はこのようになっています。

/** @type {import('.').default} **/
const plugin = function (defaults = {}) {
	/** 略 **/

	return {
		name: '@sveltejs/adapter-vercel',

		async adapt(builder) {
			/** 略 **/
		}
	}
}

つまりpluginは大枠でみるとnameadaptという2つのプロパティをもつオブジェクトを返す関数です。

adaptは何をしているかというと、ビルドした生成物をおくディレクトリ設定やコンソールへの出力などです。

komenzarkomenzar

ところで、アダプターはsvelte.config.jsに記述します。これはどこでロードしているのでしょうか。
sveltekit公式ドキュメントから引用すると、

svelte.config.js
import adapter from '@sveltejs/adapter-vercel';

export default {
	kit: {
		adapter: adapter({
			// see the 'Deployment configuration' section below
		})
	}};

これをロードしている場所があるはず。リポジトリ内でkit.adapterという文字列を検索すると、src/core/adapt内のindex.jsファイルがヒットしました。

index.js

export async function adapt( config,  /** 略 **/ ) {
	const { name, adapt } = config.kit.adapter;
	/** 略 **/
}

ここでconfigファイルが発見!追跡します。

komenzarkomenzar

src/exports/vite/index.jsにて、動的にインポートされています。ビルドする際にkit.adapterがあればインポートするようになっています。

	/** 略 **/
if (kit.adapter) {
	const { adapt } = await import('../../core/adapt/index.js');
	await adapt(
	svelte_config,
	build_data,
	metadata,
	prerendered,
	prerender_map,
	log,
	vite_config
	);
} else {
	/** 略 **/

ここでadaptの引数にあたえられているsvelte_configがどこから来ているのかが気になります。定義部分をさがすと、

/**
 * Returns the SvelteKit Vite plugins.
 * @returns {Promise<import('vite').Plugin[]>}
 */
export async function sveltekit() {
	const svelte_config = await load_config();

	/** 略 **/

viteプラグインを生成する関数の最初にありました。次はload_config()を探ります。

komenzarkomenzar

同じくsrc/exports/vite/index.jsの先頭部分にて

import { load_config } from '../../core/config/index.js';

今度はsrc/core/configをみてみます。

/**
 * Loads and validates svelte.config.js
 * @param {{ cwd?: string }} options
 * @returns {Promise<import('types').ValidatedConfig>}
 */
export async function load_config({ cwd = process.cwd() } = {}) {
	const config_file = path.join(cwd, 'svelte.config.js');

	if (!fs.existsSync(config_file)) {
		return process_config({}, { cwd });
	}

	const config = await import(`${url.pathToFileURL(config_file).href}?ts=${Date.now()}`);

	return process_config(config.default, { cwd });
}

ここでsvelte.config.jsを読み込んでいるのがわかります。

komenzarkomenzar

まとめると、

  • adapter-xxxは各プラットフォームでのビルド方法について設定する。
  • sveltekitはviteでビルドする。
    • その際にsvelte.config.jsを読み込む。
    • kit.adapterが指定されていれば読み込む。

こんな感じです。

このスクラップは2023/11/14にクローズされました