microsoft/vscode-react-native

Public

mirrored fromhttps://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3314a820561f672a145a365db5c47896e6286fa2

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/utils/sourceMap.ts

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