Svelteの根本部分を簡単に理解する

# 概要

Svelteには[svelte/template](https://github.com/sveltejs/template)の様にSvelteでのアプリ開発をすぐに始められる様なテンプレートや、より多くの機能を持った[Sveltekit](https://kit.svelte.dev/)の様な強力なフレームワーク(2022/3/10現在Beta)が既に存在しています。

しかし、この様なツールはとてもとても便利な一方、Svelteが結局何者なのかという根本的な部分を隠してしまう側面もあるかと感じています。

既にSvelteとは何か(Svelte=コンパイラ)説明する記事はたくさん存在するのですが、簡単なコードを使うことでより直感的に理解できると思い記事を書いてみました。

# 結局Svelteとは

上記でも記載したのですが、結論Svelteはコンパイラです。

:::note info
コンパイラとはプログラミング言語（高級言語）で書かれたコンピュータプログラムを、コンピュータが解釈・実行できる形式に一括して変換するソフトウェア。

[コンパイラ（compiler）とは - IT用語辞典 e-Words](https://e-words.jp/w/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9.html)
:::

Svelteの場合、Svelteの独自記法をブラウザの理解できる形(`Javascript`と`CSS`)に変換してくれます。

# コードで理解する

下記の様なJavaScriptファイルを作成します。(`npm`で`svelte`を既にインストール済みの想定)

```javascript:svelte-test.js
import * as svelteCompiler from 'svelte/compiler'

// (1) Svelteの独自記法
const SvelteComponent = `
<script>
  let text = "word";
</script>

<h1 class="greeting">Hello {text}</h1>

<style>
  .greeting {
    color: red;
  }
</style>
`

// (2) 独自記法をコンパイルする
const { js, css } = svelteCompiler.compile(SvelteComponent)

console.log(js.code)
console.log(css.code)
```

上記の簡単な`JavaScript`のコードを見て頂くとわかりますが、`(1)Svelteの独自記法`を`(2)コンパイルする`ことでブラウザの理解する事ができる`js`と`css`を返してきます。

### コンパイル後のコード

下記コードの中身を見てみるとそれぞれ普通の`css`と`JavaScript`である事がわかります。

<details><summary>css.codeの中身</summary><div>

```css
.greeting.svelte-9led3h {
color:red
}
```
</div></details>




<details><summary>js.codeの中身</summary><div>

```javascript
/* generated by Svelte v3.46.4 */
import {
	SvelteComponent,
	append_styles,
	attr,
	detach,
	element,
	init,
	insert,
	noop,
	safe_not_equal
} from "svelte/internal";

function add_css(target) {
	append_styles(target, "svelte-9led3h", ".greeting.svelte-9led3h{color:red}");
}

function create_fragment(ctx) {
	let h1;

	return {
		c() {
			h1 = element("h1");
			h1.textContent = `Hello ${textHello}`;
			attr(h1, "class", "greeting svelte-9led3h");
		},
		m(target, anchor) {
			insert(target, h1, anchor);
		},
		p: noop,
		i: noop,
		o: noop,
		d(detaching) {
			if (detaching) detach(h1);
		}
	};
}

let textHello = "word";

class Component extends SvelteComponent {
	constructor(options) {
		super();
		init(this, options, null, create_fragment, safe_not_equal, {}, add_css);
	}
}

export default Component;
```
</div></details>


これを単純に下記の様にする事で、`target`の箇所で期待した実装を表現してくれます。

```javascript
// Componentはの定義は上のjs.codeの中身を参照
const component = new Component({
	target: document.querySelector('#test'),
	props: {
		greeting: 'world'
	}
});
```

### 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258219/62f97a58-bc96-1227-405d-59172d87eb18.png)


### その他

- `compile`時のいろいろなオプションは[こちら](https://svelte.dev/docs#compile-time-svelte-compile)を参照してください
- compile時の挙動や使用するParserに関しては[こちらの記事](https://dev.to/joshnuss/svelte-compiler-under-the-hood-4j20)がわかり易く説明してくれていました。それ以上理解をする場合は実際のcompiler配下の[ソースコード](https://github.com/sveltejs/svelte/tree/master/src/compiler)を追うのが良いかと思います。
- `js.code`中で使用されている`SvelteComponent`やその他のinternal関数・オブジェクトは[こちら](https://github.com/sveltejs/svelte/tree/master/src/runtime/internal)から実際の実装を追う事ができます。

※ コード中のコメントにも記載されていますがinternal配下のコードはいつでも変わる可能性があります。

# 参考資料

- [The easiest way to get started with Svelte](https://svelte.dev/blog/the-easiest-way-to-get-started): 公式のブログで紹介されている最速でSvelteで開発を始める方法
- [Svelte Document](https://svelte.dev/docs): 公式のドキュメント
- [Svelte Turtorial](https://svelte.dev/tutorial/basics): 公式のチュートリアル
- [Sveltekit](https://kit.svelte.dev/): Svelteのフレームワーク