他のリソース permalink
Svelte FAQ と vite-plugin-svelte
FAQ も、これらのライブラリに起因する疑問点には役立つのでご参照ください。
Svelte FAQ と vite-plugin-svelte
FAQ も、これらのライブラリに起因する疑問点には役立つのでご参照ください。
SvelteKit は svelte-hmr によってデフォルトで HMR が有効になっています。Rich の 2020 Svelte Summit のプレゼンテーション を見たことがあるなら、より強力そうに見えるバージョンの HMR をご覧になったかもしれません。あのデモでは svelte-hmr
の preserveLocalState
フラグがオンになっていました。このフラグは想定外の動作やエッジケースにつながる可能性があるため、現在はデフォルトでオフになっています。でもご心配なく、SvelteKit で HMR を利用することはできます!もしローカルの状態を保持したい場合は、svelte-hmr ページに説明があるように、@hmr:keep
または @hmr:keep-all
ディレクティブを使用することができます。
SvelteKit は svelte.config.js
を ES module として想定しているため、JSON ファイルを直接要求することはできません。もしアプリケーションに package.json
からバージョン番号またはその他の情報を含めたい場合は、このように JSON をロードすることができます:
ts
import {readFileSync } from 'fs';import {fileURLToPath } from 'url';constfile =fileURLToPath (newURL ('package.json', import.meta.url ));constjson =readFileSync (file , 'utf8');constpkg =JSON .parse (json );
ライブラリのインクルードに関する問題は、ほとんどが不適切なパッケージングによるものです。ライブラリのパッケージングが Node.js に対応しているかどうかは、publint の web サイト でチェックできます。
以下は、ライブラリが正しくパッケージングされているかどうかをチェックする際に気を付けるべき点です:
exports
は main
や module
などの他のエントリーポイントのフィールドよりも優先されます。exports
フィールドを追加すると、deep import を妨げることになるため、後方互換性が失われる場合があります。"type": "module"
が指定されていない限り、ESM ファイルは .mjs
で終わる必要があり、CommonJS ファイルは .cjs
で終わる必要があります。exports
が定義されていない場合、main
を定義する必要があり、それは CommonJS ファイル か ESM ファイル でなければならず、前項に従わなければならない。module
フィールドが定義されている場合、ESM ファイルを参照している必要があります。.svelte
ファイルとして配布し、パッケージに含まれる JS は ESM のみとして記述していなければなりません。TypeScript などのカスタムスクリプトや SCSS などのスタイル言語は、それぞれ vanilla JS と CSS にするために前処理(preprocess)をしなければなりません。Svelte ライブラリのパッケージングには、svelte-package
を使用することを推奨しています。このパッケージによって、これらの作業が行われます。ライブラリが ESM バージョンを配布している場合、特に Svelte コンポーネントライブラリがその依存関係に含まれている場合、Vite を使用するとブラウザ上で最適に動作します。ライブラリの作者に ESM バージョンを提供するよう提案すると良いでしょう。しかし、CommonJS (CJS) の依存関係も上手く扱えるようにするため、デフォルトで、vite-plugin-svelte
が Vite にそれらを事前バンドルするよう指示します。Vite は esbuild
を使ってそれらを ESM に変換します。
それでもまだ問題が解消されない場合は、Vite の issue tracker と 該当のライブラリの issue tracker を検索することを推奨します。optimizeDeps
や ssr
の設定値をいじることで問題を回避できる場合もありますが、これはあくまで一時的な回避策とし、問題のあるライブラリの修正を優先したほうが良いでしょう。
ドキュメントのインテグレーションのセクション をしっかり読み込んでください。それでも問題が解決しない場合のために、よくある問題の解決策を以下に示します。
データベースに問い合わせを行うコードを サーバールート(server route) に置いてください。.svelte ファイルの中でデータベースに問い合わせを行わないでください。コネクションをすぐにセットアップし、シングルトンとしてアプリ全体からクライアントにアクセスできるように db.js.ts
のようなものを作ることができます。hooks.js.ts
で1回セットアップするコードを実行し、データベースヘルパーを必要とするすべてのエンドポイントにインポートできます。
document
や window
に依存しているクライアントサイドオンリーなライブラリはどう使えばよいですか?
permalinkもし document
や window
変数にアクセスする必要があったり、クライアントサイドだけで実行するコードが必要な場合は、browser
チェックでラップしてください:
ts
import { browser } from '$app/environment';if (browser) {// client-only code here}
コンポーネントが最初にDOMにレンダリングされた後にコードを実行したい場合は、onMount
で実行することもできます:
ts
import {onMount } from 'svelte';onMount (async () => {const {method } = await import('some-browser-only-library');method ('hello world');});
使用したいライブラリに副作用がなければ静的にインポートすることができますし、サーバー側のビルドでツリーシェイクされ、onMount
が自動的に no-op に置き換えられます:
ts
import {onMount } from 'svelte';import {method } from 'some-browser-only-library';onMount (() => {method ('hello world');});
一方、ライブラリに副作用があっても静的にインポートをしたい場合は、vite-plugin-iso-import をチェックして ?client
インポートサフィックスをサポートしてください。このインポートは SSR ビルドでは取り除かれます。しかし、この手法を使用すると VS Code Intellisense が使用できなくなることにご注意ください。
ts
import {onMount } from 'svelte';import {method } from 'some-browser-only-library?client';onMount (() => {method ('hello world');});
外部の API サーバーにデータをリクエストするのに event.fetch
を使用することができますが、CORS に対応しなければならず、一般的にはリクエストのプリフライトが必要になり、結果として高レイテンシーになるなど、複雑になることにご注意ください。別のサブドメインへのリクエストも、追加の DNS ルックアップや TLS セットアップなどのためにレイテンシーが増加する可能性があります。この方法を使いたい場合は、handleFetch
が参考になるかもしれません。
別の方法は、頭痛の種である CORS をバイパスするためのプロキシーをセットアップすることです。本番環境では、/api
などのパスを API サーバーに書き換えます(rewrite)。ローカルの開発環境では、Vite の server.proxy
オプションを使用します。
本番環境で書き換え(rewrite)をセットアップする方法は、デプロイ先のプラットフォームに依存します。もし、書き換える方法がなければ、代わりに API route を追加します:
ts
export functionGET ({params ,url }) {returnfetch (`https://my-api-server.com/${params .path +url .search }`);}
ts
export constGET = (({params ,url }) => {returnfetch (`https://my-api-server.com/${params .path +url .search }`);}) satisfiesRequestHandler ;
(必要に応じて、POST
/PATCH
などのリクエストもプロキシし、request.headers
も転送(forward)する必要があることにご注意ください)
adapter-node
は、プロダクションモードで使用するためのミドルウェアを自分のサーバで構築します。開発モードでは、Vite プラグインを使用して Vite にミドルウェア(middleware) を追加することができます。例えば:
ts
import {sveltekit } from '@sveltejs/kit/vite';/** @type {import('vite').Plugin} */constmyPlugin = {name : 'log-request-middleware',configureServer (server ) {server .middlewares .use ((req ,res ,next ) => {console .log (`Got request ${req .url }`);next ();});}};/** @type {import('vite').UserConfig} */constconfig = {plugins : [myPlugin ,sveltekit ()]};export defaultconfig ;
順序を制御する方法など、詳しくは Vite の configureServer
のドキュメント をご覧ください。
多少は。Plug'n'Play 機能、通称 'pnp' は動きません (Node のモジュール解決アルゴリズムから逸脱しており、SvelteKitが数多くのライブラリとともに使用しているネイティブの JavaScript モジュールではまだ動作しません)。.yarnrc.yml
で nodeLinker: 'node-modules'
を使用して pnp を無効にできますが、おそらく npm や pnpm を使用するほうが簡単でしょう。同じように高速で効率的ですが、互換性に頭を悩ませることはありません。
現時点の、最新の Yarn (version 3) の ESM サポート は experimental であるようです。
結果は異なるかもしれませんが、下記が有効なようです。
最初に新しいアプリケーションを作成します:
yarn create svelte myapp
cd myapp
そして Yarn Berry を有効にします:
yarn set version berry
yarn install
Yarn 3 global cache
Yarn Berry の興味深い機能の1つに、ディスク上のプロジェクトごとに複数のコピーを持つのではなく、パッケージ用に単一のグローバルキャッシュを持つことができる、というのがあります。しかし、enableGlobalCache
の設定を true にするとビルドが失敗するため、.yarnrc.yml
ファイルに以下を追加することを推奨します:
nodeLinker: node-modules
これによってパッケージはローカルの node_modules ディレクトリにダウンロードされますが、上記の問題は回避され、現時点では Yarn の version 3 を使用するベストな方法となります。