Cartes sources: rapides et faciles





Le mĂ©canisme des cartes sources est utilisĂ© pour mapper le code source du programme aux scripts gĂ©nĂ©rĂ©s sur leur base. MalgrĂ© le fait que le sujet n'est pas nouveau et qu'un certain nombre d'articles ont dĂ©jĂ  Ă©tĂ© Ă©crits dessus (par exemple, ceci , ceci et celui-ci ), certains aspects doivent encore ĂȘtre clarifiĂ©s. L'article prĂ©sentĂ© est une tentative d'organiser et de systĂ©matiser tout ce qui est connu sur ce sujet sous une forme concise et accessible.



L'article Source Maps est considéré en relation avec le développement client dans l'environnement des navigateurs populaires (par exemple, DevTools Google Chrome), bien que leur portée ne soit liée à aucun langage ou environnement particulier. La principale source de Source Maps est, bien sûr, la norme , bien qu'elle n'ait pas encore été adoptée (statut - proposition), mais toujours largement supportée par les navigateurs.



Le travail sur les cartes sources a commencé à la fin des années 2000, la premiÚre version a été créée pour le plugin Firebug Closure Inspector. La deuxiÚme version a été publiée en 2010 et contenait des changements en termes de réduction de la taille du fichier de carte. La troisiÚme version a été développée dans le cadre d'une collaboration entre Google et Mozilla et proposée en 2011 (derniÚre révision en 2013).



Actuellement, il existe une situation dans l'environnement de dĂ©veloppement client oĂč le code source n'est presque jamais intĂ©grĂ© directement dans la page Web, mais il passe par diffĂ©rentes Ă©tapes de traitement: minification, optimisation, concatĂ©nation, de plus, le code source lui-mĂȘme peut ĂȘtre Ă©crit dans des langues nĂ©cessitant une traduction . Dans ce cas, Ă  des fins de dĂ©bogage, vous avez besoin d'un mĂ©canisme qui vous permet d'observer exactement dans le dĂ©bogueur le code source lisible par l'homme.



Les cartes source nécessitent les fichiers suivants:



  • le fichier JavaScript rĂ©ellement gĂ©nĂ©rĂ©
  • l'ensemble des fichiers source utilisĂ©s pour le crĂ©er
  • fichier de mappage qui les mappe les uns aux autres


Fichier de carte



L'ensemble du travail de Source Maps est basé sur un fichier de carte, qui peut ressembler à ceci:



{
    "version":3,
    "file":"index.js",
    "sourceRoot":"",
    "sources":["../src/index.ts"],
    "names":[],
    "mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,SAAS,SAAS;IACd,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;",
    "sourcesContent": []
}


Habituellement, le nom du fichier de mappage est la somme du nom du script auquel il appartient, avec l'ajout de l'extension ".map", bundle.js - bundle.js.map. Il s'agit d'un fichier json standard avec les champs suivants:



  • "Version" - version des cartes sources;
  • "Fichier" - (facultatif) le nom du fichier gĂ©nĂ©rĂ© auquel appartient le fichier cartographique actuel;
  • "SourceRoot" - prĂ©fixe (facultatif) pour les chemins vers les fichiers source;
  • "Sources" - une liste de chemins d'accĂšs aux fichiers source (rĂ©solus de la mĂȘme maniĂšre que les adresses src de la balise de script, vous pouvez utiliser file: //.);
  • «Noms» - une liste de noms de variables et de fonctions qui ont subi une modification dans le fichier gĂ©nĂ©rĂ©;
  • "Mappings" - coordonnĂ©es des variables de mappage et des fonctions des fichiers source vers un fichier gĂ©nĂ©rĂ© au format Base64 VLQ;
  • "SourcesContent" - (facultatif) dans le cas d'un fichier de carte autonome, une liste de lignes, chacune contenant le texte source du fichier provenant des sources;


Télécharger les cartes sources



Pour que le navigateur charge le fichier de carte, l'une des mĂ©thodes suivantes peut ĂȘtre utilisĂ©e:



  • Le fichier JavaScript est fourni avec un en-tĂȘte HTTP: SourceMap: <url> (auparavant obsolĂšte, X-SourceMap: <url> Ă©tait prĂ©cĂ©demment utilisĂ©)
  • le fichier JavaScript gĂ©nĂ©rĂ© a un commentaire spĂ©cial de la forme:


//# sourceMappingURL=<url> ( CSS /*# sourceMappingURL=<url> */)


Ainsi, en téléchargeant le fichier de carte, le navigateur extraira les sources du champ «sources» et, en utilisant les données du champ «mappings», les affichera sur le script généré. Dans l'onglet Sources DevTools, vous pouvez trouver les deux options.



Le fichier: // pseudoprotocol peut ĂȘtre utilisĂ© pour spĂ©cifier le chemin. De plus, le contenu du fichier de carte encodĂ© en base64 peut ĂȘtre inclus dans <url>. Dans la terminologie Webpack, les cartes source comme celles-ci sont appelĂ©es cartes source en ligne.



//# sourceMappingURL=data:application/json;charset=utf-8;base64,<source maps Base64 code>


Erreurs de chargement des cartes source
, map- -, Network DevTools. , map-, Console DevTools : «DevTools failed to load SourceMap: ...». , : «Could not load content for ...».



Fichiers de carte autonomes



Le code des fichiers source peut ĂȘtre inclus directement dans le fichier de la carte dans le champ "sourcesContent", si ce champ est prĂ©sent, il n'est pas nĂ©cessaire de les tĂ©lĂ©charger sĂ©parĂ©ment. Dans ce cas, les noms des fichiers dans "sources" ne reflĂštent pas leur adresse rĂ©elle et peuvent ĂȘtre complĂštement arbitraires. C'est pourquoi, dans l'onglet Sources des DevTools, vous pouvez voir ces Ă©tranges "protocoles": webpack: //, ng: //, etc.



Mappings



L'essence du mécanisme de mappage est que les coordonnées (ligne / colonne) des noms des variables et des fonctions dans le fichier généré sont mappées aux coordonnées dans le fichier de code source correspondant. Pour que le mécanisme d'affichage fonctionne, les informations suivantes sont requises:



(# 1) numéro de ligne dans le fichier généré;

(# 2) numéro de colonne dans le fichier généré;

(# 3) index de la source dans "sources";

(# 4) numéro de ligne source;

(# 5) numéro de colonne source;



Toutes ces données se trouvent dans le champ «mappings», dont la valeur est une longue chaßne avec une structure spéciale et des valeurs encodées en Base64 VLQ.



La ligne est séparée par des points-virgules (;) en sections correspondant aux lignes du fichier généré (# 1).



Chaque section est séparée par des virgules (,) en segments, chacun pouvant contenir 1,4 ou 5 valeurs:



  • le numĂ©ro de colonne dans le fichier gĂ©nĂ©rĂ© (# 2);
  • index des sources dans "sources" (# 3);
  • numĂ©ro de ligne source (# 4);
  • numĂ©ro de colonne source (# 5);
  • index du nom de variable / fonction de la liste des noms;


Les valeurs des numéros de ligne et de colonne sont relatives, indiquent le décalage par rapport aux coordonnées précédentes et uniquement le premier à partir du début du fichier ou de la section.



Chaque valeur est un numéro VLQ Base64. VLQ (Variable-length Quantity) est un principe de codage d'un nombre arbitrairement grand en utilisant un nombre arbitraire de blocs binaires de longueur fixe.



Les cartes sources utilisent des blocs de six bits, qui sont classĂ©s de bas en haut. Le 6e bit le plus Ă©levĂ© de chaque bloc (bit de continuation) est rĂ©servĂ©, s'il est dĂ©fini, le bloc actuel est suivi du bloc suivant du mĂȘme numĂ©ro, s'il est rĂ©initialisĂ©, la sĂ©quence est terminĂ©e.



Étant donnĂ© que la valeur doit avoir un signe dans les cartes sources, le bit le moins significatif (bit de signe) lui est Ă©galement rĂ©servĂ©, mais uniquement dans le premier bloc de la sĂ©quence. Comme prĂ©vu, le bit de signe dĂ©fini signifie un nombre nĂ©gatif.



Ainsi, si un nombre peut ĂȘtre codĂ© avec un seul bloc, il ne peut pas ĂȘtre modulo 15 (1111 2 ), car dans le premier bloc de six bits de la sĂ©quence deux bits sont rĂ©servĂ©s: le bit de continuation sera toujours effacĂ©, le bit de signe sera mis Ă  1 en fonction du signe du nombre.



Les blocs VLQ Ă  six bits sont mappĂ©s au codage Base64, oĂč chaque sĂ©quence Ă  six bits est mappĂ©e Ă  un caractĂšre ASCII spĂ©cifique.







Nous dĂ©codons le nombre mE. Inversez l'ordre, la derniĂšre partie est Em. Nous dĂ©codons les nombres de Base64: E - 000100, m - 100110. Dans le premier, nous supprimons le bit de continuation Ă©levĂ© et deux zĂ©ros de tĂȘte - 100. Dans le second, nous supprimons les bits de continuation Ă©levĂ©e et de faible signe (le bit de signe est effacĂ© - le nombre est positif) - 0011. Par consĂ©quent, nous obtenons 100 0011 2 , qui correspond au dĂ©cimal 67.



Il est possible dans le sens opposĂ©, encoder 41. Son code binaire est 101001 2, nous avons divisĂ© en deux blocs: la partie haute - 10, la partie basse (toujours 4 bits) - 1001. À la partie haute, nous ajoutons le bit de continuation d'ordre supĂ©rieur (effacĂ©) et trois zĂ©ros non significatifs - 000010. À la partie basse, nous ajoutons le bit de continuation d'ordre supĂ©rieur (ensemble) et le bit de signe le moins significatif (effacĂ© - le nombre est positif) - 110010. Nous codons les nombres en Base64: 000010 - C, 110010 - y. Nous inversons l'ordre et, par consĂ©quent, nous obtenons yC.



La bibliothĂšque du mĂȘme nom est trĂšs utile pour travailler avec VLQ .



All Articles