Module communautaire génial

Carte des sources

Statut de construction

MNP

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

Utiliser avec Node

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 les cartes sources

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 source analysée que nous pouvons interroger pour obtenir des informations sur les positions du fichier d'origine en lui donnant une position de fichier dans la source générée.

SourceMapConsumer.initialize(options)

Lors d'une utilisation SourceMapConsumeren dehors 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 l'appelant initializeavant de construire un SourceMapConsumers.

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

  • "lib/mappings.wasm": Un 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 forme de chaîne pouvant être JSON.parse'd, soit sous forme d'objet). Selon la spécification, les cartes sources 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 qui peuvent être référencés par des mappages individuels.

  • sourceRoot : Facultatif. 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 mappe source est associée.

La promesse du consommateur de carte source construit 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();

Alternativement, vous pouvez utiliser SourceMapConsumer.withpour éviter d’avoir à vous rappeler d’appeler destroy.

SourceMapConsumer.with

Construisez un nouveau SourceMapConsumerfrom rawSourceMapand sourceMapUrl (voir le SourceMapConsumerconstructeur pour plus de détails. Ensuite, invoquez le async function f(SourceMapConsumer) -> Tavec le consommateur nouvellement construit, attendez fla fin, 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 besoin de penser à 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();

Alternativement, vous pouvez utiliser SourceMapConsumer.withpour éviter d’avoir à vous rappeler d’appeler destroy.

SourceMapConsumer.prototype.computeColumnSpans()

Calcule 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 d'origine sur la source, la ligne et la colonne pour les positions de ligne et de colonne fournies 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 la carte source sous-jacente utilise des numéros de ligne basés sur 0 -- cette bibliothèque gère la traduction).

  • column : Le 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 respectivement inférieur ou supérieur à celui que nous recherchons, si l'élément exact ne peut pas être trouvé. 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 : Le 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 : Le 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 originale.

  • 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 : Le 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 soit à la ligne recherchée, soit à 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 présente des décalages.

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

  • source: Le nom de fichier de la source originale.

  • 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 : Le 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 sinon.

En d’autres termes, si cette méthode renvoie true, elle consumer.sourceContentFor(s)réussira pour chaque source sde 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 source pour la source donnée n'est pas trouvé,une erreur est générée.Facultativement,passez-le truecomme 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, commande)

Parcourez 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 fois callbackappelé.

  • order: Soit SourceMapConsumer.GENERATED_ORDERou SourceMapConsumer.ORIGINAL_ORDER. Spécifie si vous souhaitez parcourir les mappages triés respectivement selon l'ordre des lignes/colonnes du fichier généré ou l'ordre source/ligne/colonne de l'original. 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 transmettre 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 de leur ajout. Cela peut améliorer les performances mais doit être utilisé avec discrétion, en dernier recours. Même dans ce cas, il convient d'é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 un nouveau SourceMapGeneratorà partir d'une instance existante SourceMapConsumer.

  • sourceMapConsumerLa carte source.
1
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);

SourceMapGenerator.prototype.addMapping(cartographie)

Ajoutez un mappage unique de la ligne et de la colonne source d'origine à la ligne et à la colonne de la source générée pour cette mappe 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 d'origine des lignes et des colonnes.

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

  • name: Un nom de jeton original 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 original.

  • sourceFilel'URL du fichier source d'origine.

  • sourceContentle 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 la résolution minimale de ce mappage et de celui fourni.

  • sourceMapConsumer: Le SourceMap à appliquer.

  • sourceFile: Facultatif. Le nom du fichier source. S'il est omis, sourceMapConsumer.file sera utilisé, s'il existe. Sinon, une erreur sera généré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.

    En cas d'omission, il est supposé que les deux SourceMaps se trouvent dans le même répertoire, ne nécessitant donc aucune réécriture (la fourniture '.'a le même effet).

SourceMapGenerator.prototype.toString()

Renvoie la carte source générée sous forme de 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

Les SourceNodes fournissent un moyen d'abstraire 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 comme représentation intermédiaire finale qu'un compilateur peut utiliser avant de sortir. le JS généré et la carte source.

nouveau 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 : Le 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: Le 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é

  • sourceMapConsumerLe SourceMap pour le code généré

  • relativePathLe chemin facultatif dans lequel 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(morceau)

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

  • chunk: Un extrait de chaîne du code JS généré, une autre instance de SourceNodeou 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(morceau)

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

  • chunk: Un extrait de chaîne du code JS généré, une autre instance de SourceNodeou 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éfinissez le contenu source d'un fichier source. Celui-ci sera ajouté au SourceMapchamp sourcesContent.

  • sourceFile: Le nom 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 reçoit cet extrait ainsi que l'emplacement de la ligne/colonne de sa source d'origine associée.

  • fn: La fonction de parcours.
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 parcours.
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)

Faites appel String.prototype.replaceà l'extrait source le plus à droite. Utile pour couper 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 de code ensemble 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 cette arborescence de nœuds sources, 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] }