2026年7月9日

2026年7月9日

npm workspacesでWordPressのブロックプラグインと共通コードをモノレポ管理する手順

npm workspaces は、1つのリポジトリの中にある複数の npm パッケージを、ルートの package.json からまとめて管理する npm の機能です(npm 7 以降)。WordPress の開発では、次のような場面で役に立ちます。

  • 複数のブロックプラグインで、同じ JavaScript の関数や部品を使い回したい
  • 依存パッケージのインストールとロックファイルを1か所にまとめたい
  • すべてのプラグインを1つのコマンドでビルドしたい

この記事では、共通コード用のパッケージ1つと、それを使うブロックプラグイン1つを作り、@wordpress/scripts でビルドして配布用の ZIP を作るところまでを説明します。コマンドは Node.js 22(npm 10)の Docker コンテナで実行して確かめています(2026年11月時点)。

作る構成

my-wp-monorepo/
├── package.json          ← ルート(workspaces を定義)
├── package-lock.json     ← ロックファイルはルートに1つ
├── node_modules/         ← 依存パッケージはここにまとめて入る
├── packages/
│   └── shared/           ← 共通コード(@myorg/shared)
│       ├── package.json
│       └── index.js
└── plugins/
    └── my-block/         ← ブロックプラグイン(my-block)
        ├── package.json
        ├── my-block.php
        └── src/
            ├── block.json
            └── index.js

前提

  • Node.js と npm が入っていること。@wordpress/scripts は版ごとに対応する Node.js が決まっています。2026年11月時点の 37.1.0 は、Node.js 22.22.2 以上(22 系)、24.15.0 以上(24 系)、26 以上が対象です。
  • ビルドしたプラグインを試す WordPress 環境があること。この記事のブロックは apiVersion 3 で書くので、WordPress 6.3 以降が対象です。
node -v
npm -v

ステップ1:ルートを作り、workspaces を定義する

mkdir my-wp-monorepo && cd my-wp-monorepo
npm init -y
npm pkg set private=true --json
npm pkg set 'workspaces[0]=packages/*' 'workspaces[1]=plugins/*'

ルートの package.json は次のようになります(npm init が入れる項目の一部は省略)。

{
  "name": "my-wp-monorepo",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "packages/*",
    "plugins/*"
  ]
}

"private": true にしておくと、ルートのパッケージを誤って npm に公開することを防げます。workspaces には、ワークスペースとして扱うフォルダーをパターンで書きます。テーマも同じリポジトリで管理するなら themes/* を加えます。

ステップ2:ワークスペースを作る

npm init に -w(--workspace)を付けると、そのフォルダーに package.json を作り、ワークスペースとして登録します。

# 共通コード。名前を @myorg/shared にする
npm init -y -w packages/shared --scope=@myorg

# ブロックプラグイン。名前はプラグインのフォルダー名と同じ my-block にする
npm init -y -w plugins/my-block

# 共通コードを ES モジュールとして書く
npm pkg set type=module -w packages/shared

# npm init が入れる test スクリプトは使わないので消す
npm pkg delete scripts.test -w packages/shared -w plugins/my-block

プラグインのパッケージ名に @myorg/ のようなスコープを付けないのには理由があります。後で使う wp-scripts plugin-zip は、パッケージ名から ZIP の名前とメインの PHP ファイル名(my-block.php)を決めます。スコープ付きの名前にすると、メインの PHP ファイルが ZIP に入りませんでした。プラグインはパッケージ名=フォルダー名=メインファイル名にそろえておくと扱いやすくなります。

共通コードを書きます。packages/shared/index.js:

export function formatPrice( value ) {
	return value.toLocaleString( 'ja-JP' ) + '円';
}

ステップ3:プラグインから共通コードを参照する

ワークスペースの名前を指定して npm install すると、npm はレジストリではなくリポジトリ内のパッケージを使います。

# my-block の dependencies に @myorg/shared を加える
npm install @myorg/shared -w plugins/my-block

# ビルドツールを my-block の devDependencies に加える
npm install @wordpress/scripts --save-dev -w plugins/my-block

plugins/my-block/package.json の dependencies には "@myorg/shared": "^1.0.0" が入り、ルートの node_modules/@myorg/shared は packages/shared へのシンボリックリンクになります。共通コードを書き換えると、インストールし直さなくてもプラグイン側にすぐ反映されます。

@wordpress/scripts などの依存パッケージは、原則としてルートの node_modules にまとめて入ります。ワークスペースごとに別の版が必要な場合だけ、そのワークスペースの中に入ります。

プラグイン側にビルド用のスクリプトを登録します。

npm pkg set scripts.build="wp-scripts build" scripts.start="wp-scripts start" scripts.plugin-zip="wp-scripts plugin-zip" -w plugins/my-block

ステップ4:ブロックプラグインのファイルを用意する

plugins/my-block/src/block.json:

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "myorg/price",
	"title": "Price",
	"category": "widgets",
	"editorScript": "file:./index.js"
}

plugins/my-block/src/index.js:

import { registerBlockType } from '@wordpress/blocks';
import { formatPrice } from '@myorg/shared';
import metadata from './block.json';

registerBlockType( metadata.name, {
	edit: () => <p>{ formatPrice( 1980 ) }</p>,
	save: () => <p>{ formatPrice( 1980 ) }</p>,
} );

@wordpress/blocks はインストールしていませんが、wp-scripts build が WordPress 本体の wp-blocks スクリプトを使うように変換するので、このままビルドできます。

plugins/my-block/my-block.php(プラグインのメインファイル):

<?php
/**
 * Plugin Name: My Block
 * Description: npm workspaces で管理しているブロックのサンプル。
 * Version:     1.0.0
 * Requires at least: 6.5
 * Text Domain: my-block
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

add_action( 'init', function () {
	register_block_type( __DIR__ . '/build' );
} );

ステップ5:ビルドする

# 1つのワークスペースだけビルドする(名前でもパスでも指定できる)
npm run build -w my-block

# すべてのワークスペースで build を実行する(build が無いものは飛ばす)
npm run build --workspaces --if-present

ビルドすると plugins/my-block/build/ に次のファイルができます。

ファイル 内容
index.js src/index.js と、使っている共通コード(formatPrice)をまとめたもの
index.asset.php 依存するスクリプト(wp-blocks など)とキャッシュ用の版を返す PHP
block.json src/block.json のコピー。register_block_type() が読む

開発中は npm run start -w my-block で、ファイルを保存するたびに再ビルドされます。

ルートの package.json にまとめ用のスクリプトを置いておくと、ルートで npm run build と打つだけで済みます。

npm pkg set scripts.build="npm run build --workspaces --if-present"

依存関係がつながっているかは npm ls で確認できます。

$ npm ls @myorg/shared
my-wp-monorepo@1.0.0 /work/my-wp-monorepo
+-- @myorg/shared@1.0.0 -> ./packages/shared
`-- my-block@1.0.0 -> ./plugins/my-block
  `-- @myorg/shared@1.0.0 deduped -> ./packages/shared

ステップ6:配布用の ZIP を作る

npm run plugin-zip -w my-block

plugins/my-block/my-block.zip ができ、中身は my-block/my-block.php と my-block/build/ の3ファイルです。共通コードは build/index.js にまとめて入っているので、WordPress に入れるプラグインに node_modules やモノレポの他のフォルダーは要りません。

ZIP に入れるファイルを自分で決めたい場合は、プラグインの package.json に files を書きます(例: "files": ["build", "my-block.php", "readme.txt"])。

手元の WordPress で試すときは、plugins/my-block フォルダーを WordPress の wp-content/plugins/ に置くか、シンボリックリンクを張ってから、管理画面でプラグインを有効化します。

運用のポイント

  • ロックファイルはルートに1つ。 package-lock.json はルートにだけ作られます。リポジトリにはこれをコミットし、CI ではルートで npm ci を実行すると、すべてのワークスペースの依存パッケージが入ります。
  • 依存パッケージの追加は -w を付けてルートで行う。 どのワークスペースに何を入れたかがコマンドに残り、手順書や CI にもそのまま書けます。
  • 共通コードの変更はすべてのプラグインに影響する。 共通パッケージを変えたら、npm run build --workspaces --if-present で全プラグインをビルドし直して確認します。
  • ビルド結果をコミットするかを決めておく。 build/ をリポジトリに含めない場合は、デプロイの手順でビルドしてから ZIP を作ります。

ブロック開発そのものの始め方は create-blockでブロックの雛形を作る も参考にしてください。

まとめ

  • ルートの package.json に "private": true と workspaces を書き、npm init -w でワークスペースを作る
  • npm install @myorg/shared -w plugins/my-block で、リポジトリ内の共通パッケージをシンボリックリンクとして参照できる
  • @wordpress/scripts の build で共通コードがプラグインの build/index.js にまとめられる
  • 全体のビルドは npm run build --workspaces --if-present、配布は npm run plugin-zip -w my-block
  • プラグインのパッケージ名はスコープを付けず、フォルダー名とメインファイル名にそろえる

お気軽にご相談ください

お見積りへ お問い合わせへ
▲