こんにちは。
最近、CMSのプラグインの設定ファイルのJavaScriptを作成する際、JSファイルと同階層にtxtファイルを設置してその内容を読み込みたいケースがありました。
具体的には、膨大な文字数となるデータやプロパティをJSで読み込む必要があって別ファイルに格納し、かつ元のHTML構造を大きく変えられないケースです。
そういった際にtxtファイルに格納されたテキストをJSで読み込む記述について、備忘録代わりに書いていこうと思います。
フォルダ構成
想定されるケース
(root)
┗folder
┗plugins
┗plugin_name
┗sample.js
┗sample.txt
上記のようにシステムやパッケージのpluginsディレクトリにJSを書く必要があり、同階層にtxtファイルを置くケースを想定します。
また、sample.jsがプラグインに追加で記述するjsファイルとします。
(sample.jsとsample.txtは仮名です。)
記載したコード
const currentScript = document.currentScript;
const scriptBaseUrl = currentScript?.src ? new URL(".", currentScript.src) : new URL(".", window.location.href);
const sampleTxtUrl = new URL("sample.txt", scriptBaseUrl);
let sampleText = "";
async function loadSampleText() {
try {
const response = await fetch(sampleTxtUrl.toString(), { cache: "no-store" });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
sampleText = await response.text();
} catch (error) {
console.log("エラーメッセージ", error);
}
// ここでsampleTextを呼び出す。以下、sampleTextを前提とした記述が入ります
}
loadSampleText();
記述内容
const currentScript = document.currentScript;
const scriptBaseUrl = currentScript?.src ? new URL(".", currentScript.src) : new URL(".", window.location.href);
const sampleTxtUrl = new URL("sample.txt", scriptBaseUrl);
currentScriptで現在実行しているscript要素を取得します。
今回の場合だとsample.jsを読み込むscript要素を取得していることになります。
scriptBaseUrlで現在実行中のscript要素のsrc要素、今回で言うとsample.jsがあるディレクトリを取得しています。
new URL(".", url)で、変数urlのカレントディレクトリをもとにしたURLを返します。
今回の例だとfolder/plugins/plugin_nameとなります。
sampleTxtUrlはsample.txtが配置されたフォルダを取得します。
sample.txtはjsファイル、つまりcurrentScriptと同階層にあるため今回のような記述でファイルを取得します。
async function loadSampleText() {
try {
const response = await fetch(sampleTxtUrl.toString(), { cache: "no-store" });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
sampleText = await response.text();
} catch (error) {
console.log("エラーメッセージ", error);
}
}
よくあるfetch関数の記述と大差ありません。
ですが今回のケースではtxtファイル内の記述を文字列として呼び出す必要がありましたので、toString()で文字列化したものをfetchしました。
最後に
上記のようにHTMLファイルに手を加えられない状況でJavaScript内でtxtファイルを呼び出す時にはcurrentScriptが便利でした。
参考資料