microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
remove-unused-debugging-code

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/scriptImporter.ts

206lines · 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
3fb37ad5unknown10 years ago4import path = require("path");
5import url = require("url");
623be8a6Ezio Li2 years ago6import { logger } from "@vscode/debugadapter";
a1324704Artem Egorov8 years ago7import * as semver from "semver";
09f6024fHeniker4 years ago8import { Request } from "../common/node/request";
9import { ensurePackagerRunning } from "../common/packagerStatus";
0d77292aJiglioNero4 years ago10import { ProjectVersionHelper } from "../common/projectVersionHelper";
d124bf0eYuri Skorokhodov7 years ago11import { ErrorHelper } from "../common/error/errorHelper";
12import { InternalErrorCode } from "../common/error/internalErrorCode";
ce5e88eeYuri Skorokhodov5 years ago13import { FileSystem } from "../common/node/fileSystem";
09f6024fHeniker4 years ago14import { SourceMapUtil } from "./sourceMap";
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";
09f6024fHeniker4 years ago28public static DEBUGGER_WORKER_FILENAME = `${ScriptImporter.DEBUGGER_WORKER_FILE_BASENAME}.js`;
47927908RedMickey4 years ago29
30private static readonly REMOVE_SOURCE_URL_VERSION = "0.61.0";
31private static readonly DEBUGGER_UI_SUPPORTED_VERSION = "0.50.0";
32
6eeec3c0Serge Svekolnikov8 years ago33private packagerAddress: string;
e3ae4227digeff10 years ago34private packagerPort: number;
4677921cdigeff10 years ago35private sourcesStoragePath: string;
6eeec3c0Serge Svekolnikov8 years ago36private packagerRemoteRoot?: string;
37private packagerLocalRoot?: string;
4bd0c669dlebu10 years ago38private sourceMapUtil: SourceMapUtil;
3fb37ad5unknown10 years ago39
34472878RedMickey5 years ago40constructor(
41packagerAddress: string,
42packagerPort: number,
43sourcesStoragePath: string,
44packagerRemoteRoot?: string,
45packagerLocalRoot?: string,
46) {
6eeec3c0Serge Svekolnikov8 years ago47this.packagerAddress = packagerAddress;
e3ae4227digeff10 years ago48this.packagerPort = packagerPort;
4677921cdigeff10 years ago49this.sourcesStoragePath = sourcesStoragePath;
6eeec3c0Serge Svekolnikov8 years ago50this.packagerRemoteRoot = packagerRemoteRoot;
51this.packagerLocalRoot = packagerLocalRoot;
4bd0c669dlebu10 years ago52this.sourceMapUtil = new SourceMapUtil();
3fb37ad5unknown10 years ago53}
54
0d77292aJiglioNero4 years ago55public async downloadAppScript(
34472878RedMickey5 years ago56scriptUrlString: string,
57projectRootPath: string,
58): Promise<DownloadedScript> {
1c32fe84Patricio Beltran9 years ago59const parsedScriptUrl = url.parse(scriptUrlString);
34472878RedMickey5 years ago60const overriddenScriptUrlString =
61parsedScriptUrl.hostname === "localhost"
62? this.overridePackagerPort(scriptUrlString)
63: scriptUrlString;
0d77292aJiglioNero4 years ago64
e00f7325unknown10 years ago65// We'll get the source code, and store it locally to have a better debugging experience
0d77292aJiglioNero4 years ago66let scriptBody = await Request.request(overriddenScriptUrlString, true);
e00f7325unknown10 years ago67
0d77292aJiglioNero4 years ago68const rnVersions = await ProjectVersionHelper.getReactNativeVersions(projectRootPath);
69// unfortunatelly Metro Bundler is broken in RN 0.54.x versions, so use this workaround unless it will be fixed
70// https://github.com/facebook/metro/issues/147
71// https://github.com/microsoft/vscode-react-native/issues/660
72if (
09f6024fHeniker4 years ago73ProjectVersionHelper.getRNVersionsWithBrokenMetroBundler().includes(
0d77292aJiglioNero4 years ago74rnVersions.reactNativeVersion,
09f6024fHeniker4 years ago75)
0d77292aJiglioNero4 years ago76) {
09f6024fHeniker4 years ago77const noSourceMappingUrlGenerated = scriptBody.match(/sourceMappingURL=/g) === null;
0d77292aJiglioNero4 years ago78if (noSourceMappingUrlGenerated) {
09f6024fHeniker4 years ago79const sourceMapPathUrl = overriddenScriptUrlString.replace("bundle", "map");
0d77292aJiglioNero4 years ago80scriptBody = this.sourceMapUtil.appendSourceMapPaths(scriptBody, sourceMapPathUrl);
81}
82}
83
84// Extract sourceMappingURL from body
09f6024fHeniker4 years ago85const scriptUrl = <IStrictUrl>url.parse(overriddenScriptUrlString); // scriptUrl = "http://localhost:8081/index.ios.bundle?platform=ios&dev=true"
86const sourceMappingUrl = this.sourceMapUtil.getSourceMapURL(scriptUrl, scriptBody); // sourceMappingUrl = "http://localhost:8081/index.ios.map?platform=ios&dev=true"
979d7bfemax-mironov8 years ago87
0d77292aJiglioNero4 years ago88let waitForSourceMapping: Promise<void> = Promise.resolve();
89if (sourceMappingUrl) {
90/* handle source map - request it and store it locally */
91waitForSourceMapping = this.writeAppSourceMap(sourceMappingUrl, scriptUrl).then(() => {
92scriptBody = this.sourceMapUtil.updateScriptPaths(
93scriptBody,
94<IStrictUrl>sourceMappingUrl,
95);
47927908RedMickey4 years ago96if (
97semver.gte(
98rnVersions.reactNativeVersion,
99ScriptImporter.REMOVE_SOURCE_URL_VERSION,
100) ||
101ProjectVersionHelper.isCanaryVersion(rnVersions.reactNativeVersion)
102) {
0d77292aJiglioNero4 years ago103scriptBody = this.sourceMapUtil.removeSourceURL(scriptBody);
104}
979d7bfemax-mironov8 years ago105});
0d77292aJiglioNero4 years ago106}
107await waitForSourceMapping;
108const scriptFilePath = await this.writeAppScript(scriptBody, scriptUrl);
109logger.verbose(`Script ${overriddenScriptUrlString} downloaded to ${scriptFilePath}`);
110return { contents: scriptBody, filepath: scriptFilePath };
e00f7325unknown10 years ago111}
112
0d77292aJiglioNero4 years ago113public async downloadDebuggerWorker(
34472878RedMickey5 years ago114sourcesStoragePath: string,
115projectRootPath: string,
116debuggerWorkerUrlPath?: string,
117): Promise<void> {
118const errPackagerNotRunning = ErrorHelper.getInternalError(
119InternalErrorCode.CannotAttachToPackagerCheckPackagerRunningOnPort,
120this.packagerPort,
121);
0a68f8dbArtem Egorov8 years ago122
0d77292aJiglioNero4 years ago123await ensurePackagerRunning(this.packagerAddress, this.packagerPort, errPackagerNotRunning);
124
125const rnVersions = await ProjectVersionHelper.getReactNativeVersions(projectRootPath);
09f6024fHeniker4 years ago126const debuggerWorkerURL = this.prepareDebuggerWorkerURL(
0d77292aJiglioNero4 years ago127rnVersions.reactNativeVersion,
128debuggerWorkerUrlPath,
129);
09f6024fHeniker4 years ago130const debuggerWorkerLocalPath = path.join(
0d77292aJiglioNero4 years ago131sourcesStoragePath,
132ScriptImporter.DEBUGGER_WORKER_FILENAME,
133);
09f6024fHeniker4 years ago134logger.verbose(`About to download: ${debuggerWorkerURL} to: ${debuggerWorkerLocalPath}`);
0d77292aJiglioNero4 years ago135
136const body = await Request.request(debuggerWorkerURL, true);
137
138return new FileSystem().writeFile(debuggerWorkerLocalPath, body);
2743f19cdlebu10 years ago139}
140
cf911877Yuri Skorokhodov7 years ago141public prepareDebuggerWorkerURL(rnVersion: string, debuggerWorkerUrlPath?: string): string {
142let debuggerWorkerURL: string;
143// It can be empty string
144if (debuggerWorkerUrlPath !== undefined) {
145debuggerWorkerURL = `http://${this.packagerAddress}:${this.packagerPort}/${debuggerWorkerUrlPath}${ScriptImporter.DEBUGGER_WORKER_FILENAME}`;
146} else {
147let newPackager = "";
34472878RedMickey5 years ago148if (
149!semver.valid(
150rnVersion,
09f6024fHeniker4 years ago151) /* Custom RN implementations should support new packager*/ ||
47927908RedMickey4 years ago152semver.gte(rnVersion, ScriptImporter.DEBUGGER_UI_SUPPORTED_VERSION) ||
153ProjectVersionHelper.isCanaryVersion(rnVersion)
34472878RedMickey5 years ago154) {
cf911877Yuri Skorokhodov7 years ago155newPackager = "debugger-ui/";
156}
157debuggerWorkerURL = `http://${this.packagerAddress}:${this.packagerPort}/${newPackager}${ScriptImporter.DEBUGGER_WORKER_FILENAME}`;
158}
159return debuggerWorkerURL;
160}
161
e00f7325unknown10 years ago162/**
163* Writes the script file to the project temporary location.
164*/
0d77292aJiglioNero4 years ago165private async writeAppScript(scriptBody: string, scriptUrl: IStrictUrl): Promise<string> {
09f6024fHeniker4 years ago166const scriptFilePath = path.join(
167this.sourcesStoragePath,
168path.basename(scriptUrl.pathname),
169); // scriptFilePath = "$TMPDIR/index.ios.bundle"
0d77292aJiglioNero4 years ago170await new FileSystem().writeFile(scriptFilePath, scriptBody);
171return scriptFilePath;
3fb37ad5unknown10 years ago172}
173
e00f7325unknown10 years ago174/**
175* Writes the source map file to the project temporary location.
176*/
0d77292aJiglioNero4 years ago177private async writeAppSourceMap(
178sourceMapUrl: IStrictUrl,
179scriptUrl: IStrictUrl,
180): Promise<void> {
181const sourceMapBody = await Request.request(sourceMapUrl.href, true);
09f6024fHeniker4 years ago182const sourceMappingLocalPath = path.join(
0d77292aJiglioNero4 years ago183this.sourcesStoragePath,
184path.basename(sourceMapUrl.pathname),
185); // sourceMappingLocalPath = "$TMPDIR/index.ios.map"
09f6024fHeniker4 years ago186const scriptFileRelativePath = path.basename(scriptUrl.pathname); // scriptFileRelativePath = "index.ios.bundle"
187const updatedContent = this.sourceMapUtil.updateSourceMapFile(
0d77292aJiglioNero4 years ago188sourceMapBody,
189scriptFileRelativePath,
190this.sourcesStoragePath,
191this.packagerRemoteRoot,
192this.packagerLocalRoot,
193);
194return new FileSystem().writeFile(sourceMappingLocalPath, updatedContent);
3fb37ad5unknown10 years ago195}
5e651f3edigeff10 years ago196
197/**
198* Changes the port of the url to be the one configured as this.packagerPort
199*/
200private overridePackagerPort(urlToOverride: string): string {
09f6024fHeniker4 years ago201const components = url.parse(urlToOverride);
5e651f3edigeff10 years ago202components.port = this.packagerPort.toString();
203delete components.host; // We delete the host, if not the port change will be ignored
204return url.format(components);
205}
3fb37ad5unknown10 years ago206}