microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.4.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/scriptImporter.ts

204lines · modeblame

a31b007cunknown10 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
a6562589RedMickey6 years ago4import { logger } from "vscode-debugadapter";
0a68f8dbArtem Egorov8 years ago5import { ensurePackagerRunning } from "../common/packagerStatus";
3fb37ad5unknown10 years ago6import path = require("path");
34472878RedMickey5 years ago7import { Request } from "../common/node/request";
8import { SourceMapUtil } from "./sourceMap";
3fb37ad5unknown10 years ago9import url = require("url");
a1324704Artem Egorov8 years ago10import * as semver from "semver";
34472878RedMickey5 years ago11import { ProjectVersionHelper, RNPackageVersions } from "../common/projectVersionHelper";
d124bf0eYuri Skorokhodov7 years ago12import { ErrorHelper } from "../common/error/errorHelper";
13import { InternalErrorCode } from "../common/error/internalErrorCode";
ce5e88eeYuri Skorokhodov5 years ago14import { FileSystem } from "../common/node/fileSystem";
3fb37ad5unknown10 years ago15
5c8365a6Artem Egorov8 years ago16export interface DownloadedScript {
4677921cdigeff10 years ago17contents: string;
18filepath: string;
19}
20
5c8365a6Artem Egorov8 years ago21interface IStrictUrl extends url.Url {
22pathname: string;
23href: string;
24}
25
3fb37ad5unknown10 years ago26export class ScriptImporter {
2743f19cdlebu10 years ago27public static DEBUGGER_WORKER_FILE_BASENAME = "debuggerWorker";
28public static DEBUGGER_WORKER_FILENAME = ScriptImporter.DEBUGGER_WORKER_FILE_BASENAME + ".js";
6eeec3c0Serge Svekolnikov8 years ago29private packagerAddress: string;
e3ae4227digeff10 years ago30private packagerPort: number;
4677921cdigeff10 years ago31private sourcesStoragePath: string;
6eeec3c0Serge Svekolnikov8 years ago32private packagerRemoteRoot?: string;
33private packagerLocalRoot?: string;
4bd0c669dlebu10 years ago34private sourceMapUtil: SourceMapUtil;
3fb37ad5unknown10 years ago35
34472878RedMickey5 years ago36constructor(
37packagerAddress: string,
38packagerPort: number,
39sourcesStoragePath: string,
40packagerRemoteRoot?: string,
41packagerLocalRoot?: string,
42) {
6eeec3c0Serge Svekolnikov8 years ago43this.packagerAddress = packagerAddress;
e3ae4227digeff10 years ago44this.packagerPort = packagerPort;
4677921cdigeff10 years ago45this.sourcesStoragePath = sourcesStoragePath;
6eeec3c0Serge Svekolnikov8 years ago46this.packagerRemoteRoot = packagerRemoteRoot;
47this.packagerLocalRoot = packagerLocalRoot;
4bd0c669dlebu10 years ago48this.sourceMapUtil = new SourceMapUtil();
3fb37ad5unknown10 years ago49}
50
34472878RedMickey5 years ago51public downloadAppScript(
52scriptUrlString: string,
53projectRootPath: string,
54): Promise<DownloadedScript> {
1c32fe84Patricio Beltran9 years ago55const parsedScriptUrl = url.parse(scriptUrlString);
34472878RedMickey5 years ago56const overriddenScriptUrlString =
57parsedScriptUrl.hostname === "localhost"
58? this.overridePackagerPort(scriptUrlString)
59: scriptUrlString;
e00f7325unknown10 years ago60// We'll get the source code, and store it locally to have a better debugging experience
833e37c7Vladimir Kotikov8 years ago61return Request.request(overriddenScriptUrlString, true).then(scriptBody => {
e3706a1cRedMickey6 years ago62return ProjectVersionHelper.getReactNativeVersions(projectRootPath).then(rnVersions => {
979d7bfemax-mironov8 years ago63// unfortunatelly Metro Bundler is broken in RN 0.54.x versions, so use this workaround unless it will be fixed
64// https://github.com/facebook/metro/issues/147
af0c5c30Yuri Skorokhodov5 years ago65// https://github.com/microsoft/vscode-react-native/issues/660
34472878RedMickey5 years ago66if (
67ProjectVersionHelper.getRNVersionsWithBrokenMetroBundler().indexOf(
68rnVersions.reactNativeVersion,
69) >= 0
70) {
71let noSourceMappingUrlGenerated =
72scriptBody.match(/sourceMappingURL=/g) === null;
979d7bfemax-mironov8 years ago73if (noSourceMappingUrlGenerated) {
74let sourceMapPathUrl = overriddenScriptUrlString.replace("bundle", "map");
34472878RedMickey5 years ago75scriptBody = this.sourceMapUtil.appendSourceMapPaths(
76scriptBody,
77sourceMapPathUrl,
78);
979d7bfemax-mironov8 years ago79}
80}
e00f7325unknown10 years ago81
979d7bfemax-mironov8 years ago82// Extract sourceMappingURL from body
83let scriptUrl = <IStrictUrl>url.parse(overriddenScriptUrlString); // scriptUrl = "http://localhost:8081/index.ios.bundle?platform=ios&dev=true"
84let sourceMappingUrl = this.sourceMapUtil.getSourceMapURL(scriptUrl, scriptBody); // sourceMappingUrl = "http://localhost:8081/index.ios.map?platform=ios&dev=true"
4677921cdigeff10 years ago85
ce5e88eeYuri Skorokhodov5 years ago86let waitForSourceMapping: Promise<void> = Promise.resolve();
979d7bfemax-mironov8 years ago87if (sourceMappingUrl) {
88/* handle source map - request it and store it locally */
34472878RedMickey5 years ago89waitForSourceMapping = this.writeAppSourceMap(sourceMappingUrl, scriptUrl).then(
90() => {
91scriptBody = this.sourceMapUtil.updateScriptPaths(
92scriptBody,
93<IStrictUrl>sourceMappingUrl,
94);
7fa90b3bRedMickey6 years ago95if (semver.gte(rnVersions.reactNativeVersion, "0.61.0")) {
2f5c780bYuri Skorokhodov6 years ago96scriptBody = this.sourceMapUtil.removeSourceURL(scriptBody);
97}
34472878RedMickey5 years ago98},
99);
979d7bfemax-mironov8 years ago100}
101
102return waitForSourceMapping
34472878RedMickey5 years ago103.then(() => this.writeAppScript(scriptBody, scriptUrl))
104.then((scriptFilePath: string) => {
105logger.verbose(
106`Script ${overriddenScriptUrlString} downloaded to ${scriptFilePath}`,
107);
108return { contents: scriptBody, filepath: scriptFilePath };
109});
979d7bfemax-mironov8 years ago110});
e00f7325unknown10 years ago111});
112}
113
34472878RedMickey5 years ago114public downloadDebuggerWorker(
115sourcesStoragePath: string,
116projectRootPath: string,
117debuggerWorkerUrlPath?: string,
118): Promise<void> {
119const errPackagerNotRunning = ErrorHelper.getInternalError(
120InternalErrorCode.CannotAttachToPackagerCheckPackagerRunningOnPort,
121this.packagerPort,
122);
6eeec3c0Serge Svekolnikov8 years ago123return ensurePackagerRunning(this.packagerAddress, this.packagerPort, errPackagerNotRunning)
0a68f8dbArtem Egorov8 years ago124.then(() => {
e3706a1cRedMickey6 years ago125return ProjectVersionHelper.getReactNativeVersions(projectRootPath);
a1324704Artem Egorov8 years ago126})
7fa90b3bRedMickey6 years ago127.then((rnVersions: RNPackageVersions) => {
34472878RedMickey5 years ago128let debuggerWorkerURL = this.prepareDebuggerWorkerURL(
129rnVersions.reactNativeVersion,
130debuggerWorkerUrlPath,
131);
132let debuggerWorkerLocalPath = path.join(
133sourcesStoragePath,
134ScriptImporter.DEBUGGER_WORKER_FILENAME,
135);
136logger.verbose(
137"About to download: " + debuggerWorkerURL + " to: " + debuggerWorkerLocalPath,
138);
0a68f8dbArtem Egorov8 years ago139
34472878RedMickey5 years ago140return Request.request(debuggerWorkerURL, true).then((body: string) => {
141return new FileSystem().writeFile(debuggerWorkerLocalPath, body);
142});
299b0557Patricio Beltran10 years ago143});
2743f19cdlebu10 years ago144}
145
cf911877Yuri Skorokhodov7 years ago146public prepareDebuggerWorkerURL(rnVersion: string, debuggerWorkerUrlPath?: string): string {
147let debuggerWorkerURL: string;
148// It can be empty string
149if (debuggerWorkerUrlPath !== undefined) {
150debuggerWorkerURL = `http://${this.packagerAddress}:${this.packagerPort}/${debuggerWorkerUrlPath}${ScriptImporter.DEBUGGER_WORKER_FILENAME}`;
151} else {
152let newPackager = "";
34472878RedMickey5 years ago153if (
154!semver.valid(
155rnVersion,
156) /*Custom RN implementations should support new packager*/ ||
157semver.gte(rnVersion, "0.50.0")
158) {
cf911877Yuri Skorokhodov7 years ago159newPackager = "debugger-ui/";
160}
161debuggerWorkerURL = `http://${this.packagerAddress}:${this.packagerPort}/${newPackager}${ScriptImporter.DEBUGGER_WORKER_FILENAME}`;
162}
163return debuggerWorkerURL;
164}
165
e00f7325unknown10 years ago166/**
167* Writes the script file to the project temporary location.
168*/
ce5e88eeYuri Skorokhodov5 years ago169private writeAppScript(scriptBody: string, scriptUrl: IStrictUrl): Promise<string> {
bb77358cMark Oswald10 years ago170let scriptFilePath = path.join(this.sourcesStoragePath, path.basename(scriptUrl.pathname)); // scriptFilePath = "$TMPDIR/index.ios.bundle"
34472878RedMickey5 years ago171return new FileSystem().writeFile(scriptFilePath, scriptBody).then(() => scriptFilePath);
3fb37ad5unknown10 years ago172}
173
e00f7325unknown10 years ago174/**
175* Writes the source map file to the project temporary location.
176*/
ce5e88eeYuri Skorokhodov5 years ago177private writeAppSourceMap(sourceMapUrl: IStrictUrl, scriptUrl: IStrictUrl): Promise<void> {
34472878RedMickey5 years ago178return Request.request(sourceMapUrl.href, true).then((sourceMapBody: string) => {
179let sourceMappingLocalPath = path.join(
180this.sourcesStoragePath,
181path.basename(sourceMapUrl.pathname),
182); // sourceMappingLocalPath = "$TMPDIR/index.ios.map"
183let scriptFileRelativePath = path.basename(scriptUrl.pathname); // scriptFileRelativePath = "index.ios.bundle"
184let updatedContent = this.sourceMapUtil.updateSourceMapFile(
185sourceMapBody,
186scriptFileRelativePath,
187this.sourcesStoragePath,
188this.packagerRemoteRoot,
189this.packagerLocalRoot,
190);
191return new FileSystem().writeFile(sourceMappingLocalPath, updatedContent);
192});
3fb37ad5unknown10 years ago193}
5e651f3edigeff10 years ago194
195/**
196* Changes the port of the url to be the one configured as this.packagerPort
197*/
198private overridePackagerPort(urlToOverride: string): string {
199let components = url.parse(urlToOverride);
200components.port = this.packagerPort.toString();
201delete components.host; // We delete the host, if not the port change will be ignored
202return url.format(components);
203}
3fb37ad5unknown10 years ago204}