Multipage preference

Draft ECMA-426 / August 10, 2026

Source map format specification

この仕様について

https://tc39.es/ecma426/ にある文書は、最も正確で最新のソースマップ仕様である。これは、直近に公開されたスナップショットの内容に加えて、次のスナップショットに含まれる変更を含んでいる。

この仕様への貢献

この仕様は GitHub 上で開発されている。この仕様の開発に貢献する方法はいくつかある:

この文書がどのように作成されているかについての詳細は、奥付を参照されたい。

導入

この Ecma 標準は、トランスパイルされたソースコードを元のソースへ対応付けるために使用される Source map 形式を定義する。

source map 形式には、次の目標がある:

original source map 形式(v1)は、最適化された JavaScript コードのソースレベルデバッグを可能にするために Closure Inspector で使用する目的で Joseph Schorr によって作成された(ただし、形式自体は言語に依存しない)。しかし、source map を使用するプロジェクトの規模が拡大するにつれ、この形式の冗長性が問題になり始めた。v2 形式(Source Map Revision 2 Proposal)は、全体的な source map のサイズを削減するために、いくらかの単純さと柔軟性を犠牲にして作成された。v2 バージョンの形式で加えられた変更があっても、source map ファイルのサイズはその有用性を制限していた。v3 形式は Pavel Podivilov(Google)による提案に基づいている。

source map 形式には、もはやバージョン番号はなく、代わりに常に “3” へハードコードされている。

2023-2024 年に、source map 形式は、多くの人々からの大きな貢献により、より精密な Ecma 標準へと発展した。source map 形式に対する今後の反復作業は TC39-TG4 から行われることが期待されている。

Asumu Takikawa, Nicolò Ribaudo, Jon Kuperman
ECMA-426, 第 1 版, プロジェクト編集者

1 適用範囲

この標準は、JavaScript、WebAssembly、および CSS にコンパイルされたコードのデバッグ体験を向上させるために、さまざまな種類の開発者ツールによって使用される source map 形式を定義する。

2 適合性

適合する source map 文書は、この仕様で詳述される構造に適合する JSON 文書である。

適合する source map 生成器は、適合する source map 文書であり、エラー(任意として指定されているものを含む)を報告することなくこの仕様のアルゴリズムによって復号できる文書を生成するべきである。

適合する source map 消費者は、source map 文書を取得(該当する場合)および復号するために、この仕様で指定されているアルゴリズムを実装するべきである。適合する消費者は、仕様がアルゴリズムにおいて任意にエラーを報告してよいことを示している場合、そのエラーを無視するか、終了せずに報告することが許可される。

3 参照

以下の文書は、その内容の一部または全部がこの文書の要件を構成するような形で本文中から参照されている。日付付き参照については、引用された版のみが適用される。日付なし参照については、参照された文書の最新版(すべての修正を含む)が適用される。

3.1 規範参照

ECMA-262, ECMAScript® Language Specification.
https://tc39.es/ecma262/

ECMA-404, The JSON Data Interchange Format.
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/

3.2 参考参照

IETF RFC 4648, The Base16, Base32, and Base64 Data Encodings.
https://datatracker.ietf.org/doc/html/rfc4648

WebAssembly Core Specification.
https://www.w3.org/TR/wasm-core-2/

WHATWG Encoding.
https://encoding.spec.whatwg.org/

WHATWG Fetch.
https://fetch.spec.whatwg.org/

WHATWG Infra.
https://infra.spec.whatwg.org/

WHATWG URL.
https://url.spec.whatwg.org/

4 表記上の規約

この仕様は、ECMA-262(表記上の規約)で定義されるものと同じ表記上の規約に従い、この節で定義される拡張を加える。

4.1 アルゴリズム規約

4.1.1 暗黙の完了

この仕様で宣言されるすべての抽象操作は、暗黙に、アルゴリズムが宣言した戻り型を含む normal completion、または throw completion のいずれかを返すものと仮定される。例えば、次のように宣言された抽象操作は

4.1.1.1 GetTheAnswer ( input: an integer, ): an integer

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS.

次と等価である:

4.1.1.2 GetTheAnswer2 ( input: an integer, ): either a normal completion containing an integer or a throw completion

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS.

completion record を返す抽象操作へのすべての呼び出しは、明示的な Completion 呼び出しでラップされていない限り、ECMA-262 の ? completion record をアンラップするための省略記法によってラップされているものと暗黙に仮定される。例えば:

#### ECMARKDOWN PARSE FAILED ####
        1. _result_ を GetTheAnswer(_value_) とする。
        1. _second_ を Completion(GetTheAnswer(_value_)) とする。
      

これは次と等価である:

#### ECMARKDOWN PARSE FAILED ####
        1. _result_ を ? GetTheAnswer(_value_) とする。
        1. _second_ を Completion(GetTheAnswer(_value_)) とする。
      

4.1.2 任意のエラー

アルゴリズムが任意にエラーを報告する場合、実装は次のいずれかの振る舞いを選択してよい:

  • アルゴリズムの残りの実行を継続する。
  • ユーザーにエラーを報告し(例えば、ブラウザーコンソールに)、アルゴリズムの残りの実行を継続する。
  • ThrowCompletion を返す。

実装は、異なる任意のエラーに対して異なる振る舞いを選択できる。

4.2 文法表記

この仕様は、ECMA-262(文法表記)で定義されるものと同じ文法表記上の規約に従うが、次の注意点がある:

  • この仕様で定義される文法の終端記号は、個々の符号位置である。これは、ECMA-262 の字句文法に似ており、ECMA-262 の構文文法とは異なる。
  • この仕様は、文法定義の複雑さを抑えるために、文法パラメーターまたは先読み制限を使用しない。

5 用語および定義

この文書の目的において、次の用語および定義が適用される。

generated code

コンパイラーまたはトランスパイラーによって生成されるコード。

original source

コンパイラーまたはトランスパイラーを通されていないソースコード。

source map URL

生成コードから source map の場所を参照する URL

column

生成コードの行内におけるゼロ基点のインデックス付きオフセットであり、JavaScript および CSS の source map では UTF-16 符号単位として計算され、WebAssembly source map ではバイナリー内容(単一行として表される)内のバイトインデックスとして計算される。

Note
これは、“A”(LATIN CAPITAL LETTER A)が 1 符号単位として測定され、“🔥”(FIRE)が 2 符号単位として測定されることを意味する。他の内容型の source map はこれと異なる場合がある。

6 base64 VLQ

base64 VLQ は、base64 で符号化された可変長数量であり、最上位ビット(第 6 ビット)が継続ビットとして使用され、“digits”は下位から先に文字列へ符号化され、最初の桁の最下位ビットが符号ビットとして使用される。

Note 1
base64 VLQ 符号化で表現できる値は、より大きな値に対する何らかのユースケースが提示されるまで 32 ビット数量に制限される。これは、32 ビットを超える値は無効であり、実装がそれらを拒否してよいことを意味する。符号ビットは制限に含めて数えられるが、継続ビットは含めて数えられない。
Note 2
文字列 "iB" は、2 桁の base64 VLQ を表す。最初の桁 "i" はビットパターン 0b100010 を符号化し、これは継続ビット 1(VLQ は継続する)、符号ビット 0(非負)、および値ビット 0b0001 を持つ。2 番目の桁 B はビットパターン 0b000001 を符号化し、これは継続ビット 0、符号ビットなし、および値ビット 0b00001 を持つ。この VLQ 文字列を復号すると数値 17 になる。
Note 3
文字列 "V" は、1 桁の base64 VLQ を表す。桁 "V" はビットパターン 0b010101 を符号化し、これは継続ビット 0(継続なし)、符号ビット 1(負)、および値ビット 0b1010 を持つ。この VLQ 文字列を復号すると数値 -10 になる。

base64 VLQ は、次の字句文法に従う:

Vlq :: VlqDigitList VlqDigitList :: TerminalDigit ContinuationDigit VlqDigitList TerminalDigit :: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f ContinuationDigit :: g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + /

6.1 VLQSignedValue

The syntax-directed operation VLQSignedValue takes no arguments and returns an integer. It is defined piecewise over the following productions:

Vlq :: VlqDigitList #### ECMARKDOWN PARSE FAILED ####
      1. _unsigned_ を |VlqDigitList| の VLQUnsignedValue とする。
      1. _unsigned_ modulo 2 = 1 ならば、_sign_ を -1 とする。
      1. そうでなければ、_sign_ を 1 とする。
      1. _value_ を floor(_unsigned_ / 2) とする。
      1. _value_ が 0 かつ _sign_ が -1 ならば、-231 を返す。
      1. [id="step-VLQSignedValue-boundary-check"] _value_ が ≥ 231 ならば、エラーを投げる。
      1. _sign_ × _value_ を返す。
    
Note
手順 の検査は、unsignedVlq ではなく VlqDigitListVLQUnsignedValue であるため必要である。

6.2 VLQUnsignedValue

The syntax-directed operation VLQUnsignedValue takes no arguments and returns an non-negative integer. It is defined piecewise over the following productions:

Vlq :: VlqDigitList #### ECMARKDOWN PARSE FAILED ####
      1. _value_ を |VlqDigitList| の VLQUnsignedValue とする。
      1. _value_ が ≥ 232 ならば、エラーを投げる。
      1. _value_ を返す。
    
VlqDigitList :: ContinuationDigit VlqDigitList #### ECMARKDOWN PARSE FAILED ####
      1. _left_ を |ContinuationDigit| の VLQUnsignedValue とする。
      1. _right_ を |VlqDigitList| の VLQUnsignedValue とする。
      1. _left_ + _right_ × 25 を返す。
    
TerminalDigit :: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f #### ECMARKDOWN PARSE FAILED ####
      1. _digit_ を、この生成規則に一致した文字とする。
      1. _value_ を、IETF RFC 4648 で定義される base64 符号化に従って、_digit_ に対応する整数とする。
      1. Assert: _value_ < 32。
      1. _value_ を返す。
    
ContinuationDigit :: g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 + / #### ECMARKDOWN PARSE FAILED ####
      1. _digit_ を、この生成規則に一致した文字とする。
      1. _value_ を、IETF RFC 4648 で定義される base64 符号化に従って、_digit_ に対応する整数とする。
      1. Assert: 32 ≤ _value_ < 64。
      1. _value_ - 32 を返す。
    

7 JSON 値ユーティリティ

この仕様のアルゴリズムは ECMA-262 の内部仕様の上に定義されているが、非 JavaScript プラットフォームでも容易に実装できることを意図している。この節には、文書の残りの部分から ECMA-262 の詳細を抽象化し、JSON 値を扱うためのユーティリティが含まれる。

JSON value は、JSON objectJSON arrayStringNumberBoolean、または null のいずれかである。

JSON object は、その各プロパティが次の条件を満たす Object である:

JSON array は、次の条件を満たす JSON object である:

7.1 ParseJSON ( string: a String, ): a JSON value

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
      1. _result_ を Call(%JSON.parse%, *null*, « _string_ ») とする。
      1. Assert: _result_ は JSON value である。
      1. _result_ を返す。
    
Editor's Note
この抽象操作は、ECMA-262 自体で公開される過程にあり、tc39/ecma262#3540 にある。

7.2 JSONObjectGet ( object: a JSON object, key: a String, ): a JSON value or missing

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. これは、object 内で指定された key に関連付けられた値を返す。 It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
      1. _object_ がキー _key_ を持つ own property を持たない場合、~missing~ を返す。
      1. _prop_ を、キーが _key_ である _object_ の own property とする。
      1. _prop_ の [[Value]] 属性を返す。
    

7.3 JSONArrayIterate ( array: a JSON array, ): a List of JSON values

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. これは、“For each” を使用するアルゴリズムによって反復できるように、array のすべての要素を含む List を返す。 It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
      1. _length_ を JSONObjectGet(_array_, *"length"*) とする。
      1. Assert: _length_ は非負の整数 Number である。
      1. _list_ を新しい空の List とする。
      1. _i_ を 0 とする。
      1. _i_ < ℝ(_length_) の間、繰り返す:
        1. _value_ を JSONObjectGet(_array_, ToString(𝔽(_i_))) とする。
        1. Assert: _value_ は ~missing~ ではない。
        1. _value_ を _list_ に追加する。
        1. _i_ を _i_ + 1 に設定する。
      1. _list_ を返す。
    

7.4 StringSplit ( string: a String, separators: a List of non-empty Strings, ): a List of Strings

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. これは、separators のいずれかの要素で区切られた部分文字列に文字列を分割する。複数の区切りが一致する場合、separators 内で先に現れるものがより高い優先度を持つ。 It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
      1. _parts_ を新しい空の List とする。
      1. _strLen_ を _string_ の長さとする。
      1. _lastStart_ を 0 とする。
      1. _i_ を 0 とする。
      1. _i_ < _strLen_ の間、繰り返す:
        1. _matched_ を *false* とする。
        1. _separators_ の各 String _sep_ について、次を行う:
          1. _sepLen_ を _sep_ の長さとする。
          1. _candidate_ を、_string_ の _i_ から min(_i_ + _sepLen_, _strLen_) までの部分文字列とする。
          1. _candidate_ = _sep_ かつ _matched_ が *false* ならば、
            1. _chunk_ を、_string_ の _lastStart_ から _i_ までの部分文字列とする。
            1. _chunk_ を _parts_ に追加する。
            1. _lastStart_ を _i_ + _sepLen_ に設定する。
            1. _i_ を _i_ + _sepLen_ に設定する。
            1. _matched_ を *true* に設定する。
        1. _matched_ が *false* ならば、_i_ を _i_ + 1 に設定する。
      1. _chunk_ を、_string_ の _lastStart_ から _strLen_ までの部分文字列とする。
      1. _chunk_ を _parts_ に追加する。
      1. _parts_ を返す。
    

8 位置型

8.1 Position Record

Position Record は、非負の行番号と非負の列番号からなるタプルである:

Table 1: Position Record Fields
フィールド名 値型
[[Line]] 非負の整数 Number
[[Column]] 非負の整数 Number

8.2 Original Position Record

Original Position Record は、Decoded Source Record、非負の行番号、および非負の列番号からなるタプルである。これは Position Record に似ているが、具体的な元ソースファイル内のソース位置を記述する。

Table 2: Original Position Record Fields
フィールド名 値型
[[Source]] Decoded Source Record
[[Line]] 非負の整数 Number
[[Column]] 非負の整数 Number

8.3 ComparePositions ( first: a Position Record or a Original Position Record, second: a Position Record or a Original Position Record, ): lesser, equal or greater

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. これは、firstsecond より前に出現するか、等しいか、後に出現するかに応じて、それぞれ lesserequal、または greater を返す。Original Position Records[[Source]] フィールドは無視される。 It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
      1. _first_.[[Line]] < _second_.[[Line]] ならば、~lesser~ を返す。
      1. _first_.[[Line]] > _second_.[[Line]] ならば、~greater~ を返す。
      1. Assert: _first_.[[Line]] は _second_.[[Line]] と等しい。
      1. _first_.[[Column]] < _second_.[[Column]] ならば、~lesser~ を返す。
      1. _first_.[[Column]] > _second_.[[Column]] ならば、~greater~ を返す。
      1. ~equal~ を返す。
    

9 Source map 形式

source map は、次の構造を持つトップレベル JSON object を含む JSON 文書である:

{
  "version" : 3,
  "file": "out.js",
  "sourceRoot": "",
  "sources": ["foo.js", "bar.js"],
  "sourcesContent": [null, null],
  "names": ["src", "maps", "are", "fun"],
  "mappings": "A,AAAB;;ABCDE",
  "ignoreList": [0]
}

9.1 source map の復号

Decoded Source Map Record は、次のフィールドを持つ:

Table 3: Fields of Decoded Source Map Records
フィールド名 値型
[[File]] String または null
[[Sources]] Decoded Source RecordsList
[[Mappings]] Decoded Mapping RecordsList

Decoded Source Record は、次のフィールドを持つ:

Table 4: Fields of Decoded Source Records
フィールド名 値型
[[URL]] URL または null
[[Content]] String または null
[[Ignored]] Boolean

9.1.1 ParseSourceMap ( string: a String, baseURL: an URL, ): a Decoded Source Map Record

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
        1. _json_ を ParseJSON(_string_) とする。
        1. _json_ が JSON object でないならば、エラーを投げる。
        1. JSONObjectGet(_json_, *"sections"*) が ~missing~ でないならば、
          1. DecodeIndexSourceMap(_json_, _baseURL_) を返す。
        1. DecodeSourceMap(_json_, _baseURL_) を返す。
      

9.1.2 DecodeSourceMap ( json: a JSON object, baseURL: an URL, ): a Decoded Source Map Record

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
        1. JSONObjectGet(_json_, *"version"*) が *3*𝔽 でないならば、任意にエラーを報告する。
        1. _mappingsField_ を JSONObjectGet(_json_, *"mappings"*) とする。
        1. _mappingsField_ が String でないならば、エラーを投げる。
        1. JSONObjectGet(_json_, *"sources"*) が JSON array でないならば、エラーを投げる。
        1. _fileField_ を GetOptionalString(_json_, *"file"*) とする。
        1. _sourceRootField_ を GetOptionalString(_json_, *"sourceRoot"*) とする。
        1. _sourcesField_ を GetOptionalListOfOptionalStrings(_json_, *"sources"*) とする。
        1. _sourcesContentField_ を GetOptionalListOfOptionalStrings(_json_, *"sourcesContent"*) とする。
        1. _ignoreListField_ を GetOptionalListOfArrayIndexes(_json_, *"ignoreList"*) とする。
        1. _sources_ を DecodeSourceMapSources(_baseURL_, _sourceRootField_, _sourcesField_, _sourcesContentField_, _ignoreListField_) とする。
        1. _namesField_ を GetOptionalListOfStrings(_json_, *"names"*) とする。
        1. _mappings_ を DecodeMappings(_mappingsField_, _namesField_, _sources_) とする。
        1. [declared="a,b"] _mappings_ を昇順にソートする。ここで、Decoded Mapping Record _a_ が Decoded Mapping Record _b_ より小さいとは、ComparePositions(_a_.[[GeneratedPosition]], _b_.[[GeneratedPosition]]) が ~lesser~ であることをいう。
        1. Decoded Source Map Record { [[File]]: _fileField_, [[Sources]]: _sources_, [[Mappings]]: _mappings_ } を返す。
      

9.1.2.1 GetOptionalString ( object: a JSON object, key: a String, ): a String or null

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
          1. _value_ を JSONObjectGet(_object_, _key_) とする。
          1. _value_ が String ならば、_value_ を返す。
          1. _value_ が ~missing~ でないならば、任意にエラーを報告する。
          1. *null* を返す。
        

9.1.2.2 GetOptionalListOfStrings ( object: a JSON object, key: a String, ): a List of Strings

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
          1. _list_ を新しい空の List とする。
          1. _values_ を JSONObjectGet(_object_, _key_) とする。
          1. _values_ が ~missing~ ならば、_list_ を返す。
          1. _values_ が JSON array でないならば、
            1. 任意にエラーを報告する。
            1. _list_ を返す。
          1. JSONArrayIterate(_values_) の各要素 _item_ について、次を行う:
            1. _item_ が String ならば、
              1. _item_ を _list_ に追加する。
            1. そうでなければ、
              1. 任意にエラーを報告する。
              1. 空の文字列を *list* に追加する。
          1. _list_ を返す。
        

9.1.2.3 GetOptionalListOfOptionalStrings ( object: a JSON object, key: a String, ): a List of either Strings or null

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
          1. _list_ を新しい空の List とする。
          1. _values_ を JSONObjectGet(_object_, _key_) とする。
          1. _values_ が ~missing~ ならば、_list_ を返す。
          1. _values_ が JSON array でないならば、
            1. 任意にエラーを報告する。
            1. _list_ を返す。
          1. JSONArrayIterate(_values_) の各要素 _item_ について、次を行う:
            1. _item_ が String ならば、
              1. _item_ を _list_ に追加する。
            1. そうでなければ、
              1. _item_ ≠ *null* ならば、任意にエラーを報告する。
              1. *null* を _list_ に追加する。
          1. _list_ を返す。
        

9.1.2.4 GetOptionalListOfArrayIndexes ( object: an Object, key: a String, ): a List of non-negative integers

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
          1. _list_ を新しい空の List とする。
          1. _values_ を JSONObjectGet(_object_, _key_) とする。
          1. _values_ が ~missing~ ならば、_list_ を返す。
          1. _values_ が JSON array でないならば、
            1. 任意にエラーを報告する。
            1. _list_ を返す。
          1. JSONArrayIterate(_values_) の各要素 _item_ について、次を行う:
            1. _item_ が整数 Number であり、かつ _item_ ≥ *+0*𝔽 ならば、
              1. ℝ(_item_) を _list_ に追加する。
            1. そうでなければ、
              1. 任意にエラーを報告する。
          1. _list_ を返す。
        

9.2 Mappings 構造

mappings フィールドのデータは、次のように分解される:

  • 生成ファイル内の 1 行を表す各グループは、セミコロン(;)で区切られる
  • 各セグメントは、コンマ(,)で区切られる
  • 各セグメントは、1 個、4 個、または 5 個の可変長フィールドで構成される。

各セグメント内のフィールドは次のとおりである:

  1. セグメントが表す生成コード内の行のゼロ基点の開始列。これが最初のセグメントの最初のフィールド、または新しい生成行(;)の直後の最初のセグメントである場合、このフィールドは base64 VLQ 全体を保持する。それ以外の場合、このフィールドは、このフィールドの前回の出現に相対する base64 VLQ を含む。これは、生成行ごとに前回値がリセットされるため、下記の後続フィールドとは異なることに注意。
  2. 存在する場合、sources リストへのゼロ基点インデックス。このフィールドは、このフィールドの前回の出現に相対する base64 VLQ を含む。ただし、このフィールドの最初の出現である場合は、値全体が表される。
  3. 存在する場合、元ソース内のゼロ基点の開始行。このフィールドは、このフィールドの前回の出現に相対する base64 VLQ を含む。ただし、このフィールドの最初の出現である場合は、値全体が表される。source フィールドがある場合は存在しなければならない。
  4. 存在する場合、元ソース内の行のゼロ基点の開始列。このフィールドは、このフィールドの前回の出現に相対する base64 VLQ を含む。ただし、このフィールドの最初の出現である場合は、値全体が表される。source フィールドがある場合は存在しなければならない。
  5. 存在する場合、このセグメントに関連付けられた names リストへのゼロ基点インデックス。このフィールドは、このフィールドの前回の出現に相対する base64 VLQ を含む。ただし、このフィールドの最初の出現である場合は、値全体が表される。
Note 1
この符号化の目的は、source map のサイズを削減することである。Google Calendar を使用して実施されたテストでは、VLQ 符号化により Source Map Revision 2 Proposal と比べて source map が 50% 削減された。
Note 2
1 個のフィールドを持つセグメントは、コンパイラーによって生成されたコードなど、対応する元ソースコードが存在しないためにマップされていない生成コードを表すことを意図している。4 個のフィールドを持つセグメントは、対応する名前が存在しないマップ済みコードを表す。5 個のフィールドを持つセグメントは、マップされた名前も持つマップ済みコードを表す。
Note 3
file オフセットを使用することも検討されたが、プラットフォーム固有の行末により元の内容とのずれが生じることを避けるため、行/column データを使用することが選ばれた。

Decoded Mapping Record は、次のフィールドを持つ:

Table 5: Fields of Decoded Mapping Records
フィールド名 値型
[[GeneratedPosition]] Position Record
[[OriginalPosition]] Original Position Record または null
[[Name]] String または null

9.2.1 Mappings 文法

mappings String は、次の文法に従わなければならない:

MappingsField : LineList LineList : Line Line ; LineList Line : MappingListopt MappingList : Mapping Mapping , MappingList Mapping : GeneratedColumn GeneratedColumn OriginalSource OriginalLine OriginalColumn Nameopt GeneratedColumn : Vlq OriginalSource : Vlq OriginalLine : Vlq OriginalColumn : Vlq Name : Vlq

Decode Mapping State Record は、次のフィールドを持つ:

Table 6: Fields of Decode Mapping State Records
フィールド名 値型
[[GeneratedLine]] 非負の整数
[[GeneratedColumn]] 非負の整数
[[SourceIndex]] 非負の整数
[[OriginalLine]] 非負の整数
[[OriginalColumn]] 非負の整数
[[NameIndex]] 非負の整数

9.2.1.1 DecodeMappingsField

The syntax-directed operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It is defined piecewise over the following productions:

LineList : Line ; LineList #### ECMARKDOWN PARSE FAILED ####
          1. |Line| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
          1. _state_.[[GeneratedLine]] を _state_.[[GeneratedLine]] + 1 に設定する。
          1. _state_.[[GeneratedColumn]] を 0 に設定する。
          1. |LineList| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
        
Line : [empty] #### ECMARKDOWN PARSE FAILED ####
          1. 戻る。
        
MappingList : Mapping , MappingList #### ECMARKDOWN PARSE FAILED ####
          1. |Mapping| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
          1. |MappingList| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
        
Mapping : GeneratedColumn #### ECMARKDOWN PARSE FAILED ####
          1. |GeneratedColumn| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
          1. _state_.[[GeneratedColumn]] < 0 ならば、
            1. 任意にエラーを報告する。
            1. 戻る。
          1. _position_ を新しい Position Record { [[Line]]: _state_.[[GeneratedLine]], [[Column]]: _state_.[[GeneratedColumn]] } とする。
          1. _decodedMapping_ を新しい DecodedMappingRecord { [[GeneratedPosition]]: _position_, [[OriginalPosition]]: *null*, [[Name]]: *null* } とする。
          1. _decodedMapping_ を _mappings_ に追加する。
        
Mapping : GeneratedColumn OriginalSource OriginalLine OriginalColumn Nameopt #### ECMARKDOWN PARSE FAILED ####
          1. |GeneratedColumn| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
          1. _state_.[[GeneratedColumn]] < 0 ならば、
            1. 任意にエラーを報告する。
            1. 戻る。
          1. _generatedPosition_ を新しい Position Record { [[Line]]: _state_.[[GeneratedLine]], [[Column]]: _state_.[[GeneratedColumn]] } とする。
          1. |OriginalSource| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
          1. |OriginalLine| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
          1. |OriginalColumn| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
          1. _state_.[[SourceIndex]] < 0 または _state_.[[SourceIndex]] ≥ _sources_ の要素数、または _state_.[[OriginalLine]] < 0、または _state_.[[OriginalColumn]] < 0 ならば、
            1. 任意にエラーを報告する。
            1. _originalPosition_ を *null* とする。
          1. そうでなければ、
            1. _originalPosition_ を新しい Original Position Record { [[Source]]: _sources_[_state_.[[SourceIndex]]], [[Line]]: _state_.[[OriginalLine]], [[Column]]: _state_.[[OriginalColumn]] } とする。
          1. _name_ を *null* とする。
          1. |Name| が存在するならば、
            1. |Name| の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
            1. _state_.[[NameIndex]] < 0 または _state_.[[NameIndex]] ≥ _names_ の要素数ならば、任意にエラーを報告する。
            1. そうでなければ、_name_ を _names_[_state_.[[NameIndex]]] に設定する。
          1. _decodedMapping_ を新しい DecodedMappingRecord { [[GeneratedPosition]]: _generatedPosition_, [[OriginalPosition]]: _originalPosition_, [[Name]]: _name_ } とする。
          1. _decodedMapping_ を _mappings_ に追加する。
        
GeneratedColumn : Vlq #### ECMARKDOWN PARSE FAILED ####
          1. _relativeColumn_ を |Vlq| の VLQSignedValue とする。
          1. _state_.[[GeneratedColumn]] を _state_.[[GeneratedColumn]] + _relativeColumn_ に設定する。
        
OriginalSource : Vlq #### ECMARKDOWN PARSE FAILED ####
          1. _relativeSourceIndex_ を |Vlq| の VLQSignedValue とする。
          1. _state_.[[SourceIndex]] を _state_.[[SourceIndex]] + _relativeSourceIndex_ に設定する。
        
OriginalLine : Vlq #### ECMARKDOWN PARSE FAILED ####
          1. _relativeLine_ を |Vlq| の VLQSignedValue とする。
          1. _state_.[[OriginalLine]] を _state_.[[OriginalLine]] + _relativeLine_ に設定する。
        
OriginalColumn : Vlq #### ECMARKDOWN PARSE FAILED ####
          1. _relativeColumn_ を |Vlq| の VLQSignedValue とする。
          1. _state_.[[OriginalColumn]] を _state_.[[OriginalColumn]] + _relativeColumn_ に設定する。
        
Name : Vlq #### ECMARKDOWN PARSE FAILED ####
          1. _relativeName_ を |Vlq| の VLQSignedValue とする。
          1. _state_.[[NameIndex]] を _state_.[[NameIndex]] + _relativeName_ に設定する。
        

9.2.2 DecodeMappings ( rawMappings: a String, names: a List of Strings, sources: a List of Decoded Source Records, ): a List of Decoded Mapping Record

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
        1. _mappings_ を新しい空の List とする。
        1. _mappingsNode_ を、|MappingsField| を目標記号として使用して _rawMappings_ を構文解析したときのルート Parse Node とする。
        1. 構文解析が失敗したならば、
          1. 任意にエラーを報告する。
          1. _mappings_ を返す。
        1. _state_ を、すべてのフィールドが 0 に設定された新しい Decode Mapping State Record とする。
        1. _mappingsNode_ の DecodeMappingsField を、引数 _state_、_mappings_、_names_、および _sources_ で実行する。
        1. _mappings_ を返す。
      

9.2.3 生成された JavaScript コードのための mappings

mapping エントリを持ち得る生成コード位置は、ECMAScript Lexical Grammar に従い、input elements の観点から定義される。mapping エントリは、次のいずれかを指さなければならない:

9.2.4 生成された JavaScript コードのための名前

source map 生成器は、JavaScript トークンについて、次の場合に [[Name]] フィールドを持つ mapping エントリを作成するべきである:

  • 元ソース言語の構文要素が、生成された JavaScript コードに意味的に対応付けられる。
  • 元ソース言語の構文要素が名前を持つ。

その場合、mapping エントリの [[Name]] は、元ソース言語の構文要素の名前であるべきである。非 null の [[Name]] を持つ mapping は、named mapping と呼ばれる。

Note 1
関数や変数をリネームしたり、即時実行関数式から関数名を削除したりするミニファイア。

次の列挙は、ECMAScript Syntactic Grammar の生成規則と、source map 生成器が named mapping を出力するべきそれぞれのトークンまたは非終端記号(生成規則の右辺)を列挙する。そのようなトークンに対して作成される mapping エントリは、9.2.3 節に従わなければならない。

この列挙は「最小限」として理解されるべきである。一般に、source map 生成器は任意の追加 named mapping を自由に出力できる。

Note 2
この列挙は、生成器が "should" により named mapping を出力するべきトークンに加えて、"may" により named mapping を出力してもよいトークンも列挙している。これらは、既存のツールが named mapping を出力または期待している現実を反映している。重複した named mapping は比較的安価である。names へのインデックスは相互に相対符号化されるため、同じ名前への後続の mapping は 0(A)として符号化される。

9.3 sources の解決

sourceRoot を前置した後に sources が絶対 URL でない場合、sources は source map に相対して解決される(HTML 文書内でスクリプトの src 属性を解決する場合と同様)。

9.3.1 DecodeSourceMapSources ( baseURL: an URL, sourceRoot: a String or null, sources: a List of either Strings or null, sourcesContent: a List of either Strings or null, ignoreList: a List of non-negative integers, ): a List of Decoded Source Record

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
        1. _decodedSources_ を新しい空の List とする。
        1. _sourcesContentCount_ を _sourcesContent_ 内の要素数とする。
        1. *sourceUrlPrefix* を空の文字列とする。
        1. _sourceRoot_ ≠ *null* ならば、
          1. _sourceRoot_ が符号位置 U+002F(SOLIDUS)で終わるならば、
            1. _sourceUrlPrefix_ を _sourceRoot_ に設定する。
          1. そうでなければ、
            1. _sourceUrlPrefix_ を _sourceRoot_ と *"/"* の文字列連結に設定する。
        1. _index_ を 0 とする。
        1. _index_ < _sources_ の長さの間、繰り返す:
          1. _source_ を _sources_[_index_] とする。
          1. _decodedSource_ を Decoded Source Record { [[URL]]: *null*, [[Content]]: *null*, [[Ignored]]: *false* } とする。
          1. _source_ ≠ *null* ならば、
            1. _source_ を _sourceUrlPrefix_ と _source_ の文字列連結に設定する。
            1. _sourceURL_ を、_baseURL_ を用いて _source_ を URL parsing した結果とする。
            1. _sourceURL_ が ~failure~ ならば、任意にエラーを報告する。
            1. そうでなければ、_decodedSource_.[[URL]] を _sourceURL_ に設定する。
          1. _ignoreList_ が _index_ を含むならば、_decodedSource_.[[Ignored]] を *true* に設定する。
          1. _sourcesContentCount_ > _index_ ならば、_decodedSource_.[[Content]] を _sourcesContent_[_index_] に設定する。
          1. _decodedSource_ を _decodedSources_ に追加する。
          1. _index_ を _index_ + 1 に設定する。
        1. _decodedSources_ を返す。
      
Note
ソース内容の表示をサポートするが、同じ URL と異なる内容を持つ複数のソースの表示をサポートしない実装は、与えられた URL に対応するさまざまな内容のうちの 1 つを任意に選択する。

9.4 拡張

source map 消費者は、追加機能をこの形式に追加しても既存ユーザーを破壊しないように、追加の認識されないプロパティを source map の拒否原因とするのではなく無視しなければならない。

10 Index source map

生成コードの連結およびその他の一般的な後処理をサポートするために、source map の代替表現がサポートされる:

{
  "version" : 3,
  "file": "app.js",
  "sections": [
    {
      "offset": {"line": 0, "column": 0},
      "map": {
        "version" : 3,
        "file": "section.js",
        "sources": ["foo.js", "bar.js"],
        "names": ["src", "maps", "are", "fun"],
        "mappings": "AAAA,E;;ABCDE"
      }
    },
    {
      "offset": {"line": 100, "column": 10},
      "map": {
        "version" : 3,
        "file": "another_section.js",
        "sources": ["more.js"],
        "names": ["more", "is", "better"],
        "mappings": "AAAA,E;AACA,C;ABCDE"
      }
    }
  ]
}

index map は、標準 map の形式に従う。通常の source map と同様に、ファイル形式はトップレベル object を持つ JSON である。通常の source map の version および file フィールドを共有するが、新しい sections フィールドを得る。

sections フィールドは、次のフィールドを持つ object の配列である:

sections は開始位置でソートされなければならず、表される sections は重なってはならない。

10.1 DecodeIndexSourceMap ( json: an Object, baseURL: an URL, ): a Decoded Source Map Record

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
      1. _sectionsField_ を JSONObjectGet(_json_, *"sections"*) とする。
      1. Assert: _sectionsField_ は ~missing~ ではない。
      1. _sectionsField_ が JSON array でないならば、エラーを投げる。
      1. JSONObjectGet(_json_, *"version"*) が *3*𝔽 でないならば、任意にエラーを報告する。
      1. _fileField_ を GetOptionalString(_json_, *"file"*) とする。
      1. _sourceMap_ を Decoded Source Map Record { [[File]]: _fileField_, [[Sources]]: « », [[Mappings]]: « » } とする。
      1. _previousOffsetPosition_ を *null* とする。
      1. _previousLastMapping_ を *null* とする。
      1. JSONArrayIterate(_sectionsField_) の各 JSON value _section_ について、次を行う:
        1. _section_ が JSON object でないならば、
          1. 任意にエラーを報告する。
        1. そうでなければ、
          1. _offset_ を JSONObjectGet(_section_, *"offset"*) とする。
          1. _offset_ が JSON object でないならば、エラーを投げる。
          1. _offsetLine_ を JSONObjectGet(_offset_, *"line"*) とする。
          1. _offsetColumn_ を JSONObjectGet(_offset_, *"column"*) とする。
          1. _offsetLine_ が整数 Number でないならば、
            1. 任意にエラーを報告する。
            1. _offsetLine_ を *+0*𝔽 に設定する。
          1. _offsetColumn_ が整数 Number でないならば、
            1. 任意にエラーを報告する。
            1. _offsetColumn_ を *+0*𝔽 に設定する。
          1. _offsetPosition_ を新しい Position Record { [[Line]]: _offsetLine_, [[Column]]: _offsetColumn_ } とする。
          1. _previousOffsetPosition_ ≠ *null* ならば、
            1. ComparePositions(_offsetPosition_, _previousOffsetPosition_) が ~lesser~ ならば、任意にエラーを報告する。
          1. _previousLastMapping_ ≠ *null* ならば、
            1. ComparePositions(_offsetPosition_, _previousLastMapping_.[[GeneratedPosition]]) が ~lesser~ ならば、任意にエラーを報告する。
            1. NOTE: 復号アルゴリズムのこの部分は、index source map の sections フィールドのエントリが順序付けられており、重なっていないことを検査する。生成器は重なりのある sections を持つ index source map を生成するべきでないと期待されるが、source map 消費者は、例えば sections のオフセットが順序付けられているというより単純な条件のみを検査してもよい。
          1. _mapField_ を JSONObjectGet(_section_, *"map"*) とする。
          1. _mapField_ が JSON object でないならば、エラーを投げる。
          1. _decodedSectionCompletion_ を Completion(DecodeSourceMap(_json_, _baseURL_)) とする。
          1. _decodedSectionCompletion_ が throw completion ならば、
            1. 任意にエラーを報告する。
          1. そうでなければ、
            1. _decodedSection_ を _decodedSectionCompletion_.[[Value]] とする。
            1. _decodedSection_.[[Sources]] の各 Decoded Source Record _additionalSource_ について、次を行う:
              1. _sourceMap_.[[Sources]] が _additionalSource_ を含まないならば、
                1. _additionalSource_ を _sourceMap_.[[Sources]] に追加する。
            1. _offsetMappings_ を新しい空の List とする。
            1. _decodedSection_.[[Mappings]] の各 Decoded Mapping Record _mapping_ について、次を行う:
              1. _mapping_.[[GeneratedPosition]].[[Line]] = 0 ならば、
                1. _mapping_.[[GeneratedPosition]].[[Column]] を _mapping_.[[GeneratedPosition]].[[Column]] + _offsetColumn_ に設定する。
              1. _mapping_.[[GeneratedPosition]].[[Line]] を _mapping_.[[GeneratedPosition]].[[Line]] + _offsetLine_ に設定する。
              1. _mapping_ を _offsetMappings_ に追加する。
            1. _sourceMap_.[[Mappings]] を、_sourceMap_.[[Mappings]] と _offsetMappings_ のリスト連結に設定する。
            1. _previousOffsetPosition_ を _offsetPosition_ に設定する。
            1. _offsetMappings_ が空でないならば、_previousLastMapping_ を _offsetMappings_ の最後の要素に設定する。
        1. _sourceMap_ を返す。
    
Note
実装は、index source map の sections を、mappings を結合せずに表現することを選んでもよい。例えば、各 section を別々に格納し、二分探索を行うことができる。

11 source map の取得

11.1 生成コードを source map にリンクする

source map 形式は言語およびプラットフォームに依存しないことを意図しているが、Web サーバーでホストされる JavaScript という期待されるユースケースについて、それらを参照する方法を定義することは有用である。

source map を出力にリンクする方法は 2 つ考えられる。1 つ目は HTTP ヘッダーを追加するためにサーバーサポートを必要とし、2 つ目はソース内の注釈を必要とする。

source map は、WHATWG URL で定義される URL を通じてリンクされる。特に、URI に出現することが許可される集合外の文字はパーセントエンコードされなければならず、data URI であってもよい。sourcesContent とともに data URI を使用すると、完全に自己完結した source map が可能になる。

HTTP sourcemap ヘッダーはソース注釈よりも優先され、両方が存在する場合、ヘッダー URL を使用して source map ファイルを解決するべきである。

source map URL を取得するために使用される方法にかかわらず、それを解決するには同じ処理が使用される。その処理は次のとおりである。

source map URL が絶対でない場合、それは生成コードのsource originに相対する。source origin は次のいずれかの場合によって決定される:

  • 生成されたソースが src 属性を持つ script 要素に関連付けられておらず、生成コード内に //# sourceURL コメントが存在する場合、そのコメントを使用して source origin を決定するべきである。

    Note
    以前は、これは //@ sourceURL であり、//@ sourceMappingURL と同様に両方を受け入れるのは合理的であるが、//# が推奨される。
  • 生成コードが script 要素に関連付けられており、その script 要素が src 属性を持つ場合、script 要素の src 属性が source origin になる。
  • 生成コードが script 要素に関連付けられており、その script 要素が src 属性を持たない場合、source origin はページの origin になる。
  • 生成コードが eval() 関数または new Function() を介して文字列として評価されている場合、source origin はページの origin になる。

11.1.1 HTTP ヘッダーを通じたリンク

ファイルが sourcemap ヘッダーを伴って HTTP(S) を通じて提供される場合、そのヘッダーの値はリンクされた source map の URL である。

sourcemap: <url>
Note
この文書の以前の改訂では、ヘッダー名として x-sourcemap が推奨されていた。これは現在非推奨であり、現在は sourcemap が期待される。

11.1.2 インライン注釈を通じたリンク

生成コードは、sourceMappingURL という名前で source map の URL を含むコメント、またはその言語や形式に応じた同等の構文を含むべきである。この仕様は、JavaScript、CSS、および WebAssembly においてそのコメントがどのように見えるべきかを定義する。他の言語は類似の規約に従うべきである。

ある言語について、sourceMappingURL コメントを検出する方法は複数あり得る。これは、異なる実装が自分たちにとってより複雑でない方法を選択できるようにするためである。生成コードは、すべての抽出方法の結果が同じである場合、source map に曖昧さなくリンクする

ツールが source map に曖昧さなくリンクする 1 つ以上のソースファイルを消費し、source map にリンクする出力ファイルを生成する場合、それは曖昧さなく行われなければならない。

Note

次の JavaScript コードは source map にリンクするが、曖昧さなくリンクしているわけではない:

let a = `
//# sourceMappingURL=foo.js.map
// `

これから source map URL構文解析を通じて抽出すると foo.js.map が得られる一方、構文解析なしでは null が得られる。

11.1.2.1 JavaScriptExtractSourceMapURL ( source: a String, ): a String or null

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. これは、JavaScript ソースから source map URL を抽出する。これには 2 つの可能な実装がある:構文解析を通じて行うか、構文解析なしで行うかである。

source map URL構文解析を通じて抽出するには:

#### ECMARKDOWN PARSE FAILED ####
          1. _source_ を ECMA-262 の字句文法に従って解析することによって得られた入力要素の List を _tokens_ とする。
          1. _tokens_ の各非終端記号 _token_ について、逆順に、次の手順を行う。
            1. _token_ が |SingleLineComment|、|WhiteSpace|、または |LineTerminatorSequence| のいずれでもない場合は、*null* を返す。
            1. _comment_ を _token_ の内容とする。
            1. _sourceMapURL_ を MatchSourceMapURL(_comment_) とする。
            1. _sourceMapURL_ が String である場合は、_sourceMapURL_ を返す。
          1. *null* を返す。
        

source map URL構文解析なしで抽出するには:

#### ECMARKDOWN PARSE FAILED ####
          1. _lines_ を StringSplit(_source_, « *"\u000D\u000A"*, *"\u000A"*, *"\u000D"*, *"\u2028"*, *"\u2029"* ») とする。
          1. 注記: 上記の文字列のリストは |LineTerminatorSequence| 生成規則に一致する。
          1. _lines_ の各 String _lineStr_ について、List の逆順に、次の手順を行う。
            1. _line_ を StringToCodePoints(_lineStr_) とする。
            1. _position_ を 0 とする。
            1. _lineLength_ を _line_ の長さとする。
            1. _position_ < _lineLength_ である間、次の手順を繰り返す。
              1. _first_ を _line_[_position_] とする。
              1. _first_ が U+002F (SOLIDUS) であり、かつ _position_ + 1 < _lineLength_ である場合は、次の手順を行う。
                1. _position_ を _position_ + 1 に設定する。
                1. _second_ を _line_[_position_] とする。
                1. _second_ が U+002F (SOLIDUS) である場合は、次の手順を行う。
                  1. _position_ を _position_ + 1 に設定する。
                  1. _comment_ を _lineStr_ の _position_ から _lineLength_ までの部分文字列とする。
                  1. _comment_ がコードポイント U+0022 (QUOTATION MARK)、U+0027 (APOSTROPHE)、または U+0060 (GRAVE ACCENT) のいずれかを含む場合は、次の手順を行う。
                    1. *null* を返す。
                  1. _comment_ がコードポイント U+002A (ASTERISK) の直後にコードポイント U+002F (SOLIDUS) が続く箇所を含む場合は、次の手順を行う。
                    1. *null* を返す。
                  1. _sourceMapURL_ を MatchSourceMapURL(_comment_) とする。
                  1. _sourceMapURL_ が String である場合は、_sourceMapURL_ を返す。
                  1. _position_ を _lineLength_ に設定する。
                1. そうでない場合は、
                  1. *null* を返す。
              1. そうでなく、_first_ が ECMAScript |WhiteSpace| である場合は、次の手順を行う。
                1. _position_ を _position_ + 1 に設定する。
              1. そうでない場合は、
                1. *null* を返す。
          1. *null* を返す。
        
Note

source がエラーなしで構文解析でき、そこから source map URL構文解析なしで抽出した結果が非 null である場合、それを構文解析を通じて抽出しても同じ結果が得られる。

11.1.2.1.1 MatchSourceMapURL ( comment: a String, ): either none or a String

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
            1. _pattern_ を RegExpCreate(*"^[@#]\\s\*sourceMappingURL=(\\S\*?)\\s\*$"*, *""*) とする。
            1. _match_ を RegExpExec(_pattern_, _comment_) とする。
            1. _match_ が *null* でないならば、Get(_match_, *"1"*) を返す。
            1. ~none~ を返す。
          
Note
この注釈の接頭辞は当初 //@ であったが、これは Internet Explorer の Conditional Compilation と衝突するため、//# に変更された。

source map 生成器は //# のみを出力しなければならない一方、source map 消費者は //@//# の両方を受け入れなければならない。

11.1.2.2 CSSExtractSourceMapURL ( source: a String, ): a String or null

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. これは、CSS ソースから source map URL を抽出する。

CSS から source map URL を抽出することは JavaScript と似ているが、CSS は /* ... */ 形式のコメントのみをサポートする点が例外である。

11.1.2.3 WebAssemblyExtractSourceMapURL ( bytes: a Data Block, ): a String or null

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. これは、WebAssembly バイナリーソースから source map URL を抽出する。

#### ECMARKDOWN PARSE FAILED ####
        1. _module_ を module_decode(_bytes_) とする。
        1. _module_ が WebAssembly error ならば、*null* を返す。
        1. _module_ の各 custom section _customSection_ について、次を行う:
          1. _name_ を _customSection_ の `name` とする。
          1. CodePointsToString(_name_) が *"sourceMappingURL"* ならば、
            1. _value_ を _customSection_ の `bytes` とする。
            1. CodePointsToString(_value_) を返す。
        1. *null* を返す。
      

WebAssembly はテキスト形式ではなく、コメントをサポートしないため、単一の曖昧さのない抽出方法をサポートする。URLWebAssembly name として符号化され、custom section の内容として配置される。WebAssembly コードを生成するツールが、sourceMappingURL 名を持つ custom section を 2 つ以上生成することは無効である。

11.2 source map のフェッチ

11.2.1 FetchSourceMap ( url: an URL, ): a Promise

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
        1. _promiseCapability_ を NewPromiseCapability(%Promise%) とする。
        1. _request_ を、request URL が _url_ である新しい request とする。
        1. _processResponseConsumeBody_ を、_promiseCapability_ と _url_ をキャプチャする、パラメーター (_response_, _bodyBytes_) を持つ新しい Abstract Closure とし、呼び出されたときに次の手順を実行する:
          1. _bodyBytes_ が *null* または ~failure~ ならば、
            1. Call(_promiseCapability_.[[Reject]], *undefined*, « a new *TypeError* ») を実行する。
            1. 戻る。
          1. _url_ の scheme が HTTP(S) scheme であり、かつバイト列 \``)]}'`\` が _bodyBytes_ の byte-sequence-prefix であるならば、
            1. _bodyBytes_ の byte-sequence-length ≠ 0 かつ _bodyBytes_[0] が HTTP newline byte でない間、繰り返す:
              1. _bodyBytes_ から 0 番目の要素を削除する。
          1. _bodyString_ を UTF-8 decode of _bodyBytes_ の Completion とする。
          1. IfAbruptRejectPromise(_bodyString_, _promiseCapability_)。
          1. _jsonValue_ を Completion(ParseJSON(_bodyString_)) とする。
          1. IfAbruptRejectPromise(_jsonValue_, _promiseCapability_)。
          1. Call(_promiseCapability_.[[Resolve]], *undefined*, « _jsonValue_ ») を実行する。
        1. processResponseConsumeBody を _processResponseConsumeBody_ に設定して fetch _request_ を実行する。
        1. _promiseCapability_.[[Promise]] を返す。
      
Note

歴史的な理由により、HTTP(S) 経由で source map を配信する際、サーバーは source map の前に文字列 )]}' で始まる行を付加する場合がある。

)]}'garbage here
{"version": 3, ...}

これは次のように解釈される

{"version": 3, ...}

12 source map record に対する操作

source map を復号した後、source map 消費者は、得られた Decoded Source Map Records を使用して、デバッグやその他のユースケースのために位置情報を検索できる。この節では、source map 消費者によってサポートされ得る典型的な操作の振る舞いを説明する。

GetOriginalPositions 操作は、生成コード内の位置に対応する元ソース内の位置を問い合わせるために使用できる。例えば、デバッガーで、ユーザーのマウスクリックに基づいて生成コードから元ソースへ移動するために使用できる。

12.1 GetOriginalPositions ( sourceMapRecord: a Decoded Source Map Record, generatedPosition: a Position Record, ): a List of Original Position Records

The abstract operation UNKNOWN takes UNPARSEABLE ARGUMENTS. It performs the following steps when called:

#### ECMARKDOWN PARSE FAILED ####
      1. _mappings_ を _sourceMapRecord_.[[Mappings]] とする。
      1. _last_ を *null* とする。
      1. _originalPositions_ を新しい空の List とする。
      1. _mappings_ の各要素 _mapping_ について、List の逆順に次を行う:
        1. _last_ が *null* ならば、
          1. ComparePositions(_mapping_.[[GeneratedPosition]], _generatedPosition_) を実行した結果が ~lesser~ または ~equal~ ならば、
            1. _last_ を _mapping_ に設定する。
      1. _last_ が *null* でないならば、
        1. _mappings_ の各要素 _mapping_ について、次を行う:
          1. ComparePositions(_last_.[[GeneratedPosition]], _mapping_.[[GeneratedPosition]]) を実行した結果が ~equal~ ならば、
            1. _mapping_.[[OriginalPosition]] を _originalPositions_ に追加する。
      1. _originalPositions_ を返す。
    

Annex A (informative) 規約

source map を扱う場合、またはそれらを生成する場合には、次の規約に従うべきである。

A.1 Source map の命名

一般に、source map は生成ファイルと同じ名前を持つが、.map 拡張子が付く。例えば、page.js については、page.js.map という名前の source map が生成される。

A.2 eval されたコードを名前付き生成コードへリンクする

eval されたコードで source map を使用するためにサポートされるべき既存の規約があり、それは次の形式を持つ:

//# sourceURL=foo.js

これは Give your eval a name with //@ sourceURL で説明されている。

Annex B (informative) 注記

B.1 言語中立のスタックマッピング

ソース言語に関する知識なしのスタックトレースマッピングは、この文書では扱われない

B.2 多段階マッピング

ツールが何らかの DSL(テンプレート)からソースを生成したり、TypeScript → JavaScript → minified JavaScript へコンパイルしたりして、最終的な source map が作成される前に複数の変換が発生することがより一般的になっている。この問題は 2 つの方法のいずれかで扱える。簡単だが損失のある方法は、デバッグの目的ではプロセス内の中間手順を無視することである。変換からのソース位置情報は、無視される(中間変換が “Original Source” と見なされる)か、引き継がれる(中間変換が隠される)。より完全な方法は、複数段階のマッピングをサポートすることである:Original Source も source map 参照を持つ場合、ユーザーにはそれも使用する選択肢が与えられる。

しかし、JavaScript 以外で “source map reference” がどのように見えるのかは不明である。より具体的には、JavaScript 形式の単一行コメントをサポートしない言語において source map reference がどのように見えるのかが不明である。

Annex C (informative) 他の仕様で定義される用語

この節では、この文書によって使用される、ECMA-262 以外の外部仕様で定義されるすべての用語およびアルゴリズムを列挙する。

WebAssembly Core Specification <https://www.w3.org/TR/wasm-core-2/>
custom section, module_decode, WebAssembly error, WebAssembly names
WHATWG Encoding <https://encoding.spec.whatwg.org/>
UTF-8 decode
WHATWG Fetch <https://fetch.spec.whatwg.org/>
fetch, HTTP newline byte, processResponseConsumeBody, request, request URL
WHATWG Infra <https://infra.spec.whatwg.org/>
byte sequence, byte-sequence-prefix, byte-sequence-length,
WHATWG URL <https://url.spec.whatwg.org/>
HTTP(S) scheme, scheme, URL, URL parsing

Annex D (informative) 参考文献

  1. IETF RFC 4648, The Base16, Base32, and Base64 Data Encodings, available at <https://datatracker.ietf.org/doc/html/rfc4648>
  2. ECMA-262, ECMAScript® Language Specification, available at <https://tc39.es/ecma262/>
  3. ECMA-404, The JSON Data Interchange Format, available at <https://www.ecma-international.org/publications-and-standards/standards/ecma-404/>
  4. WebAssembly Core Specification, available at <https://www.w3.org/TR/wasm-core-2/>
  5. WHATWG Encoding, available at <https://encoding.spec.whatwg.org/>
  6. WHATWG Fetch, available at <https://fetch.spec.whatwg.org/>
  7. WHATWG Infra, available at <https://infra.spec.whatwg.org/>
  8. WHATWG URL, available at <https://url.spec.whatwg.org/>
  9. Give your eval a name with //@ sourceURL, Firebug (2009), available at <http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/>
  10. Source Map Revision 2 Proposal, John Lenz (2010), available at <https://docs.google.com/document/d/1xi12LrcqjqIHTtZzrzZKmQ3lbTv9mKrN076UB-j3UZQ/>
  11. Variable-length quantity, Wikipedia, available at <https://en.wikipedia.org/wiki/Variable-length_quantity>

Annex E (informative) 奥付

この仕様は、GitHub 上で Ecmarkup と呼ばれるプレーンテキストソース形式により執筆されている。Ecmarkup は、プレーンテキストで ECMAScript 仕様を執筆し、その仕様をこの文書の編集上の規約に従うフル機能の HTML レンダリングへ処理するためのフレームワークおよびツールセットを提供する HTML および Markdown の方言である。Ecmarkup は、構文を定義するための Grammarkdown や、アルゴリズム手順を執筆するための Ecmarkdown など、多数の他の形式および技術の上に構築され、それらを統合している。この仕様の PDF レンダリングは、HTML レンダリングを PDF に印刷することにより生成される。

この仕様の初版は、HTML および Markdown に基づく別のプレーンテキストソース形式である Bikeshed を使用して執筆された。

標準化前のこの文書のバージョンは、Google Docs を使用して執筆された。

Copyright & Software License

Ecma International

Rue du Rhone 114

CH-1204 Geneva

Tel: +41 22 849 6000

Fax: +41 22 849 6001

Web: https://ecma-international.org/

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.