こんにちは。PR TIMESでフロントエンドエンジニアをしている夛田(@unachang113)です。
PR TIMESではプレスリリース配信のエディターにTiptapというヘッドレスエディターフレームワークを使用しています。
2025年2月にTiptapのバージョンをv2.0.0-betaからv2.10.5まで上げ、3月に最新版までバージョンアップを実施したことを今回は話そうと思います。
Tiptapのバージョンアップが滞っていた要因
弊社では月に1回リファクタリングデーを実施していて、リファクタリングデーのタイミングでrenovateを使い依存しているパッケージのバージョンアップを実施しています。

しかし、Tiptapに関しては2年近くの間バージョンアップが行われていない状態でした。
要因としては以下です。
- 2023年12月にUIを刷新したエディター(以下、新エディター)のリリースが行われた後、元々提供していたエディター(以下、旧エディター)と新エディターの並行運用期間があったため、Tiptapのバージョンアップを実施する際に旧エディターと新エディターの両方の動作を確認する必要があったこと
- エディターが動かなくなるとPR TIMES上でプレスリリースの配信ができなくなるため不具合なくバージョンアップを遂行する必要があったこと
1番目のストップ要因となっている旧エディターに関しては自動テストがほぼない状態だったため、もしバージョンアップ起因の問題がないかを確認する際に手動テストを実施するしかない状態だったことや、仮に不具合があった場合既に廃止が決まっている旧エディターに新たに大きな改修を行うことは今後の運用期間に対して修正ボリュームが大きく、開発のコストが見合わないため、新エディターに1本化されるまではTiptapのバージョンアップをストップせざるを得ない状況になっていました。
旧エディターの廃止によりTiptapバージョンアップチャンスが到来
2024年の秋頃、2024年12月に旧エディターが廃止され、新エディターに1本化されることが決まりました。
旧エディターが廃止されれば新旧2つのエディターをメンテナンスする必要がなくなるため、修正コストは確実に減ります。
あとは要因の2番目にあげた不具合を起こさず安全にバージョンアップが実施できるかどうかが肝になってきました。
旧エディターを廃止した話は本筋から外れるのでこのブログでは話しませんが、社内ラジオのHAPPR RADIOで経緯を話しているので興味がある方は聞いてみてください。
とりあえず開発環境でバージョンを上げてみる
開発環境でひとまずv2.0.0betaから2024年11月当時の最新だったv2.10.5までバージョンアップを実施してみることにしました。バージョンアップの際に修正した箇所がいくつかあったので紹介しようと思います。
バージョンアップ時に修正した内容
1. LinkExtensionの型エラーの修正
PR TIMESではTiptapで提供されているLinkExtensionを拡張する形で独自のLinkExtensionを作成しています。
v2.0.0-betaでは拡張機能にOptionを渡す際、addOption() の中に必要なOptionを記載して渡していましたが、新しいバージョンではaddOptionで指定していたparamsをExtensionの引数としてそのまま渡す形に変更されていたため、型エラーになっていました。
そのため、以下のように修正を行っています。
before
import {Link, type LinkOptions} from '@tiptap/extension-link';
export type PressReleaseLinkOptions = {
'data-link-id'?: string;
} & LinkOptions;
export const LinkExtension = Link.extend<PressReleaseLinkOptions>({
...
addOptions() {
return {
openOnClick: false,
linkOnPaste: false,
autolink: false,
protocols: [],
// eslint-disable-next-line @typescript-eslint/naming-convention
HTMLAttributes: {
target: '_blank',
rel: 'nofollow ugc noopener',
class: 'pr-link',
},
};
},
});after
import {Link, type LinkOptions} from '@tiptap/extension-link';
export type PressReleaseLinkOptions = {
'data-link-id'?: string;
} & LinkOptions;
export const LinkExtension = Link.extend<PressReleaseLinkOptions>({
...
autolink: false,
openOnClick: false,
linkOnPaste: false,
protocols: [],
HTMLAttributes: {
target: '_blank',
rel: 'nofollow ugc noopener',
class: 'pr-link',
},
});また余談ですが、Tiptapで提供している拡張機能のカスタマイズの方法は上記のようにExtensionをメソッドに切り出して.extendというAPIを用いて新しい拡張機能を作成する方法とuseEditorというEditor用のインスタンスを作成するためのカスタムフック内でconfigureというメソッドを用いてoptionを渡して既存の拡張の設定を上書きする方法があります。
const editor = useEditor({
editable: true,
extensions: [
Link.configure({
openOnClick: false,
linkOnPaste: false,
})
],
...
});configure での指定と.extendでの仕様の違いをイマイチ理解しておらず、型エラーの修正にハマり、TiptapのIssueでバグではないかと起票したところ、そもそもAPIの機能が異なっていることを教えてもらいました(ありがとうございました)。
2. NodeViewのアウトラインの修正
これまではNodeViewのアウトラインの有無をPropsのselected がtrueになっているかどうかで判定をしていました。
import {type NodeViewProps, NodeViewWrapper} from '@tiptap/react';
export function NodeViewSample(props: NodeViewProps) {
const {selected, node} = props;
return (
<NodeViewWrapper
className='pr-sample-extension'
{/* selectedの値を見てoutline用のclassを付与していた */}
className={selected && styles.selected}
as='div'
data-url={url}
>
<img src={src} width={200} height={200} alt='' />
</NodeViewWrapper>
);
)
}ただ、TiptapのバージョンアップでNodeを選択した際に.Prosemirror-selectednode というclassが付与されるようになった事により、アウトラインが二重で表示される事象が発生していました。

解消法としてはNodeのselectedを使っての判定をやめ、.Prosemirror-selectednodeがnodeViewのHTMLにあるかどうかでoutlineの有無の設定を行うように修正しました。
安全にバージョンアップを実施するためのテストを実施
修正対応を完了することができたので、あとは不具合がないかを確認するためにテストを実施するのみとなりました。
新エディターの自動テストは旧エディターよりテストケースの数が増え拡充を行いましたが、網羅的には書けていませんでした。また、自由入力のエディターはそもそもすべての入力ケースを自動テストで担保することは難しく、CIでPlaywrightやvitestのテストが通ったからヨシ!!!と手放しで言える状況ではありませんでした。
そこで、チーム内で相談し以下の様に手動テストでの確認を進めることにしました。
- アドホックテストの実施
- システムテストの実施
- リファクタリングデーでのQAチェック
1. アドホックテストの実施
アドホックテストとは、事前にテストケースや手順を決めずに、場当たり的にソフトウェアやシステムのテストを行う手法です。
エディターはパターンや操作パターンが多い事から過去にシステムテストを実施した際にエンジニアのデバッグで漏れていたバグチケットが大量に起票されることが多かったため、最初にアドホックテストをしてそこで出た不具合を潰してからシステムテストに入ることにしました。
実施方法としてはエディターチームのエンジニア全員が1日かけてエディターを触って、不具合を見つけたらスプレッドシートに起票→その後PdMと相談して優先度付けをしてJiraに起票する形で行っていきました。

2. システムテストの実施
入力ケースが多いエディターにおいて1からテストケースを作成していくのは大変骨が折れる作業となります。ただ、新エディターのリリースや旧エディターの廃止、各種機能追加時に作成した過去にテストケースが資産として残っている状態でした。
上述したテストケースと過去のシステムテストで起票されたバグチケットをQAエンジニアが確認し、今回のエディターのバージョンアップ用にピックアップする形でテストケースを作成し、自分とQAエンジニアの2人で確認の対応を進めていきました。
結果としてはアドホックテストである程度不具合は潰せている状態だったため、バージョンアップ起因の不具合は0でシステムテストを終えることができました。
3. リファクタリングデーでのQAチェック
Tiptapのバージョンアップが滞っていた要因の項でも触れましたが、PR TIMESでは月に1度リファクタリングデーを実施しています。リファクタリングデーは2日間実施され、1日目は実装、2日目はリリースする予定の内容にバグが含まれていないか確認するための結合テスト・QAが行われます。
アドホック・システムテストを経て動作に問題ないことは確認できていましたが、念には念をということでリリースのタイミングをリファクタリングデーにしてリファクタリングデーのQAも通し、なるべく多くの人の目を通した状態でリリースする作戦をとりました。
結果
2月のリリース後、バージョンアップ起因の不具合は発生せずエディターの稼働を継続することができました。また3月にはリファクタリングデーでrenovateを用いたマイナーバージョンアップも実施し、その後も継続的にバージョンアップを行うことができています。
今後の展望
2025月5月現在、TiptapはV3のβ版がリリースされ2025年後半にリリースが予定されています。
V3がリリースされる前に安全にインシデント無くV2の最新にバージョンアップできた経験は今後V3のアップデートを実施する際にも負担が小さく行うことができる可能性があがるし、今回のバージョンアップの知見を活かしてV3も安全にバージョンを実施できたら良いなと思っています。
We are hiring!
一緒にPR TIMESの開発を担ってくれるエンジニアはもちろん、各種ポジションで採用を行っています!

