こんにちは。よっしーです(^^)
今日は、SvelteKitでのサーバー専用モジュールについて解説しています。
背景
SvelteKitでのサーバー専用モジュールについて調査する機会がありましたので、その時の内容を備忘として記事に残しました。
サーバー専用モジュール
SvelteKitは、良き友人のようにあなたの秘密を守ってくれます。フロントエンドとバックエンドを同じリポジトリで開発する際、APIキーなどの機密データを誤ってフロントエンドコードにインポートしてしまう可能性があります。SvelteKitはこれを完全に防ぐための方法として「サーバーオンリーモジュール」を提供しています。
プライベート環境変数
$env/static/private
および$env/dynamic/private
モジュールは、hooks.server.js
や+page.server.js
のようなサーバー側でのみ実行されるモジュールにのみインポートすることができます。
サーバーオンリーユーティリティ
$app/server
モジュールは、ファイルシステムからアセットを読み取るためのread
関数を含んでおり、同様にサーバー側で実行されるコードでのみインポートすることができます。
独自のモジュール
独自のサーバーオンリーモジュールを作成するには2つの方法があります:
- ファイル名に
.server
を追加する(例:secrets.server.js
) $lib/server
ディレクトリに配置する(例:$lib/server/secrets.js
)
動作の仕組み
サーバーオンリーコードをパブリックなコードが(直接または間接的に)インポートすると、以下のような状況が発生します:
例示コード:
$lib/server/secrets
export const atlantisCoordinates = [/* redacted */];
src/routes/utils
export { atlantisCoordinates } from '$lib/server/secrets.js';
export const add = (a, b) => a + b;
src/routes/+page
<script>
import { add } from './utils.js';
</script>
エラー発生
SvelteKitは以下のようなエラーを表示します:
Cannot import $lib/server/secrets.js into public-facing code:
- src/routes/+page.svelte
- src/routes/utils.js
- $lib/server/secrets.js
重要なポイント
- パブリックコード(
src/routes/+page.svelte
)がadd
関数のみを使用し、機密のatlantisCoordinates
を使用していない場合でも、機密コードがブラウザにダウンロードされる可能性があるため、このインポートチェーンは安全ではないと見なされます。
動的インポートについて
- この機能は動的インポート(
await import(
./${foo}.js)
のような補間されたものを含む)でも機能します。 - ただし、開発中に公開コードとサーバーオンリーモジュールの間に2つ以上の動的インポートがある場合、コードが最初に読み込まれる時点では不正なインポートは検出されません。
テストにおける注意点
- Vitestなどのユニットテストフレームワークは、サーバーオンリーコードとパブリックコードを区別しません。
- そのため、
process.env.TEST === 'true'
の場合、不正なインポートの検出は無効化されます。
補足説明
- セキュリティ重視の設計:
- SvelteKitは、フロントエンドとバックエンドのコードを明確に分離することで、セキュリティリスクを軽減します。
- 環境変数やシステムリソースへのアクセスを制限することで、機密情報の漏洩を防ぎます。
- インポートチェーンの全体を追跡し、潜在的な脆弱性を特定します。
- モジュールの種類:
- プライベート環境変数モジュール:機密性の高い設定値の管理用
- サーバーユーティリティ:サーバー側の機能(ファイル操作など)へのアクセス用
- 使用場面:
- APIキーの管理
- データベース接続情報の保護
- サーバーサイドの処理に必要な機密情報の取り扱い
- 開発体験:
- 明確なエラーメッセージにより、開発者は問題の所在を素早く特定できます。
- テスト環境では制限が緩和され、より柔軟なテストが可能です。
- ベストプラクティス:
- サーバー専用のコードは明確に分離する
- 機密情報を含むモジュールは適切なディレクトリ構造で管理する
- インポートの依存関係に注意を払う
このような機能により、開発者は安全にフルスタック開発を行うことができます。
おわりに
今日は、 SvelteKitでのサーバー専用モジュールについて解説しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント