3
3

More than 1 year has passed since last update.

p5.js Web Editor で JavaScript のモジュール(ES Modules)を扱う【その2】: simplex-noise.js の CDN からの import でダイナミックインポートを使う

Posted at

以前、以下の記事で取り扱った内容と、似た内容の話です。

●【完走賞ゲット-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側に影響が出ない、今回の方法を利用していこうかと思っています。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3