Module communautaire génial

Carte des sources

État de la construction

NMP

Il s'agit d'une bibliothèque pour générer et utiliser le format de carte source décrit ici .

Utiliser avec le nœud

1
$ npm install source-map

Utilisation sur le Web

1 2 3 4 5 6
<script src="https://unpkg.com/source-map@0.7.2/dist/source-map.js"></script> <script> sourceMap.SourceMapConsumer.initialize({ "lib/mappings.wasm": "https://unpkg.com/source-map@0.7.2/lib/mappings.wasm" }); </script>

Table des matières

Exemples

Consuming a source map

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
const rawSourceMap = { version: 3, file: 'min.js', names: ['bar', 'baz', 'n'], sources: ['one.js', 'two.js'], sourceRoot: 'http://example.com/www/js/', mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA' }; const whatever = await SourceMapConsumer.with(rawSourceMap, null, consumer => { console.log(consumer.sources); // [ 'http://example.com/www/js/one.js', // 'http://example.com/www/js/two.js' ] console.log(consumer.originalPositionFor({ line: 2, column: 28 })); // { source: 'http://example.com/www/js/two.js', // line: 2, // column: 10, // name: 'n' } console.log(consumer.generatedPositionFor({ source: 'http://example.com/www/js/two.js', line: 2, column: 10 })); // { line: 2, column: 28 } consumer.eachMapping(function (m) { // ... }); return computeWhatever(); });

Generating a source map

Guide détaillé : compilation en JavaScript et débogage avec des cartes source

Avec SourceNode (API de haut niveau)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
function compile(ast) { switch (ast.type) { case 'BinaryExpression': return new SourceNode( ast.location.line, ast.location.column, ast.location.source, [compile(ast.left), " + ", compile(ast.right)] ); case 'Literal': return new SourceNode( ast.location.line, ast.location.column, ast.location.source, String(ast.value) ); // ... default: throw new Error("Bad AST"); } } var ast = parse("40 + 2", "add.js"); console.log(compile(ast).toStringWithSourceMap({ file: 'add.js' })); // { code: '40 + 2', // map: [object SourceMapGenerator] }

Avec SourceMapGenerator (API bas niveau)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
var map = new SourceMapGenerator({ file: "source-mapped.js" }); map.addMapping({ generated: { line: 10, column: 35 }, source: "foo.js", original: { line: 33, column: 2 }, name: "christopher" }); console.log(map.toString()); // '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'

API

Obtenez une référence au module :

1 2 3 4 5 6 7 8
// Node.js var sourceMap = require('source-map'); // Browser builds var sourceMap = window.sourceMap; // Inside Firefox const sourceMap = require("devtools/toolkit/sourcemap/source-map.js");

SourceMapConsumer

Une SourceMapConsumerinstance représente une carte de source analysée que nous pouvons interroger pour obtenir des informations sur les positions de fichier d'origine en lui donnant une position de fichier dans la source générée.

SourceMapConsumer.initialize(options)

Lors d'une utilisation en SourceMapConsumerdehors de node.js, par exemple sur le Web, il a besoin de savoir à partir de quelle URL charger lib/mappings.wasm.Vous devez l'informer en appelant initializeavant de construire tout SourceMapConsumers.

L'objet options a les propriétés suivantes :

  • "lib/mappings.wasm": A Stringcontenant l'URL du lib/mappings.wasmfichier.
1 2 3
sourceMap.SourceMapConsumer.initialize({ "lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm" });

nouveau SourceMapConsumer(rawSourceMap)

Le seul paramètre est la carte source brute (soit sous la forme d'une chaîne pouvant être utilisée JSON.parse, soit sous forme d'objet). Selon les spécifications, les cartes source ont les attributs suivants :

  • version: quelle version de la spécification de la carte source cette carte suit.

  • sources: un tableau d'URL vers les fichiers source d'origine.

  • names: un tableau d'identifiants pouvant être référencés par des mappages individuels.

  • sourceRoot : facultatif. La racine de l'URL à partir de laquelle toutes les sources sont relatives.

  • sourcesContent: facultatif. Un tableau du contenu des fichiers source d'origine.

  • mappings: une chaîne de VLQ base64 qui contiennent les mappages réels.

  • file: Facultatif. Le nom de fichier généré auquel cette carte source est associée.

La promesse du consommateur de carte de source construite est renvoyée.

Lorsque le SourceMapConsumerne sera plus utilisé, vous devez appeler sa destroyméthode.

1 2 3
const consumer = await new sourceMap.SourceMapConsumer(rawSourceMapJsonData); doStuffWith(consumer); consumer.destroy();

Vous pouvez également utiliser SourceMapConsumer.withpour éviter d'avoir à vous rappeler d'appeler destroy.

SourceMapConsumer.with

Construisez un nouveau à SourceMapConsumerpartir de rawSourceMapet sourceMapUrl (voir le SourceMapConsumerconstructeur pour plus de détails. Ensuite, appelez le async function f(SourceMapConsumer) -> Tavec le consommateur nouvellement construit, attendez pour fterminer, appelez destroyle consommateur et renvoyez fla valeur de retour de .

Vous ne devez pas utiliser le consommateur une fois fterminé !

En utilisant with, vous n'avez pas à vous souvenir d'appeler manuellement destroyle consommateur, car il sera appelé automatiquement une fois fterminé.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
const xSquared = await SourceMapConsumer.with( myRawSourceMap, null, async function (consumer) { // Use `consumer` inside here and don't worry about remembering // to call `destroy`. const x = await whatever(consumer); return x * x; } ); // You may not use that `consumer` anymore out here; it has // been destroyed. But you can use `xSquared`. console.log(xSquared);

SourceMapConsumer.prototype.destroy()

Libérez les données wasm associées à ce consommateur de carte source qui sont gérées manuellement.

1
consumer.destroy();

Vous pouvez également utiliser SourceMapConsumer.withpour éviter d'avoir à vous rappeler d'appeler destroy.

SourceMapConsumer.prototype.computeColumnSpans()

Calculez la dernière colonne pour chaque mappage généré. La dernière colonne est inclusive.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
// Before: consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) // [ { line: 2, // column: 1 }, // { line: 2, // column: 10 }, // { line: 2, // column: 20 } ] consumer.computeColumnSpans(); // After: consumer.allGeneratedPositionsFor({ line: 2, source: "foo.coffee" }) // [ { line: 2, // column: 1, // lastColumn: 9 }, // { line: 2, // column: 10, // lastColumn: 19 }, // { line: 2, // column: 20, // lastColumn: Infinity } ]

SourceMapConsumer.prototype.originalPositionFor(generatedPosition)

Renvoie les informations sur la source, la ligne et la colonne d'origine pour les positions de ligne et de colonne de la source générée. Le seul argument est un objet avec les propriétés suivantes :

  • line: Le numéro de ligne dans la source générée. Les numéros de ligne dans cette bibliothèque sont basés sur 1 (notez que la spécification de mappage source sous-jacente utilise des numéros de ligne basés sur 0 - cette bibliothèque gère la traduction).

  • column: numéro de colonne dans la source générée. Les numéros de colonne dans cette bibliothèque sont basés sur 0.

  • bias: Soit SourceMapConsumer.GREATEST_LOWER_BOUNDou SourceMapConsumer.LEAST_UPPER_BOUND. Spécifie s'il faut renvoyer l'élément le plus proche qui est inférieur ou supérieur à celui que nous recherchons, respectivement, si l'élément exact est introuvable. La valeur par défaut est SourceMapConsumer.GREATEST_LOWER_BOUND.

et un objet est renvoyé avec les propriétés suivantes :

  • source: Le fichier source d'origine, ou null si cette information n'est pas disponible.

  • line: numéro de ligne dans la source d'origine, ou null si cette information n'est pas disponible. Le numéro de ligne est basé sur 1.

  • column: numéro de colonne dans la source d'origine, ou null si cette information n'est pas disponible. Le numéro de colonne est basé sur 0.

  • name: L'identifiant d'origine, ou null si cette information n'est pas disponible.

1 2 3 4 5 6 7 8 9 10 11
consumer.originalPositionFor({ line: 2, column: 10 }) // { source: 'foo.coffee', // line: 2, // column: 2, // name: null } consumer.originalPositionFor({ line: 99999999999999999, column: 999999999999999 }) // { source: null, // line: null, // column: null, // name: null }

SourceMapConsumer.prototype.generatedPositionFor(originalPosition)

Renvoie les informations de ligne et de colonne générées pour les positions de source, de ligne et de colonne d'origine fournies. Le seul argument est un objet avec les propriétés suivantes :

  • source: Le nom de fichier de la source d'origine.

  • line: le numéro de ligne dans la source d'origine. Le numéro de ligne est basé sur 1.

  • column: numéro de colonne dans la source d'origine. Le numéro de colonne est basé sur 0.

et un objet est renvoyé avec les propriétés suivantes :

  • line: le numéro de ligne dans la source générée, ou null. Le numéro de ligne est basé sur 1.

  • column: numéro de colonne dans la source générée, ou null. Le numéro de colonne est basé sur 0.

1 2 3
consumer.generatedPositionFor({ source: "example.js", line: 2, column: 10 }) // { line: 1, // column: 56 }

SourceMapConsumer.prototype.allGeneratedPositionsFor(originalPosition)

Renvoie toutes les informations de ligne et de colonne générées pour la source, la ligne et la colonne d'origine fournies. Si aucune colonne n'est fournie, renvoie tous les mappages correspondant à la ligne recherchée ou à la ligne la plus proche qui a des mappages. Sinon, renvoie tous les mappages correspondant à la ligne donnée et soit à la colonne que nous recherchons, soit à la colonne la plus proche qui a des décalages.

Le seul argument est un objet avec les propriétés suivantes :

  • source: Le nom de fichier de la source d'origine.

  • line: le numéro de ligne dans la source d'origine. Le numéro de ligne est basé sur 1.

  • column: facultatif. Numéro de colonne dans la source d'origine. Le numéro de colonne est basé sur 0.

et un tableau d'objets est renvoyé, chacun avec les propriétés suivantes :

  • line: le numéro de ligne dans la source générée, ou null. Le numéro de ligne est basé sur 1.

  • column: numéro de colonne dans la source générée, ou null. Le numéro de colonne est basé sur 0.

1 2 3 4 5 6 7
consumer.allGeneratedpositionsfor({ line: 2, source: "foo.coffee" }) // [ { line: 2, // column: 1 }, // { line: 2, // column: 10 }, // { line: 2, // column: 20 } ]

SourceMapConsumer.prototype.hasContentsOfAllSources()

Renvoie true si nous avons le contenu source intégré pour chaque source répertoriée dans la carte source, false dans le cas contraire.

En d'autres termes, si cette méthode renvoie true, alors consumer.sourceContentFor(s)réussira pour chaque source sdans consumer.sources.

1 2 3 4 5 6 7
// ... if (consumer.hasContentsOfAllSources()) { consumerReadyCallback(consumer); } else { fetchSources(consumer, consumerReadyCallback); } // ...

SourceMapConsumer.prototype.sourceContentFor(source[, returnNullOnMissing])

Renvoie le contenu source d'origine pour la source fournie. Le seul argument est l'URL du fichier source d'origine.

Si le contenu de la source donnée n'est pas trouvé, une erreur est renvoyée. Facultativement, passez en truetant que deuxième paramètre à nullrenvoyer à la place.

1 2 3 4 5 6 7 8 9 10 11
consumer.sources // [ "my-cool-lib.clj" ] consumer.sourceContentFor("my-cool-lib.clj") // "..." consumer.sourceContentFor("this is not in the source map"); // Error: "this is not in the source map" is not in the source map consumer.sourceContentFor("this is not in the source map", true); // null

SourceMapConsumer.prototype.eachMapping (rappel, contexte, ordre)

Itérer sur chaque mappage entre une source/ligne/colonne d'origine et une ligne/colonne générée dans cette carte source.

  • callback: La fonction qui est appelée avec chaque mappage. Les mappages ont la forme { source, generatedLine, generatedColumn, originalLine, originalColumn, name }

  • context: Facultatif. S'il est spécifié, cet objet sera la valeur de this chaque callbackappel.

  • order: Soit SourceMapConsumer.GENERATED_ORDERou SourceMapConsumer.ORIGINAL_ORDER. Spécifie si vous souhaitez parcourir les mappages triés selon l'ordre des lignes/colonnes du fichier généré ou l'ordre source/ligne/colonne de l'original, respectivement. La valeur par défaut est SourceMapConsumer.GENERATED_ORDER.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
consumer.eachMapping(function (m) { console.log(m); }) // ... // { source: 'illmatic.js', // generatedLine: 1, // generatedColumn: 0, // originalLine: 1, // originalColumn: 0, // name: null } // { source: 'illmatic.js', // generatedLine: 2, // generatedColumn: 0, // originalLine: 2, // originalColumn: 0, // name: null } // ...

SourceMapGenerator

Une instance de SourceMapGenerator représente une carte source qui est construite de manière incrémentielle.

nouveau SourceMapGenerator([startOfSourceMap])

Vous pouvez passer un objet avec les propriétés suivantes :

  • file: Le nom de fichier de la source générée à laquelle cette carte source est associée.

  • sourceRoot: une racine pour toutes les URL relatives dans cette carte source.

  • skipValidation: Facultatif. Lorsque true, désactive la validation des mappages au fur et à mesure qu'ils sont ajoutés. Cela peut améliorer les performances mais doit être utilisé avec discrétion, en dernier recours. Même dans ce cas, il faut éviter d'utiliser cet indicateur lors de l'exécution de tests, si possible.

1 2 3 4
var generator = new sourceMap.SourceMapGenerator({ file: "my-generated-javascript-file.js", sourceRoot: "http://example.com/app/js/" });

SourceMapGenerator.fromSourceMap(sourceMapConsumer)

Crée une nouvelle à SourceMapGeneratorpartir d'une SourceMapConsumerinstance existante .

  • sourceMapConsumer La carte des sources.
1
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);

SourceMapGenerator.prototype.addMapping(mapping)

Ajoutez un seul mappage de la ligne et de la colonne source d'origine à la ligne et à la colonne de la source générée pour ce mappage source en cours de création. L'objet de mappage doit avoir les propriétés suivantes :

  • generated: un objet avec les positions de ligne et de colonne générées.

  • original: un objet avec les positions de ligne et de colonne d'origine.

  • source: Le fichier source d'origine (par rapport à la sourceRoot).

  • name: un nom de jeton d'origine facultatif pour ce mappage.

1 2 3 4 5
generator.addMapping({ source: "module-one.scm", original: { line: 128, column: 0 }, generated: { line: 3, column: 456 } })

SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)

Définissez le contenu source d'un fichier source d'origine.

  • sourceFile l'URL du fichier source d'origine.

  • sourceContent le contenu du fichier source.

1 2
generator.setSourceContent("module-one.scm", fs.readFileSync("path/to/module-one.scm"))

SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile[, sourceMapPath]])

Applique un SourceMap pour un fichier source au SourceMap. Chaque mappage vers le fichier source fourni est réécrit à l'aide du SourceMap fourni. Remarque : La résolution des mappages résultants est le minimum de ce mappage et du mappage fourni.

  • sourceMapConsumer: Le SourceMap à appliquer.

  • sourceFile: Facultatif. Le nom de fichier du fichier source. S'il est omis, sourceMapConsumer.file sera utilisé, s'il existe. Sinon, une erreur sera renvoyée.

  • sourceMapPath: Facultatif. Le nom de répertoire du chemin d'accès au SourceMap à appliquer. S'il est relatif, il est relatif au SourceMap.

    Ce paramètre est nécessaire lorsque les deux SourceMaps ne sont pas dans le même répertoire et que le SourceMap à appliquer contient des chemins sources relatifs. Si tel est le cas, ces chemins sources relatifs doivent être réécrits par rapport au SourceMap.

    S'il est omis, il est supposé que les deux SourceMaps sont dans le même répertoire, ne nécessitant donc aucune réécriture (la fourniture '.'a le même effet).

SourceMapGenerator.prototype.toString()

Restitue la carte source en cours de génération en une chaîne.

1 2
generator.toString() // '{"version":3,"sources":["module-one.scm"],"names":[],"mappings":"...snip...","file":"my-generated-javascript-file.js","sourceRoot":"http://example.com/app/js/"}'

SourceNode

SourceNodes fournit un moyen d'abstraire sur l'interpolation et/ou la concaténation d'extraits de code source JavaScript généré, tout en conservant les informations de ligne et de colonne associées entre ces extraits et le code source d'origine. Ceci est utile en tant que représentation intermédiaire finale qu'un compilateur peut utiliser avant la sortie le JS généré et la carte source.

new SourceNode([ligne, colonne, source[, morceau[, nom]]])

  • line : le numéro de ligne d'origine associé à ce nœud source, ou null s'il n'est pas associé à une ligne d'origine. Le numéro de ligne est basé sur 1.

  • column: numéro de colonne d'origine associé à ce nœud source, ou null s'il n'est pas associé à une colonne d'origine. Le numéro de colonne est basé sur 0.

  • source: nom de fichier de la source d'origine ; null si aucun nom de fichier n'est fourni.

  • chunk: Facultatif. Est immédiatement transmis à SourceNode.prototype.add, voir ci-dessous.

  • name: facultatif. L'identifiant d'origine.

1 2 3 4 5
var node = new SourceNode(1, 2, "a.cpp", [ new SourceNode(3, 4, "b.cpp", "extern int status;\n"), new SourceNode(5, 6, "c.cpp", "std::string* make_string(size_t n);\n"), new SourceNode(7, 8, "d.cpp", "int main(int argc, char** argv) {}\n"), ]);

SourceNode.fromStringWithSourceMap(code, sourceMapConsumer[, relativePath])

Crée un SourceNode à partir du code généré et un SourceMapConsumer.

  • code: Le code généré

  • sourceMapConsumer Le SourceMap pour le code généré

  • relativePathLe chemin facultatif auquel les sources relatives sourceMapConsumer doivent être relatives.

1 2
const consumer = await new SourceMapConsumer(fs.readFileSync("path/to/my-file.js.map", "utf8")); const node = SourceNode.fromStringWithSourceMap(fs.readFileSync("path/to/my-file.js"), consumer);

SourceNode.prototype.add(chunk)

Ajoutez un morceau de JS généré à ce nœud source.

  • chunk: un extrait de chaîne de code JS généré, une autre instance de SourceNode, ou un tableau où chaque membre est l'un de ces éléments.
1 2 3
node.add(" + "); node.add(otherNode); node.add([leftHandOperandNode, " + ", rightHandOperandNode]);

SourceNode.prototype.prepend(chunk)

Ajoutez un morceau de JS généré à ce nœud source.

  • chunk: un extrait de chaîne de code JS généré, une autre instance de SourceNode, ou un tableau où chaque membre est l'un de ces éléments.
1
node.prepend("/** Build Id: f783haef86324gf **/\n\n");

SourceNode.prototype.setSourceContent(sourceFile, sourceContent)

Définir le contenu source pour un fichier source. Ce sera ajouté au SourceMapdans le sourcesContentdomaine.

  • sourceFile: Le nom de fichier du fichier source

  • sourceContent: Le contenu du fichier source

1 2
node.setSourceContent("module-one.scm", fs.readFileSync("path/to/module-one.scm"))

SourceNode.prototype.walk(fn)

Parcourez l'arborescence des extraits de code JS dans ce nœud et ses enfants. La fonction de marche est appelée une fois pour chaque extrait de code JS et est transmise à cet extrait et à l'emplacement de la ligne/colonne de sa source associée d'origine.

  • fn: La fonction de traversée.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", [ "tres", new SourceNode(5, 6, "c.js", "quatro") ] ]); node.walk(function (code, loc) { console.log("WALK:", code, loc); }) // WALK: uno { source: 'b.js', line: 3, column: 4, name: null } // WALK: dos { source: 'a.js', line: 1, column: 2, name: null } // WALK: tres { source: 'a.js', line: 1, column: 2, name: null } // WALK: quatro { source: 'c.js', line: 5, column: 6, name: null }

SourceNode.prototype.walkSourceContents(fn)

Parcourez l'arborescence des SourceNodes. La fonction de marche est appelée pour chaque contenu de fichier source et reçoit le nom de fichier et le contenu source.

  • fn: La fonction de traversée.
1 2 3 4 5 6 7 8 9 10 11 12
var a = new SourceNode(1, 2, "a.js", "generated from a"); a.setSourceContent("a.js", "original a"); var b = new SourceNode(1, 2, "b.js", "generated from b"); b.setSourceContent("b.js", "original b"); var c = new SourceNode(1, 2, "c.js", "generated from c"); c.setSourceContent("c.js", "original c"); var node = new SourceNode(null, null, null, [a, b, c]); node.walkSourceContents(function (source, contents) { console.log("WALK:", source, ":", contents); }) // WALK: a.js : original a // WALK: b.js : original b // WALK: c.js : original c

SourceNode.prototype.join(sep)

Comme Array.prototype.joinsauf pour SourceNodes. Insère le séparateur entre chacun des enfants de ce nœud source.

  • sep: Le séparateur.
1 2 3 4 5 6
var lhs = new SourceNode(1, 2, "a.rs", "my_copy"); var operand = new SourceNode(3, 4, "a.rs", "="); var rhs = new SourceNode(5, 6, "a.rs", "orig.clone()"); var node = new SourceNode(null, null, null, [ lhs, operand, rhs ]); var joinedNode = node.join(" ");

SourceNode.prototype.replaceRight(modèle, remplacement)

Appelez String.prototype.replacel'extrait de source le plus à droite. Utile pour rogner l'espace blanc à la fin d'un nœud source, etc.

  • pattern: Le motif à remplacer.

  • replacement: La chose par laquelle remplacer le motif.

1 2
// Trim trailing white space. node.replaceRight(/\s*$/, "");

SourceNode.prototype.toString()

Renvoie la représentation sous forme de chaîne de ce nœud source. Parcourt l'arborescence et concatène tous les différents extraits en une seule chaîne.

1 2 3 4 5 6 7 8 9 10 11
var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", [ "tres", new SourceNode(5, 6, "c.js", "quatro") ] ]); node.toString() // 'unodostresquatro'

SourceNode.prototype.toStringWithSourceMap([startOfSourceMap])

Renvoie la représentation sous forme de chaîne de cet arbre de nœuds source, plus un SourceMapGenerator qui contient tous les mappages entre les sources générées et originales.

Les arguments sont les mêmes que ceux de new SourceMapGenerator.

1 2 3 4 5 6 7 8 9 10 11 12
var node = new SourceNode(1, 2, "a.js", [ new SourceNode(3, 4, "b.js", "uno"), "dos", [ "tres", new SourceNode(5, 6, "c.js", "quatro") ] ]); node.toStringWithSourceMap({ file: "my-output-file.js" }) // { code: 'unodostresquatro', // map: [object SourceMapGenerator] }