JavaScriptやCSSを読み込むローダーライブラリをES Modulesとして読み込む
今どきのnpmパッケージはUNPKGやPika CDNを使えば、ES Modulesとして直接import
文読み込めることがあります。
たとえばPreactなら、次のようにUNPKG経由で直接モジュールをインポートできます。
<script type="module">
import { h, Component, render } from 'https://unpkg.com/preact?module';
// Create your app
const app = h('h1', null, 'Hello World!');
render(app, document.body);
</script>
これは、ECMAScript Modulesに対応しているブラウザでしか動きませんが、モダンなブラウザのみ対象のサイトならbundlerなどのツールを使わずにライブラリを気軽に利用できます。(最適化する場合はbundlerを使った方がよさそうですが)
ECMAScriptのimport
文自体については次を参照してください。
- import - JavaScript | MDN
- ECMAScriptモジュール · JavaScript Primer #jsprimer
- Todoアプリ · JavaScript Primer #jsprimerはBundlerやTranspilerを使わずにES Modulesでアプリを作る例です
しかし、このUNPKGやPika CDNからすべてのライブラリが直接Importできるわけではありません。
これを行うにはライブラリ側がpackage.json
のmodule
フィールに対応している必要があります。
そのため、ES Modulesに対応してないライブラリ(UMD形式のみ配布するライブラリなど)は、<script>
タグで読み込んでグローバルに追加されたメソッドを使う必要があります。
また、UIライブラリに含まれるCSSファイルなどもUNPKGなどから取得はできますが、
ES ModulesではCSSファイルは読み込めないためlink
タグなどを使って読み込む必要があります。
このようにライブラリごとに読み込み方法が異なるため、ES Modulesに対応していないJSやCSSの読み込みをラップするdynamic-import-assetsというパッケージを書きました。
dynamic-import-assets
dynamic-import-assetsは、Modulesに対応していないJavaScriptやCSSを読み込むローダーライブラリです。
たとえば、@evillt/toastというToast UIを提供するライブラリは、<script>
タグでJavaScriptを読み込み、<link rel=stylesheet>
でCSSを読み込んでから扱います。
<link rel="stylesheet" href="https://unpkg.com/@evillt/toast/dist/toast.min.css" />
<script src="https://unpkg.com/@evillt/toast"></script>
<script>
toast.createToast('Hello world')
</script>
これをUNPKGとdynamic-import-assetsを使えば次のように書けます。
(async function main(){
const { dynamicImportJS, dynamicImportCSS } = await import("https://unpkg.com/dynamic-import-assets?module");
await Promise.all([
// inject <link rel="stylesheet">
dynamicImportCSS("https://unpkg.com/@evillt/toast/dist/toast.min.css"),
// inject <script>
dynamicImportJS("https://unpkg.com/@evillt/toast")
]);
// use toast after loaded
toast.createToast("Hello world");
})();
既存方法で<script>
タグや<link>
タグをHTMLに書いてしまうと、ライブラリが必要ない場合も読み込んでしまいます。
dynamic-import-assetsではJavaScriptやCSSのロードをJavaScriptから行うため、 必要なタイミングで動的にライブラリを取得できます。
たとえば、次のように?show_toast
というクエリがURLに付いてるときのみToast表示をしたい場合は次のように書けます。
(async function main(){
// ?show_toast
const showToast = (new URL(location.href)).searchParams.has("show_toast")
if (!showToast) {
return;
}
const { dynamicImportJS, dynamicImportCSS } = await import("https://unpkg.com/dynamic-import-assets@^1.0.0?module");
await Promise.all([
dynamicImportCSS("https://unpkg.com/@evillt/[email protected]/dist/toast.min.css"),
dynamicImportJS("https://unpkg.com/@evillt/[email protected]")
]);
toast.createToast("Hello world");
})();
おわりに
モダンなブラウザのみが対象なら、ES Modules(import
文やDynamic Imports)を使ってUNPKGやPika CDNを使って、
npmに公開されているライブラリを直接読み込めることがあります。
<script>
タグで読み込む方法と違ってグローバルに読み込む必要もなくなるため、ちょっとしたサイトでちょっとしたライブラリを使う場合には便利です。
ただし、ES Modules形式で配布していないライブラリやCSSは<script>
や<link>
タグまたはDOM APIを使って読み込む必要があります。
これらのライブラリもDynamic Importsと同じように書き方で読み込めるものが欲しかったのでdynamic-import-assetsを作りました。
逆にライブラリ作者側でES Modules形式も配布したい場合は、次のようなビルドツールを使うのが良いかもしれません。
- developit/microbundle: 📦 Zero-configuration bundler for tiny modules.
- pikapkg/pack: 📦⚡️ Build your npm package using composable plugins. https://www.pika.dev/blog/introducing-pika-pack/
この辺でまだこなれたツールがないのも、ES Modules形式で配布しているライブラリが少ない原因かもしれません。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。