2021-03-15
Prism.js の prism-php を利用した際に出るエラー `TypeError: Cannot read property 'tokenizePlaceholders' of undefined.` の解消方法
TL;DR
当ブログのシンタックスハイライトでもお世話になっている Prism.js で、PHP のシンタックスハイライトを利用しようとしたところエラーが発生したので対処方法をメモ。
prism-php
を読み込む前に prism-markup-templating
を読み込むと解消します。
バージョン
Prism.js ^1.23.0
エラー詳細
prism-php
を読み込んでシンタックスハイライト適用時、下記のエラーが発生する。(PHP 以外の言語は正常に動作する)
import Prism from 'prismjs';
import 'prismjs/components/prism-php';
const code = `echo "hello, world";`
const html = Prism.highlight(code, Prism.languages.php, 'php');
// TypeError: Cannot read property 'tokenizePlaceholders' of undefined
// あるいは
// TypeError: Cannot read property 'buildPlaceholders' of undefined
解決方法
prism-php
を読み込む前に prism-markup-templating
を読み込むようにすると、正常に動作します。
import Prism from 'prismjs';
import 'prismjs/components/prism-markup-templating';
import 'prismjs/components/prism-php';
原因は prism-php.js:L301-L312
の下記箇所です。しっかり他モジュールに依存していますね。
prism-php.js
(function (Prism) {
// 省略
Prism.hooks.add('before-tokenize', function(env) {
if (!/<\?/.test(env.code)) {
return;
}
var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*(?:[^*]|\*(?!\/))*(?:\*\/|$))*?(?:\?>|$)/ig;
Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern);
});
Prism.hooks.add('after-tokenize', function(env) {
Prism.languages['markup-templating'].tokenizePlaceholders(env, 'php');
});
}(Prism));
以上です