[[🦉Various Complements]]のUIに[[Svelte]]を導入してみた記録。以下を参考に。
<div class="link-card">
<div class="link-card-header">
<span class="link-card-site-name">marcus.se.net</span>
</div>
<div class="link-card-body">
<div class="link-card-content">
<div>
<p class="link-card-title">Svelte | Obsidian Plugin Developer Docs</p>
</div>
<div class="link-card-description">
This guide explains how to configure your plugin to use Svelte, a light-weight alternative to tradit...
</div>
</div>
</div>
<a href="https://marcus.se.net/obsidian-plugin-docs/getting-started/svelte"></a>
</div>
> [!caution] #2023/01/29
> このノートは[[Rollup]]プロジェクトを前提とした内容になっているが #2023/01/29 時点での主流は[[esbuild]]ベース。上記ドキュメントも[[esbuild]]ベースになっている。
> この先を読み進めるなら、その前提で適宜脳内置換をすること。
## プロジェクトへ適応
### 依存関係のインストール
```console
npm install --save-dev svelte svelte-preprocess @tsconfig/svelte rollup-plugin-svelte
```
### [[tsconfig.json]]に設定を追加・削除
```diff:tsconfig.json
{
+ "extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"strict": true,
+ "types": ["svelte", "node"],
"baseUrl": ".",
- "inlineSourceMap": true,
```
### [[rollup.config.js]]に設定を追加・削除
```diff:rollup.config.js
import typescript from "@rollup/plugin-typescript";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
+ import svelte from "rollup-plugin-svelte";
+ import sveltePreprocess from "svelte-preprocess";
export default {
input: "src/main.ts",
output: {
dir: ".",
sourcemap: "inline",
format: "cjs",
exports: "default",
},
external: ["obsidian"],
plugins: [
typescript(),
+ svelte({ emitCss: false, preprocess: sveltePreprocess() }),
nodeResolve({ browser: true }),
commonjs(),
],
};
```
## 動作確認
ドキュメントのサンプルコンポーネントを追加して表示させてみる。
```ts:Component.svelte
<script lang="ts">
export let count: number;
export let onClickClose: (num: number) => void;
const handleClickPlus = () => {
count++;
};
const handleClickClose = () => {
onClickClose(count);
};
</script>
<div class="number">
<span>My number is {count}!</span>
<button on:click={handleClickPlus}>plus</button>
<button on:click={handleClickClose}>close</button>
</div>
<style>
.number {
color: red;
}
</style>
```
[[Obsidian]]のModalクラスにて、[[Svelte]]のコンポーネントを自身のElementに付与。
```ts:SampleModal.ts
import { App, Modal } from "obsidian";
import Component from "./component/Component.svelte";
export class SampleModal extends Modal {
constructor(app: App) {
super(app);
const { contentEl } = this;
new Component({
target: contentEl,
props: {
count: 0,
onClickClose: (num: number) => {
console.log(num);
},
},
});
}
}
```
あとは普通にモーダルを表示させれば、モーダルの中で[[Svelte]]のコンポーネントが動く。
```ts
(new SampleModal(this.app)).open()
```
> [!error]- ビルドに失敗する場合
> 依存packageを最新化する。たとえば以下のエラーに遭遇した。
>
> ```console
> rollup v2.60.0
> bundles src/main.ts → ...
> (!) Plugin typescript: @rollup/plugin-typescript TS5023: Unknown compiler option 'preserveValueImports'.
> node_modules\@tsconfig\svelte\tsconfig.json: (18:5)
> [!] (plugin typescript) Error: @rollup/plugin-typescript: Couldn't process compiler options
> Error: @rollup/plugin-typescript: Couldn't process compiler options
> at error (C:\Users\tadashi-aikawa\git\github.com\tadashi-aikawa\obsidian-various-complements-plugin\node_modules\rollup\dist\shared\rollup.js:158:30)
> ```
>
> アップデート前後のバージョン以下。
> ```console
> @babel/core ^7.16.0 → ^7.17.8
> @babel/preset-env ^7.16.4 → ^7.16.11
> @babel/preset-typescript ^7.16.0 → ^7.16.7
> @rollup/plugin-commonjs ^15.1.0 → ^21.0.2
> @rollup/plugin-node-resolve ^9.0.0 → ^13.1.3
> @rollup/plugin-typescript ^6.0.0 → ^8.3.1
> @types/node ^14.14.2 → ^17.0.21
> babel-jest ^27.4.2 → ^27.5.1
> jest ^27.4.3 → ^27.5.1
> @types/jest ^27.0.3 → ^27.4.1
> obsidian ^0.13.11 → ^0.13.30
> prettier ^2.2.1 → ^2.6.0
> rollup ^2.32.1 → ^2.70.1
> tslib ^2.0.3 → ^2.3.1
> typescript ^4.0.3 → ^4.6.2
> ```
> [!error]- TS1371エラーになる
> [[📝Svelteを使ったプロジェクトでtypeやinterfaceをimportするとTS1371エラーになる]] を参照
> [!error]- [[Jest]]のテストコードで大量にエラーが出る
> [[Jest]]の型が認識されていないのが原因。[[tsconfig.json]]に[[types (tsconfig)|types]]を追加する。
>
> ```diff:tsconfig.json
> {
> "extends": "@tsconfig/svelte/tsconfig.json",
> "compilerOptions": {
> "strict": true,
> - "types": ["svelte", "node"],
> + "types": ["svelte", "node", "jest"],
> ```
>
## `CustomDictionaryWordRegisterModal`のUIを[[Svelte]]化
このダイアログの中身を[[Svelte]]で置き換える。
![[Pasted image 20220321174706.png]]
> [!todo]
> 移植する (2022-03-21)