プログラミング/svelte の変更点

更新


#author("2024-09-06T15:07:58+00:00","default:administrator","administrator")
#author("2024-09-06T15:08:14+00:00","default:administrator","administrator")
[[公開メモ]]

* svelte や svelte kit を使いこなしたい [#o86663ca]

svelte や svelte kit は Web サイト構築用のライブラリ

Visual Studio Code を最大限活用するために作られた最新のエコシステムの恩恵を受けるために勉強してみよう

以下で学ぶこと:

- データベースの使い方を学ぶ (Prisma)
- フォームのバリデーション (SuperForms, Zod)
- サインアップ・ログイン・ログアウトのできる認証機能 (Lucia)
- その際にメールアドレスの確認を行う (nodemailer)
- css ライブラリを選定する (TailwindCSS, DaisyUI, svelte-french-toast)
- デプロイ方法を学ぶ (node build)
- テストを書く (Playwright, vitest)


* 目次 [#p0ab4c9c]

#contents

** いろいろ読んで勉強中 [#o6d339e1]

- SvelteKit+Superforms+Prisma+Luciaでログイン機能を爆速で実装する~
https://zenn.dev/gawarago/articles/f75f5113a3803d
- SvelteKitが正式リリースされたのでtRPCとPrismaを使ってWebアプリを開発してみた~
https://zenn.dev/kosei28/articles/d965f221a656fd
- Vitest / Playwrightを使ってSvelteのコンポーネントをテストする~
https://qiita.com/oekazuma/items/925ddbf48870fb999c19#vitest%E3%81%A8%E3%81%AF
- TypeScript 4.9のas const satisfiesが便利。型チェックとwidening防止を同時に行う~
https://zenn.dev/moneyforward/articles/typescript-as-const-satisfies
- コーディング不要でGraphQLサーバが作れるPrismaを触ってみて可能性を感じた - SMARTCAMP Engineer Blog~
https://tech.smartcamp.co.jp/entry/started-prisma
- worst password list~
https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/10-million-password-list-top-100000.txt
- 5歳娘「パパ、余分なpropsいっぱい書くんだね!」~
https://qiita.com/Yametaro/items/814f40d08e9d30584e20#5%E6%AD%B3%E5%A8%98%E3%83%91%E3%83%91%E4%BD%99%E5%88%86%E3%81%AAprops%E3%81%84%E3%81%A3%E3%81%B1%E3%81%84%E6%9B%B8%E3%81%8F%E3%82%93%E3%81%A0%E3%81%AD
-- svelte での書き方 → https://stackoverflow.com/questions/76285794/svelte-components-intrinsicelements-or-sveltehtmlelements-for-extending-with-ht

* いよいよやってみる [#s61d3616]

ここでの作業内容を収めた GitHub プロジェクト:~
https://github.com/osamutake/svelte-authtest

+ [[プログラミング/svelte/VSCodeの準備]]
+ [[プログラミング/svelte/テストの仕方を確認]]
+ [[プログラミング/svelte/Prisma と Lucia を使った認証システム]]
+ [[プログラミング/svelte/メールアドレスの確認を行う]]
+ [[プログラミング/svelte/認証機能のテストを追加]]
+ [[プログラミング/svelte/管理者権限を付与する]]
+ [[プログラミング/svelte/ブログ的なもの作り-投稿・表示・編集]]
+ [[プログラミング/svelte/コード配置の整理]]
+ [[プログラミング/svelte/記事の見た目をいじる]]
+ [[プログラミング/svelte/pukiwikiの記事を流し込む]]

* Svelte 5 [#g8e59aef]

- [[プログラミング/svelte/svelte5の$stateをexportする]]
- [[プログラミング/svelte/svelte5への移行]]
- [[プログラミング/svelte/svelte5手順覚書]]
- [[プログラミング/svelte/svelte5手抜き国際化]]
- [[プログラミング/svelte/svelte5ダイナミックコンポーネントを使ったテーマ変更]]

* 小ネタ [#vd27dac7]

** typescript + vitest で npm パッケージの開発 [#g7ba2712]

[[typescript + vitest で npm パッケージの開発 2024]]

** オンプレミスの GitLab サーバーで CI ランナーと npm パッケージサーバーを動かす [#h214d3d0]

[[オンプレGitLabでgit&CI&npmサーバー2024]]
[[オンプレGitLabでgit+CI+npmサーバー2024]]

** svelte コンポーネントの Re-export [#b20fae61]

default に名前を付けて Export すればいい

 LANG:html
 <script lang='ts'>
   export { default as Component } from 'component.svelte';


** +layout.server.ts からの PageData を +page.server.ts で使う [#hc48192a]

*** load 内で使うとき [#o751a952]

load 内で使えればよいのであれば event.parent() を使って

~+page.server.ts
 LANG:ts
 export const load = (async (event) => {
   const data = await event.parent();

とすればよい。

*** actions で使うとき [#kb762bb4]

actions が呼ばれるときはページのレンダリングと違って API としての呼び出しになるため layout.server.ts は呼ばれない。

そういうデータはどうやら PageData ではなく Locals に保存されるべきで src/hooks.server.js で設定するのが筋らしい。

- https://kit.svelte.jp/docs/types#app-locals
- https://kit.svelte.jp/docs/hooks

** 呼び出し間隔の調整を行う [#t37e6d7d]

主にイベントハンドラからの呼び出しを UI へフィードバックする際に使うことを想定している。

 LANG: ts
 // const throttled = new Throttle(func, minInterval);
 // throttled.exec(arg1, arg2);
 // のように使うと、最低限 interval 空けて実行される
 // interval 未満の場合には interval だけ待ってから実行
 // 実行待ちがあって呼び出されればそちらをキャンセルして新しい方を実行待ちする
 export class Throttle {
   lastExecTime = 0;
   timerId: number | undefined;
 
   constructor(
     private func: (...args: unknown[]) => void,
     private millisec: number = 50
   ) {}
 
   exec(...args: unknown[]) {
     // 実行待ちがあればキャンセル
     window.clearTimeout(this.timerId);
     this.timerId = undefined;
 
     const execute = () => {
       this.timerId = undefined;
       this.func(...args);
       this.lastExecTime = performance.now();
     };
 
     // あとどれだけ待つ必要があるか
     const wait = this.lastExecTime + this.millisec - performance.now();
     if (wait < 0) {
       // 即実行
       execute();
     } else {
       // 実行予約
       this.timerId = window.setTimeout(execute, wait);
     }
   }
 }

** path へのエイリアスを tsconfig で利かす [#mfcee49f]

tsx を使うと .ts ファイルを直接実行できて便利なのだけれど、そこから呼ばれる import に $lib などのパスエイリアスが含まれて入れるとエラーになる。

その場合には tsx に --tsconfig を指定して動かすといい

 LANG:console
 $ ./node_modules/.bin/tsx --tsconfig tsconfig.json some-script.ts 

** grep する [#a09ba0fc]

~-r で再帰をかけておき、除外するディレクトリを exclude-dir で指定するといい

 LANG:console
 $ grep --exclude-dir={node_modules,assets,.svelte-kit,build,bower_components} -rl "検索対象"

~-l を付けることでファイル名のみを表示させている

VSC の terminal なら表示されたファイル名の Ctrl+Click でファイルを開ける

** ZodObject の中身を見る [#b5d6e707]

 LANG:ts
 export const SettingScheme = z.object({
   param1: z.string().default('default1'),
   param2: z.string().default('default2'),
 });
  
 // データ型を得る
 type Setting = z.infer<typeof SettingScheme>;
 
 // z.object に渡した { param1: ..., param2: ... } を得る
 const objectDefinition = SettingScheme.shape;
 
 // objectDefinition['param1'] は ZodDefault<ZodString> のようなもの
 // ZodString を取り出すには
 let param1def: any = objectDefinition['param1];
 while(param1def?._def?.innerType) {
   // ZodDefault などでラップされているのを剥がす
   param1def = param1def_def.innerType;
 }

Counter: 1766 (from 2010/06/03), today: 4, yesterday: 2