この記事はIonic Framework / Capacitor / Stencil Advent Calendar 2020 20日目の記事です。
stencilはUIフレームのionicで利用されているWeb Componentをビルドするフレームワークです。
stencilの特徴はVue,Angular,ReactといったJavascriptフレーワークにも依存せずにScopedなComponentを開発できる点にあります。
またstencilでビルドされたJSを読み込むだけで使えるので、複数の異なったドメインにも共有することできます。
※npm
での提供もできます。
stencilの始め方
npm init stencil
を実行するだけで始められます。
stencil-component-starterといったスターターキットも用意されており、これを利用すると開発、テスト、ビルドがフォローされているので、すぐにstencilの気持ち良い開発環境が手にはいります。
stencilはTypeScriptに対応しており、当然このリポジトリもtypeScriptで開発できます。
コードの解説
私は当時stencilを触るのは初めてで、どう使うものなのかよくわかっていなかったので自分がコードを読んでして気がついたこと、調べたことを共有します。
npm run start
をするとsyncとbuildが走り、WebComponentのファイルも生成されます。
buildされたファイルは下記のファイルから読まれており、my-component
のComponentが利用できるようになります。
<script type="module" src="/build/stencil-starter-project-name.esm.js"></script>
<script nomodule src="/build/stencil-starter-project-name.js"></script>
stencilはshadowDomでもLightDomでもどちらのComponentでも作成できます。
切り替え方法もとても簡単でshadow
をtrue
,false
を切り替えるだけです。
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true,
})
Propsを受け取ることも可能です。
下記のように @Prop()
name:type;
を書くだけでstateを持てるのでComponent内で利用でき取り回しがしやすいです。
@Prop() first: string;
scssを使いたい場合
先程紹介したリポジトリではcssを読んでいるだけなので、scssは使えません。
scssを利用するためには、stencil-sassを利用します。
npm install @stencil/sass --save-dev
をしてから、stencil.config.ts
に記載するだけなので簡単にscssを使用できる環境が作れます。
import { Config } from '@stencil/core';
import { sass } from '@stencil/sass';
export const config: Config = {
plugins: [
sass()
]
};
storybookを利用する
stencilでいくら簡単に利用できるようにしても、Web Componentを作っただけではなかなか開発者以外の方に使ってもらうのは難しいです。
そこで他のComponent同様にstorybookを使うとpropsや見た目がわかりやすくなり利用者が増やしやすくなります。
storybookの利用は特別なやり方があるわけではなくnpm install --save-dev @storybook/html babel-loader @babel/core
を実行して、ディレクトリやファイルを設置するだけです。
storybookで外部ファイルを読み込むpreview-head.html
では、下記のようなpathでstencilで作成したComponentのjsを読み込めます。
<script type="module" src="./stencil-starter-project-name/stencil-starter-project-name.esm.js"></script>
<script nomodule src="./stencil-starter-project-name/stencil-starter-project-name.js"></script>
readmeの自動生成
めちゃくちゃ感動したのですが、stencilではComponent毎のreadmeがnpm run build
で自動生成されます。
これをstorybookの@storybook/addon-notes
と組み合わせるとプロパティもstorybookで確認できるようになりより大勢の方との開発がしやすくなります。
もう少し便利にstencilを始める
上記で紹介したstencil-component-starterをforkして、scss,storybookなどを使用できるリポジトリを作成しています。
github:contiki9/stencil-component-starter
github-pagesでstorybookも公開できるようになっています。
stencilの良さ、WebComponentの使いやすさがすぐに体感できると思います。
stencilが解決すること
実はstencilは以前から知っていたのですが、ReactでComponentとか作ったほうがいいじゃんと半ば無視をしていたのですが、phpで動いてる環境とvue.jsで作られたページが入り乱れたプロジェクトがあり、その両方にUI Componentを提供する必要がありその方法を模索してる中でstencilのことを思い出しました。
stencilに目をつけたのはShadowDomが簡単に作れるところで、Globalに存在するCSSの影響を受けずにUIを作れるので見た目が崩れないと保証された点です。
またカラーなどもプロパティで定義したものしか受け付けないのでUIにルールを適応してほか開発者に提供できるので、知らないところでUIがレイプされたといった事件を未然に防ぐことができます。
今後stencilでComponentを作るべきだなどとは思っていないのですが、長期運用やほかブランドにも展開可能なデザインシステムを作る場合は十分に選択肢に挙げられると考えています。
ルールが定義されたComponentが広域に展開されると大規模な開発や複数プロジェクトがあるとよく起こりがちなUIに関しての捉え方が変わってしまう問題が起こるのですが、利用方法を物理的に制限してしまえるshadowDomを使うことで「そんなルールでやってるなんて知らなかった」といったすれ違いコミュケーションを避けやすくなります。
毎度おなじみ、「銀の銃弾」にstencilがなるわけではないですがWeb Componentで開発することで得られる恩恵はありそうです。
最後に
どいうった粒度でUI Componentを作るのが良いかでstencilを使うメリットは変わってきます。
なんでもstencilに依存して作ってしまうとすぐに使いにくい限定的なComponentが量産されて保守もメンテもされなくなる誰も得をしない世界が起きてしまうでしょう。
Atomic Designから離れたComponent設計が必要になりますがデザインシステムを構築するにあたってstencilは「ちょうどいい」ライブラリになってくれると期待しています。
デザインシステムを構築するにあたっての考えはまた別の機会に記事にしたいと思います。