yasudacloudの日記

札幌に住むソフトウェアエンジニア

Strapiのプラグインシステムについて

Strapiのプラグインシステムは良く出来ています。

先日、予告されていたマーケットプレイスが公開されたこともあり自分の知見をアウトプットしていきたいと思います。

 

プラグインの読み込み

まず、プラグインの読み込みはnpm or yarnでインストールする方法とsrc/pluginsに置く方法があります。

npmはそのままで、npmに公開されているプラグインをインストールするだけで完了です。

 

src/pluginsに配置する方式は主に自分でプラグインを開発する場合に行われます。

例えば `yarn strapi generate`を実行してプラグインを作成するとsrc/pluginsに雛形が出来上がります。他のユースケースとして、他の人が作ったプラグインをcloneして手を加える場合にも利用できそうです。

 

プラグインの設定値

プラグインの設定は前述のどちらの場合であってもconfig/plugins.js で設定を行います。

src/pluginsにパッケージがある場合は

module.exports = {
'プラグイン': {
resolve: './src/plugins/プラグイン',
enabled: true
}
}
というようにresolveでプラグインの場所を明示する必要があります。プラグインが設定値を求めている場合はこちらにconfig: { キー名: 値 } を追記します。プラグインでデフォルト値が設定されていてもこっちが上書きされます。

 

また、プラグイン側から設定値を取得するには

strapi.config.get('プラグイン名')

で読み取ることが可能です。

 

設定値を環境毎に切りたい場合、config/plugins.jsにprocess.envで値を読み込むか、プロジェクト側から`config/env/{環境名}/plugins.js`のようにファイル毎切り替える方法があります。

個人的にはプラグイン内で直接環境変数を参照するのは避けた方が良いと思います。

 

プラグインの構成

肝心の中身に触れていきます。

generateコマンドで作成すると./adminと./serverの大きく2つに分かれます。

adminは管理画面のUI部分、serverは主にバックエンドの実装になります。

 

まず、adminの方ですが画面はReactの実装になります。

Reactに関連しますが、axiosやstyled-components、react-intlやreact-helmet、react-router-domなどなどReact使いには嬉しいライブラリが標準で使えます。

react-router-domはプラグイン名がルートになるため、http://localhost:1337/hoge のように自由なパスで画面を作れるわけではないことに注意です。

 

バージョン4の場合、公式のデザインガイドがあるためこちらを参考にすると良いです。

design-system.strapi.io

ただしコードレベルでは情報が少なめなので、標準搭載のプラグインのUIを真似ようと思ったら結局node_modulesを漁るのが早かったりします。。

 

画面以外の話では他言語化の仕組みもadminに入っています。

公式によるとプラグインマーケットプレイスに公開する場合は英語は必須のようなので英語をデフォルトにして日本語をJSONで作っていくのがおすすめです。

 

次にserverについて。

serverの方は出来ることが多く、自分も全てを把握出来ていません。

先程の流れで話していくと、adminで作った画面から呼び出し可能なAPIを作ることができます。

この時に必要な最低限のレイヤーはadmin/index.js、admin/routes、admin/controllersです。Web FW経験者なら直感的に分かると思うので詳細は省略します。

 

他にはcontent-typesが自動生成されているかと思います。例えばプラグインで独自のコレクションタイプやシングルタイプを作成することができます。

middlewareもWeb FWではお馴染みの機能で、リクエストの前後に処理を加えることができます。

 

他には、プラグインのライフサイクルにregister/destroyがあります。

こちらはおそらくプラグインが有効化/無効化した時に呼び出される仕組みだと思いますが、具体的にどういうタイミングでコールされるのか検証ができていません。

 

docs.strapi.io

 

他にも各レイヤーのcreateCoreService、createCoreController、createCoreRouterなど便利関数があるのですが長くなったのでこのへんで。