以前、以下の記事で取り扱った内容と、似た内容の話です。
●【完走賞ゲット-7】p5.js Web Editor で JavaScript のモジュール(ES Modules)を扱う: simplex-noise.js の最新版(4.x)を CDN から import する - Qiita
https://qiita.com/youtoy/items/6f6522e2df781a200b39
上記の記事と今回の差分は、以下の記事などに出てくる「ダイナミックインポート」を使うかどうかという点です。
●Dynamic imports(ダイナミックインポート)
https://ja.javascript.info/modules-dynamic-imports
今回はダイナミックインポートを使うことで、前回の記事・今回の記事で出て行くる HTML・JavaScript のそれぞれの内容に少し違いが生じます。具体的な話は、この後に書いていきます。
p5.js で JavaScript のモジュール(ES Modules)を扱う
まず、「p5.js で JavaScript のモジュール(ES Modules)を扱う」という目的のために、前回対応した内容の概略から説明していきます。
前の記事で取り扱った内容
前回の記事では、simplex-noise.js を JavaScript のプログラム内でインポートして利用するため、HTMLファイルの scriptタグの部分で以下の対応を行いました。
<script src="sketch.js"></script>
↓ 「type="module"」を追加
<script src="sketch.js" type="module"></script>
これは、ブラウザの JavaScript のプログラムで ES Modules を利用するための対応です。
あとは simplex-noise.js をインポートするだけで OK、という状態になれば良かったのですが、p5.js の処理がうまく動かなくなりました(※ p5.js は Instance mode ではなく、Global mode で利用しています)。
その原因は、「上記の scriptタグに関する対応を行ったことで、プログラムのスコープに影響が出たため」でした。これにより、グローバルスコープにある p5.js の関数の呼び出しが、デフォルトの記述方法では行えなりました。具体的には、例えば p5.js でよく使われる「setup()」・「draw()」などの記述方法が、以下の書き方だと呼び出せなくなりました。
function setup() {
...
}
function draw() {
...
}
前回の記事では、この問題に対処するため、以下のように「windowオブジェクト」を使う形にしました。これにより、呼び出しができなくなっていた p5.js の関数を呼び出すことができるようになりました。
window.setup = () => {
...
};
今回扱う内容
今回用いる方法は、前回と少し違いがあります。「インポートを行う」という部分は同じなのですが、その際に「ダイナミックインポート」を利用します。
細かな説明については、以下のページをご参照ください。
●Dynamic imports(ダイナミックインポート)
https://ja.javascript.info/modules-dynamic-imports
これにより何が変わるかというと、前回の記事で行った「type="module"
の記載を scriptタグに追加する対応」が不要になります。そのため、前回発生していたスコープ絡みの問題への対処が不要になります。
ダイナミックインポートで simplex-noise.js を読み込む
それでは、ダイナミックインポートを使って simplex-noise.js を読み込んでみます。やり方についてざっくり書くと、非同期処理を用いた読み込みを行います。
実際に用いたコードを以下に掲載して、それに続けて内容の補足を書きます。
let noise2D;
async function preload() {
const { createNoise2D } = await import(
"https://cdn.jsdelivr.net/npm/simplex-noise@4.0.1/dist/esm/simplex-noise.js"
);
noise2D = createNoise2D();
}
function setup() {
createCanvas(400, 400);
}
function draw() {
background(0);
if (noise2D) {
background(220);
console.log(noise2D(10, frameCount));
}
}
ダイナミックインポートを使っているのは、preload() の中です。
そこで async/await を使った処理を用いていますが、この読み込み方法だと scriptタグに「type="module"」を追加しなくても良くなります。
なお、インポートは、p5.js の関数である「preload()」の中で行いましたが、そこに async をつけているため、この関数自体も非同期処理になります。
そのため、その後の部分(draw() の中)で simplex-noise.js の処理を用いる際には、読み込みが完了している状態かどうかを if文で判別するようにしています。
前回と今回のインポート処理の部分を比較する
前回と今回のインポート処理の部分を、並べて書いてみます。
import { createNoise2D } from "https://cdn.jsdelivr.net/npm/simplex-noise@4.0.1/dist/esm/simplex-noise.js";
...
async function preload() {
const { createNoise2D } = await import(
"https://cdn.jsdelivr.net/npm/simplex-noise@4.0.1/dist/esm/simplex-noise.js"
);
...
}
記述方法は少し変わりますが、大幅な変更・処理の追加が必要になる感じはありません。個人的には、p5.js側に影響が出ない、今回の方法を利用していこうかと思っています。