Gutenberg のカスタムブロックでも、ES Modules import を使う。

要は、どうしたいかというと、

const { registerBlockType } = wp.blocks;

これを、Gutenberg のコアのソースコードのように、

import { registerBlockType } form '@wordpress/blocks'

としたいと言うことです。

やりかた

webpack.config.js を の externals を良い感じに設定すればできます。Gunteberg 本体も似たようなコトをやっています。

const entryPointNames = [
	'blocks',
	'components',
	'editor',
	'utils',
	'viewport',
	'edit-post',
	'core-blocks',
	'nux',
];

const gutenbergPackages = [
	'api-request',
	'blob',
	'core-data',
	'data',
	'date',
	'deprecated',
	'dom',
	'element',
	'keycodes',
	'plugins',
	'shortcode',
];

const wordPressPackages = [
	'a11y',
	'dom-ready',
	'hooks',
	'i18n',
	'is-shallow-equal',
];

const externals = {
	react: 'React',
	'react-dom': 'ReactDOM',
	tinymce: 'tinymce',
	moment: 'moment',
	jquery: 'jQuery',
	lodash: 'lodash',
	'lodash-es': 'lodash'
};

[
	...entryPointNames,
	...gutenbergPackages,
	...wordPressPackages,
].forEach( ( name ) => {
	externals[`@wordpress/${ name }`] = {
		window: ['wp', name],
	};
} );

module.exports = {
	output: {
		library: ['wp', '[name]'],
		libraryTarget: 'window',
	},
	mode: 'production',
	module: {
		rules: [
			{
				test: /\.js$/,
				exclude: /node_modules/,
				use: {
					loader: 'babel-loader',
					options: {
						presets: ['@babel/preset-env']
					}
				}
			}
		]
	},
	devtool: 'source-map',
	externals,
	resolve: {
		extensions: ['.js', '.jsx']
	}
};

こんな感じの config を書いてます。externals の 設定を行えば、@wordpress/{packageName} みたいなので、import の解決が出来ます。output の設定も書かないとうまいこと動きません。ここでちょっとつまづきました。

メリット

  • コアのソースをコピペするときに、import とかを書き換えなくて済む。
  • npm で、@wordpress/editor 等を devDependencies で入れておけば、PHPStorm 等でコードジャンプが容易に出来る。
  • ちょっとカッコいい。

addFilter 等もあるため、コアのソースを読みたいという瞬間はかなり多いです。ですので、コードジャンプが行えるのは大きな利点なのかなとおもいます。