microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
8ab8eac02e97316421203cd7f8075cdef6e98769

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/utils/sourceMap.ts

109lines · modecode

1import url = require("url");
2import path = require("path");
3
4interface ISourceMap {
5 file: string;
6 sources: string[];
7 version: number;
8 names: string[];
9 mappings: string;
10 sourceRoot?: string;
11 sourcesContent?: string[];
12}
13
14export class SourceMapUtil {
15 /**
16 * Given a script body and URL, this method parses the body and finds the corresponding source map URL.
17 * If the source map URL is not found in the body in the expected form, null is returned.
18 */
19 public getSourceMapURL(scriptUrl: url.Url, scriptBody: string): url.Url {
20 let result: url.Url = null;
21
22 // scriptUrl = "http://localhost:8081/index.ios.bundle?platform=ios&dev=true"
23 let sourceMappingRelativeUrl = this.getSourceMapRelativeUrl(scriptBody); // sourceMappingRelativeUrl = "/index.ios.map?platform=ios&dev=true"
24 if (sourceMappingRelativeUrl) {
25 let sourceMappingUrl = url.parse(sourceMappingRelativeUrl);
26 sourceMappingUrl.protocol = scriptUrl.protocol;
27 sourceMappingUrl.host = scriptUrl.host;
28 // parse() repopulates all the properties of the URL
29 result = url.parse(url.format(sourceMappingUrl));
30 }
31
32 return result;
33 }
34
35 /**
36 * Updates the contents of a source map file to be VS Code friendly:
37 * - makes source paths unix style and relative to the sources root path
38 * - updates the url of the script file
39 * - deletes the script content from the source map
40 *
41 * @parameter sourceMapBody - body of the source map as generated by the RN Packager.
42 * @parameter scriptPath - path of the script file asssociated with this source map.
43 * @parameter sourcesRootPath - root path of sources
44 *
45 */
46 public updateSourceMapFile(sourceMapBody: string, scriptPath: string, sourcesRootPath: string): string {
47 try {
48 let sourceMap = <ISourceMap>JSON.parse(sourceMapBody);
49 sourceMap.sources = sourceMap.sources.map(sourcePath => {
50 return this.updateSourceMapPath(sourcePath, sourcesRootPath);
51 });
52
53 delete sourceMap.sourcesContent;
54 sourceMap.sourceRoot = "";
55 sourceMap.file = scriptPath;
56 return JSON.stringify(sourceMap);
57 } catch (exception) {
58 return sourceMapBody;
59 }
60 }
61
62 /**
63 * Given an absolute source path, this method does two things:
64 * 1. It changes the path from absolute to be relative to the sourcesRootPath parameter.
65 * 2. It changes the path separators to Unix style.
66 */
67 private updateSourceMapPath(sourcePath: string, sourcesRootPath: string) {
68 let relativeSourcePath = path.relative(sourcesRootPath, sourcePath);
69 return this.makeUnixStylePath(relativeSourcePath);
70 }
71
72 /**
73 * Visual Studio Code source mapping requires Unix style path separators.
74 * This method replaces all back-slash characters in a given string with forward-slash ones.
75 */
76 private makeUnixStylePath(p: string): string {
77 return p.replace(/\\/g, "/");
78 }
79
80 /**
81 * Returns the regex used for source map url matching.
82 */
83 private getSourceMapUrlRegex(): RegExp {
84 return /\/\/(#|@) sourceMappingURL=(.+?)\s*$/m;
85 }
86
87 /**
88 * Parses the body of a script searching for a source map URL.
89 * It supports the following source map url styles:
90 * //# sourceMappingURL=path/to/source/map
91 * //@ sourceMappingURL=path/to/source/map
92 *
93 * Returns the first match if found, null otherwise.
94 */
95 private getSourceMapRelativeUrl(body: string) {
96 let match = body.match(this.getSourceMapUrlRegex());
97 // If match is null, the body doesn't contain the source map
98 return match ? match[2] : null;
99 }
100
101 /**
102 * Updates source map URLs in the script body.
103 */
104 public updateScriptPaths(scriptBody: string, sourceMappingUrl: url.Url) {
105 // Update the body with the new location of the source map on storage.
106 return scriptBody.replace(this.getSourceMapUrlRegex(),
107 "//# sourceMappingURL=" + path.basename(sourceMappingUrl.pathname));
108 }
109}