Javascriptを行儀良くプログラミングしようと思ったら、moduleタイプでの記述にすると思いますが、とあるプログラムで動的にmoduleファイルを読み込む仕様が必要になりました。
importを動的に行うことができるという事がわかり、そのシステムが実現できたんですが、あまりこんなやり方をする人がいないみたいで、色々試した結果習得できた方法をブログに残しておきたいと思います。
通常のmoduleタイプの書き方
moduleタイプで書かれたjavascriptは、exportをセットするだけで、別ファイルで手軽にクラス、関数、変数、定数などの受け渡しができます。
import { ExportName1, ExportName2 } from './sample.js'
new ExportName1()
注意点としては、from句にセットするファイルパスは、次の3つのどれかで書かないとエラーになります。
- "./~"
- "../~"
- "http(s)://~"
動的にimportする書き方
importは、上記のように宣言っぽく記述するパターンと、関数として指定する記述パターンがあります。
import('./sample.js')
このように、引数にファイルパスを入れると、動的にモジュールを読み込むことができるんですね。
でも、動的に読み込んだjsモジュールプログラムの読み込み完了は非同期的に完了するので、次のように書いて、読み込み完了を待ち受ける必要があります。
import('./normal.js').then((ExportName1, ExportName2) => {
new ExportName1()
})
なんとなく、標準的な書き方と、同じ感じになったのが分かりますか?
非同期に慣れていない人は、プログラムの順番に戸惑うかもしれませんが、Javascriptのプログラミングにおいて非同期に慣れないと、しんどくなるので、import以外でも非同期の書き方に慣れておきましょう。
応用編
こうした動的な書き方は、変則的に思われガチですが、javascriptのモジュールタイプの欠点として、
ブラウザキャッシュ問題があります。
一度キャッシュされてしまうとプログラム更新をしても、正確に更新をしてくれるわけではなく、利用者がスーパーリロードをするか、キャッシュが切れるのをまつしかありません。
そんな時に、import関数パターンで書く場合であれば、次のように書くことで、常にキャッシュ回避する事ができます。
import(`./sample.js?${(+new Date())}`).then(...)
もちろん、キャッシュ機能を有効にしたい場合であれば、次のようにバージョンキャッシュにすることも可能です。
import(`./sample.js?${version)}`).then(...)
あとがき
1回の作りきりプログラムなどであれば、キャッシュなどを気にしなくていいかと思いがちですが、
何かしらのプログラム修正を行う場合に、ローカルブラウザのキャッシュは、サーバー側からコントロールするのが難しくなるので、キャッシュ回避処理を安定的にできるようにしておくのは、サービスクリエーターとしては有り難い機能だと思います。
動的読み込みと、キャッシュ回避手段としての、今回のimport関数を便利に使うと、webサービス開発がもっと便利になりそうですね。
0 件のコメント:
コメントを投稿