Skip to content

Instantly share code, notes, and snippets.

@nexpr
Last active August 14, 2022 10:00
Show Gist options
  • Save nexpr/3c4a07d1f9b937030e46bd48a4cf09e3 to your computer and use it in GitHub Desktop.
Save nexpr/3c4a07d1f9b937030e46bd48a4cf09e3 to your computer and use it in GitHub Desktop.
同じ HTML ファイル中の script タグを import 可能にする

同じ HTML ファイル中の script タグを import 可能にする

使い方

  1. import する script タグを用意
    • script タグに data-module 属性で名前をつける
    • 上記でつけた名前を使って import する
    • script タグが実行されないように type には text/module 等を指定する
  2. このモジュールを script タグでロード
    • type="module"つけない (importmap は module の実行前に作る必要がある)
    • エントリポイントのモジュール名を # の後に指定
      • 例: #main
      • 省略すると実行されない
      • 省略する場合は手動でインポートが必要

仕組み

  • URL.createObjectURL で script タグごとに URL を作成
  • importmap で data-module の名前と URL をマッピング

<!DOCTYPE html>

<script type="text/module" data-module="add">
	export const add = (a, b) => a + b
</script>

<script type="text/module" data-module="up">
	import { add } from "add"
	const up = x =>  add(x, 1)

	export default up
</script>

<script type="text/module" data-module="main">
	import up from "up"

	console.log(up(1))
	// 2
</script>

<script src="https://gistcdn.githack.com/nexpr/3c4a07d1f9b937030e46bd48a4cf09e3/raw/7f2ebc2f78b0582699f1671c06e6cc7e98b43eac/import-script-module.js
#main"></script>
{
const name_to_url = {}
for (const script of document.querySelectorAll("script[data-module]")) {
name_to_url[script.dataset.module] = URL.createObjectURL(new Blob([script.innerHTML], { type: "text/javascript" }))
}
const importmap = document.createElement("script")
importmap.type = "importmap"
importmap.innerHTML = `{"imports": ${JSON.stringify(name_to_url)}}`
document.head.append(importmap)
const src = document.currentScript.src
const index = src.indexOf("#")
const main_module = index < 0 ? null : src.slice(index + 1)
if (main_module) {
import(main_module)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment