register_block_type() と wp-scripts を使おう

この記事は Snow Monkey アドベントカレンダー 2019 12日目の記事です。

先日、Snow Monkey Blocks で大幅なリファクタリングをおこないました。

やったことは主に2つあります。

  • 全てのブロックで register_block_type() を使うように変更
  • ビルドに wp-scripts を使うように変更

全てのブロックで register_block_type() を使うように変更

Snow Monkey Blocks は全部で30個以上のブロックを持っています。これまでそれらのブロックを定義した JavaScript ファイルは、1つのファイルに結合し、wp_enqueue_script() でそのファイルを読み込むという流れで読み込みをおこなっていました。

特にその方法でも問題なく動作はするのですが、Gutenberg Freaks のオンラインミートアップで Gutenberg Handbook を読んだときに、カスタムブロックの登録には register_block_type() を使いましょうと書いてあることに気づきました。

具体的には、各ブロックごとに「エディター用の script」「エディター用の style」「フロント&エディター用の script」「フロント&エディター用の style」の各ファイルを wp_register_script()wp_register_style() で準備しておき、それらを register_block_type() 経由で読み込ませるという流れになります。

サンプルコードは以下。

add_action(
	'init',
 	function() {
		wp_register_script( 'ハンドル名', ... );
		~省略〜
		wp_register_style( 'ハンドル名', ... );

		register_block_type(
			'plugin/block',
			[
				'editor_script' => 'エディター用 script のハンドル名',
				'editor_style'  => 'エディター用 style のハンドル名',
				'script'        => 'フロント&エディター用 script のハンドル名',
				'style'         => 'フロント&エディター用 style のハンドル名',
			]
		);
	}
);

ハンドブック的には一応これが正しいカスタムブロックの登録方法になるようです。

ちなみに、WordPress 公式ディレクトリにカスタムブロックを含むプラグインを掲載すると、そのプラグインのページに「このプラグインは○個のブロックを提供します。」という表示がでるようになっています。1ファイルに結合して読み込ませる方法だとここの表示がおかしなことになるので、register_block_type() で登録するようにしたほうが良いのかなと思います。

また、今後、プラグインディレクトリと同じようにブロックディレクトリなるものも用意されるように話が進んでいるそうです。そうなったときはおそらく各ブロックごとにブロックディレクトリに登録するようになると思うので(完全に予想)、いまのうちから register_block_type() を使う形にして慣れておいたほうが良いのではと思います。

ビルドに wp-scripts を使うように変更

これまで Snow Monkey Blocks では、JavaScript のビルドを Webpack + Babel でおこなっていました。これもちゃんと環境を整えれば普通にビルドできるのですが、Gutenberg ハンドブックには @wordpress/scripts というライブラリを使ってビルドする例が掲載されています。

@wordpress/scripts に含まれる wp-scripts というコマンドで JavaScript のビルドすることができます。複雑な Webpack や Babel の設定ファイルを一切用意することなく、ただ @wordpress/scripts を npm install して wp-scripts コマンドを叩くだけで良いのです!カスタムブロックを初めてつくろうとするときに一番の障壁になるのが JavaScript のビルド環境の構築だと思うので、wp-scripts はその問題を一気に解決してくれます。

ということでサンプルは以下。npm scripts として利用します。

{
  "scripts": {
    "build:accordion": "wp-scripts build block/accordion/editor --output-path=dist/block/accordion"
  }
}

上記は block/accordion/editor.js をビルドして dist/block/accordion/editor.js に書き出すというコマンドになります。

このとき、dist/block/accordion には editor.asset.php という、{ファイル名}.asset.php な PHP ファイルも書き出されます。カスタムブロックのエディター用 script を読み込むときは、その script 内で使っているブロックエディター用の script(例えば Rich Text Component の script とか)より後に読み込む必要があるため、wp_register_script() の引数で dependencies を指定することで読み込む順序を制御しなければなりません。

例えばこんな感じ。

wp_register_script(
	'ハンドル名',
	'ファイルパス',
	[ 'wp-element', 'wp-polyfill' ] // ここで依存関係を指定
);

で、この依存関係はそのカスタムブロックが何に依存するかによって変わってくるので、なかなか指定がめんどくさいわけです。それが {ファイル名}.asset.php で解決できるのです。 {ファイル名}.asset.php にはそのカスタムブロックが依存するライブラリのハンドル名が自動的に書き出されるので、このファイルを include() するだけで依存関係が解決できます。

$asset = include( '/PATH/TO/{ファイル名}.asset.php' );
wp_register_script(
	'ハンドル名',
	'ファイルパス',
	$asset['dependencies']
);

おまけ:JavaScript の lint も wp-scripts でできる

下記のコマンドで、指定したディレクトリ名の JavaScript ファイルが正しい構文で書かれているかをチェックしてくれます。

wp-scripts lint-js ディレクトリ名

これもビルドと同じで本来ならややこしい設定ファイルを用意しなければならないのですが、wp-scripts ではそのような設定ファイルは不要です。すばらしい!

ちなみに、Snow Monkey Blocks では設定ファイル .eslintrc.js を用意しています…。globals に一個キーを足したかったのですが、うまい方法がわからず、wp-scripts の中に含まれる .eslintrc.js をコピーしてきて globals を追記し、Snow Monkey Blocks のルートに配置しました(ルートに設定ファイルがあるとそれが優先的に利用されます)。

module.exports = {
	root: true,
	extends: [
		'plugin:@wordpress/eslint-plugin/recommended',

		// Temporary workaround to use linting rules for both e2e and unit tests with all files
		// until override files globbing logic is fixed when using with --config.
		// @see https://github.com/eslint/eslint/issues/11558
		'plugin:@wordpress/eslint-plugin/test-e2e',
		'plugin:@wordpress/eslint-plugin/test-unit',
	],
	globals: {
		smb: true,
	},
};

この場合、もし @wordpress/scripts のアップデートで extends が更新されてしまったら、僕がコピーしたファイルにも手動で反映しなければいけないため、良い方法とはいえません。もし良い解決策をご存じの方がいらっしゃればぜひ教えてください!


Snow Monkey アドベントカレンダー 2019、まだまだ空きがありますのでぜひお気軽にご参加どうぞ!(すでに僕はネタ切れであります!

この記事を書いた人

キタジマ タカシ

長崎県長崎市在住。地元のWeb制作会社でWebデザイナー/エンジニアとして従事した後、2015年にフリーランス [ モンキーレンチ ] として独立。WordPress のテーマやプラグイン、ライブラリ、CSS フレームワーク等、多数のプロダクトをオープンソースで開発・公開しています。

Snow Monkey オンラインコミュニティ

Snow Monkey をより良いテーマにするために、今後の機能開発等について情報共有したりディスカッションをしたりする場所です。より多くのユーザーの交流があったほうがより良いプロダクトに育っていくと思いますので、ぜひご参加ください!