Módulo comunitario incrible

Mapa de orixe

Estado de compilación

NPM

Esta é unha biblioteca para xerar e consumir o formato de mapa fonte descrito aquí .

Usar con Node

1
$ npm install source-map

Uso na 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>

Táboa de contidos

Exemplos

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

Guía de profundidade: compilación de JavaScript e depuración con mapas de orixe

Con SourceNode (API de alto nivel)

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] }

Con SourceMapGenerator (API de baixo nivel)

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

Obter unha referencia ao módulo:

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

Unha SourceMapConsumerinstancia representa un mapa de orixe analizado que podemos consultar información sobre as posicións orixinais do ficheiro dándolle unha posición no ficheiro xerado.

SourceMapConsumer.initialize (opcións)

Cando se usa SourceMapConsumerfóra de node.js, por exemplo na web, precisa saber desde que URL cargar lib/mappings.wasm. Debe informalo chamando initializeantes de construír calquera SourceMapConsumers.

O obxecto opcións ten as seguintes propiedades:

  • "lib/mappings.wasm": A que Stringcontén a URL do lib/mappings.wasmficheiro.
1 2 3
sourceMap.SourceMapConsumer.initialize({ "lib/mappings.wasm": "https://example.com/source-map/lib/mappings.wasm" });

novo SourceMapConsumer (rawSourceMap)

O único parámetro é o mapa de orixe en bruto (como unha cadea que se pode facer JSON.parseou como obxecto). Segundo a especificación, os mapas de orixe teñen os seguintes atributos:

  • version: Que versión da especificación do mapa de orixe segue este mapa.

  • sources: Unha matriz de URL aos ficheiros fonte orixinais.

  • names: Unha matriz de identificadores aos que se pode facer referencia mediante mapas individuais.

  • sourceRoot: Opcional. A raíz URL desde a que todas as fontes son relativas.

  • sourcesContent: Opcional. Unha matriz de contido dos ficheiros fonte orixinais.

  • mappings: Unha cadea de VLQ base64 que conteñen as asignacións reais.

  • file: Opcional. O nome de ficheiro xerado co que está asociado este mapa de orixe.

Devólvese a promesa do consumidor do mapa de souce construído.

Cando o SourceMapConsumerxa non se use, ten que chamar ao seu destroymétodo.

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

Como alternativa, pode usar SourceMapConsumer.withpara evitar ter que lembrar de chamar destroy.

SourceMapConsumer.with

Construír un novo a SourceMapConsumerpartir de rawSourceMape sourceMapUrl (consulte o SourceMapConsumerconstructor para máis detalles. A continuación, invoque o async function f(SourceMapConsumer) -> Tco consumidor recentemente construído, esperar fa completalo, chamar destroyao consumidor e fdevolver o valor devolto.

Non debes usar o consumidor despois de fcompletalo.

Ao usalo with, non ten que lembrarse de chamar manualmente destroyao consumidor, xa que se chamará automaticamente unha vez ffinalizado.

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 ()

Libere os datos de wasm asociados ao consumidor deste mapa de orixe que se xestionan manualmente.

1
consumer.destroy();

Como alternativa, pode usar SourceMapConsumer.withpara evitar ter que lembrar de chamar destroy.

SourceMapConsumer.prototype.computeColumnSpans ()

Calcula a última columna de cada mapeo xerado. A última columna é incluída.

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)

Devolve a información de orixe, liña e columna orixinais para as posicións de liña e columna da fonte xerada. O único argumento é un obxecto coas seguintes propiedades:

  • line: O número de liña na fonte xerada. Os números de liña desta biblioteca están baseados en 1 (teña en conta que a especificación do mapa de orixe subxacente utiliza números de liña baseados en 0: esta biblioteca manexa a tradución).

  • column: O número de columna na fonte xerada. Os números desta biblioteca están baseados en 0.

  • bias: Calquera SourceMapConsumer.GREATEST_LOWER_BOUNDou SourceMapConsumer.LEAST_UPPER_BOUNDEspecifica se a devolver o elemento máis próximo que é menor ou maior que o que está a buscar, respectivamente, se o elemento exacto non se pode atopar patróns para .. SourceMapConsumer.GREATEST_LOWER_BOUND.

e devólvese un obxecto coas seguintes propiedades:

  • source: O ficheiro fonte orixinal ou nulo se esta información non está dispoñible.

  • line: O número de liña na fonte orixinal ou nulo se esta información non está dispoñible. O número de liña está baseado en 1.

  • column: O número de columna da fonte orixinal ou nulo se esta información non está dispoñible. O número de columna está baseado en 0.

  • name: O identificador orixinal ou nulo se esta información non está dispoñible.

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)

Devolve a información de liña e columna xerada para as posicións orixinais de orixe, liña e columna proporcionadas. O único argumento é un obxecto coas seguintes propiedades:

  • source: O nome do ficheiro da fonte orixinal.

  • line: O número de liña na fonte orixinal. O número de liña está baseado en 1.

  • column: O número de columna da fonte orixinal. O número de columna está baseado en 0.

e devólvese un obxecto coas seguintes propiedades:

  • line: O número de liña na fonte xerada ou nulo. O número de liña está baseado en 1.

  • column: O número de columna da fonte xerada ou nulo. O número de columna está baseado en 0.

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

SourceMapConsumer.prototype.allGeneratedPositionsFor (originalPosition)

Devolve toda a información xerada sobre a liña e a columna para a fonte, liña e columna orixinais proporcionadas. Se non se fornece ningunha columna, devolve todos os mapeamentos correspondentes a unha liña que estamos a buscar ou á seguinte liña máis próxima que teña algunha asignación. Se non, devolve todas as correspondencias correspondentes á liña indicada e á columna que estamos a buscar ou á seguinte columna máis próxima que teña algunha compensación.

O único argumento é un obxecto coas seguintes propiedades:

  • source: O nome do ficheiro da fonte orixinal.

  • line: O número de liña na fonte orixinal. O número de liña está baseado en 1.

  • column: Opcional. O número de columna na fonte orixinal. O número de columna está baseado en 0.

e devólvese unha matriz de obxectos, cada un deles coas seguintes propiedades:

  • line: O número de liña na fonte xerada ou nulo. O número de liña está baseado en 1.

  • column: O número de columna da fonte xerada ou nulo. O número de columna está baseado en 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 ()

Devolve verdadeiro se temos o contido de orixe incrustado para todas as fontes listadas no mapa de orixe, en caso contrario, falso.

Noutras palabras, se este método volve true, entón consumer.sourceContentFor(s)terá éxito para todas as fontes sde consumer.sources.

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

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

Devolve o contido de orixe orixinal da fonte proporcionada. O único argumento é a URL do ficheiro de orixe orixinal.

Se non se atopa o contido da fonte indicada, entón prodúcese un erro. Opcionalmente, pase truecomo o segundo parámetro que nullvolveu.

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 (devolución de chamada, contexto, orde)

Repita cada mapa entre unha fonte / liña / columna orixinal e unha liña / columna xerada neste mapa de orixe.

  • callback: A función que se chama con cada asignación. As asignacións teñen a forma { source, generatedLine, generatedColumn, originalLine, originalColumn, name }

  • context: Opcional. Se se especifica, este obxecto será o valor de this cada vez que callbackse chama.

  • order: Calquera SourceMapConsumer.GENERATED_ORDERou SourceMapConsumer.ORIGINAL_ORDEREspecifica se desexa iterado sobre os mapeamento clasificadas segundo a liña de solicitude do ficheiro xerado / columna ou fin de liña / / columna de orixe do orixinal, respectivamente estándar é .. 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

Unha instancia de SourceMapGenerator representa un mapa de orixe que se está a construír incrementalmente.

novo SourceMapGenerator ([startOfSourceMap])

Podes pasar un obxecto coas seguintes propiedades:

  • file: O nome do ficheiro da fonte xerada á que está asociado este mapa de orixe.

  • sourceRoot: Unha raíz para todos os URL relativos neste mapa de orixe.

  • skipValidation: Opcional. Cando truedesactiva a validación dos mapeamentos a medida que se van engadindo. Isto pode mellorar o rendemento, pero débese usar con discreción como último recurso. Aínda así, se é posible, debería evitar este indicador cando se executen probas.

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

SourceMapGenerator.fromSourceMap (sourceMapConsumer)

Crea unha nova a SourceMapGeneratorpartir dunha SourceMapConsumerinstancia existente .

  • sourceMapConsumer O SourceMap.
1
var generator = sourceMap.SourceMapGenerator.fromSourceMap(consumer);

SourceMapGenerator.prototype.addMapping (mapeo)

Engade unha única asignación desde a liña e columna de orixe orixinais á liña e columna da fonte xerada para a creación deste mapa de orixe. O obxecto de asignación debería ter as seguintes propiedades:

  • generated: Un obxecto coas posicións de liña e columna xeradas.

  • original: Un obxecto coa posición orixinal da liña e da columna.

  • source: O ficheiro fonte orixinal (en relación ao sourceRoot).

  • name: Un nome de token orixinal opcional para esta asignación.

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)

Configure o contido fonte dun ficheiro fonte orixinal.

  • sourceFile o URL do ficheiro fonte orixinal.

  • sourceContent o contido do ficheiro fonte.

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

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

Aplica un SourceMap para un ficheiro fonte ao SourceMap. Cada asignación ao ficheiro fonte subministrado reescríbese usando SourceMap subministrado. Nota: a resolución para as asignacións resultantes é a mínima deste mapa e do mapa subministrado.

  • sourceMapConsumer: O mapa fonte que se aplicará.

  • sourceFile: Opcional. O nome do ficheiro de orixe. Se se omite, empregarase o ficheiro sourceMapConsumer.file, se existe. En caso contrario, producirase un erro.

  • sourceMapPath: Opcional. O nome de dirección do camiño ao SourceMap que se vai aplicar. Se é relativo, é relativo ao SourceMap.

    Este parámetro é necesario cando os dous SourceMap non están no mesmo directorio e o SourceMap que se vai aplicar contén camiños de orixe relativos. Se é así, eses camiños de orixe relativos deben ser reescritos en relación ao Mapa de orixe.

    Se se omite, suponse que ambos SourceMaps están no mesmo directorio, polo que non precisan ningunha reescritura (o subministro '.'ten o mesmo efecto).

SourceMapGenerator.prototype.toString ()

Representa o mapa de orixe que se está xerando a unha cadea.

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 proporcionan un xeito de abstraerse sobre interpolar e / ou concatenar fragmentos de código fonte xerado de JavaScript, mantendo a información de liña e columna asociada entre eses fragmentos e o código fonte orixinal. Isto é útil xa que a representación intermedia final pode usar un compilador antes de emitir o JS xerado e o mapa fonte.

novo SourceNode ([liña, columna, fonte [, anaco [, nome]]])

  • line: O número de liña orixinal asociado a este nodo de orixe ou nulo se non está asociado a unha liña orixinal. O número de liña está baseado en 1.

  • column: O número de columna orixinal asociado a este nodo de orixe ou nulo se non está asociado a unha columna orixinal. O número de columna está baseado en 0.

  • source: Nome de ficheiro da fonte orixinal; nulo se non se fornece ningún nome de ficheiro.

  • chunk: Opcional. Pásase inmediatamente a SourceNode.prototype.add, ver máis abaixo.

  • name: Opcional. O identificador orixinal.

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 (código, sourceMapConsumer [, relativePath])

Crea un SourceNode a partir do código xerado e un SourceMapConsumer.

  • code: O código xerado

  • sourceMapConsumer O SourceMap para o código xerado

  • relativePathO camiño opcional no que sourceMapConsumer deben estar relativas as fontes relativas.

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 (anaco)

Engade un anaco de JS xerado a este nodo de orixe.

  • chunk: Un fragmento de cadea de código JS xerado, outra instancia de SourceNodeou unha matriz onde cada membro é unha desas cousas.
1 2 3
node.add(" + "); node.add(otherNode); node.add([leftHandOperandNode, " + ", rightHandOperandNode]);

SourceNode.prototype.prepend (anaco)

Prepara un anaco de JS xerado a este nodo de orixe.

  • chunk: Un fragmento de cadea de código JS xerado, outra instancia de SourceNodeou unha matriz onde cada membro é unha desas cousas.
1
node.prepend("/** Build Id: f783haef86324gf **/\n\n");

SourceNode.prototype.setSourceContent (sourceFile, sourceContent)

Define o contido de orixe a un ficheiro de orixe. Isto vai ser engadido ao SourceMapno sourcesContentcampo.

  • sourceFile: O nome do ficheiro fonte

  • sourceContent: O contido do ficheiro orixe

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

SourceNode.prototype.walk (fn)

Camiña sobre a árbore de fragmentos de JS neste nodo e os seus fillos. A función camiñante chámase unha vez por cada fragmento de JS e pásase ese fragmento e a súa liña de liña / columna orixinal asociada.

  • fn: A función de percorrido.
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)

Camiña sobre a árbore de SourceNodes. A función camiñante chámase para cada contido do ficheiro fonte e pásase o nome do ficheiro e o contido fonte.

  • fn: A función de percorrido.
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)

Como Array.prototype.joinagás para SourceNodes. Insire o separador entre cada un dos fillos deste nodo fonte.

  • sep: O separador.
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 (patrón, substitución)

Chama String.prototype.replaceao fragmento de fonte máis á dereita. Útil para recortar espazo en branco desde o final dun nodo de orixe, etc.

  • pattern: O patrón a substituír.

  • replacement: A cousa coa que substituír o patrón.

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

SourceNode.prototype.toString ()

Devolve a representación de cadea deste nodo fonte. Camiña sobre a árbore e concatena todos os fragmentos xuntos nunha soa cadea.

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])

Devolve a representación en cadea desta árbore de nodos de orixe, máis un SourceMapGenerator que contén todas as asignacións entre as fontes xeradas e as orixinais.

Os argumentos son os mesmos que os 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] }