microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
4f7b3bc0b2dffacee9487be46ec8f710ac83a8eb

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/scriptImporter.ts

139lines · 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
b0061ac6Meena Kunnathur Balakrishnan10 years ago4import {FileSystem} from "../common/node/fileSystem";
0a68f8dbArtem Egorov8 years ago5import { logger } from "vscode-chrome-debug-core";
6import { ensurePackagerRunning } from "../common/packagerStatus";
3fb37ad5unknown10 years ago7import path = require("path");
8import Q = require("q");
b0061ac6Meena Kunnathur Balakrishnan10 years ago9import {Request} from "../common/node/request";
10import {SourceMapUtil} from "./sourceMap";
3fb37ad5unknown10 years ago11import url = require("url");
a1324704Artem Egorov8 years ago12import * as semver from "semver";
13import {ReactNativeProjectHelper} from "../common/reactNativeProjectHelper";
3fb37ad5unknown10 years ago14
5c8365a6Artem Egorov8 years ago15export interface DownloadedScript {
4677921cdigeff10 years ago16contents: string;
17filepath: string;
18}
19
5c8365a6Artem Egorov8 years ago20interface IStrictUrl extends url.Url {
21pathname: string;
22href: string;
23}
24
3fb37ad5unknown10 years ago25export class ScriptImporter {
2743f19cdlebu10 years ago26public static DEBUGGER_WORKER_FILE_BASENAME = "debuggerWorker";
27public static DEBUGGER_WORKER_FILENAME = ScriptImporter.DEBUGGER_WORKER_FILE_BASENAME + ".js";
6eeec3c0Serge Svekolnikov8 years ago28private packagerAddress: string;
e3ae4227digeff10 years ago29private packagerPort: number;
4677921cdigeff10 years ago30private sourcesStoragePath: string;
6eeec3c0Serge Svekolnikov8 years ago31private packagerRemoteRoot?: string;
32private packagerLocalRoot?: string;
4bd0c669dlebu10 years ago33private sourceMapUtil: SourceMapUtil;
3fb37ad5unknown10 years ago34
6eeec3c0Serge Svekolnikov8 years ago35constructor(packagerAddress: string, packagerPort: number, sourcesStoragePath: string, packagerRemoteRoot?: string, packagerLocalRoot?: string) {
36this.packagerAddress = packagerAddress;
e3ae4227digeff10 years ago37this.packagerPort = packagerPort;
4677921cdigeff10 years ago38this.sourcesStoragePath = sourcesStoragePath;
6eeec3c0Serge Svekolnikov8 years ago39this.packagerRemoteRoot = packagerRemoteRoot;
40this.packagerLocalRoot = packagerLocalRoot;
4bd0c669dlebu10 years ago41this.sourceMapUtil = new SourceMapUtil();
3fb37ad5unknown10 years ago42}
43
979d7bfemax-mironov8 years ago44public downloadAppScript(scriptUrlString: string, projectRootPath: string): Q.Promise<DownloadedScript> {
1c32fe84Patricio Beltran9 years ago45const parsedScriptUrl = url.parse(scriptUrlString);
46const overriddenScriptUrlString = (parsedScriptUrl.hostname === "localhost") ? this.overridePackagerPort(scriptUrlString) : scriptUrlString;
e00f7325unknown10 years ago47// We'll get the source code, and store it locally to have a better debugging experience
833e37c7Vladimir Kotikov8 years ago48return Request.request(overriddenScriptUrlString, true).then(scriptBody => {
979d7bfemax-mironov8 years ago49return ReactNativeProjectHelper.getReactNativeVersion(projectRootPath).then(rnVersion => {
50// unfortunatelly Metro Bundler is broken in RN 0.54.x versions, so use this workaround unless it will be fixed
51// https://github.com/facebook/metro/issues/147
52// https://github.com/Microsoft/vscode-react-native/issues/660
53if (ReactNativeProjectHelper.getRNVersionsWithBrokenMetroBundler().indexOf(rnVersion) >= 0) {
54let noSourceMappingUrlGenerated = scriptBody.match(/sourceMappingURL=/g) === null;
55if (noSourceMappingUrlGenerated) {
56let sourceMapPathUrl = overriddenScriptUrlString.replace("bundle", "map");
57scriptBody = this.sourceMapUtil.appendSourceMapPaths(scriptBody, sourceMapPathUrl);
58}
59}
e00f7325unknown10 years ago60
979d7bfemax-mironov8 years ago61// Extract sourceMappingURL from body
62let scriptUrl = <IStrictUrl>url.parse(overriddenScriptUrlString); // scriptUrl = "http://localhost:8081/index.ios.bundle?platform=ios&dev=true"
63let sourceMappingUrl = this.sourceMapUtil.getSourceMapURL(scriptUrl, scriptBody); // sourceMappingUrl = "http://localhost:8081/index.ios.map?platform=ios&dev=true"
4677921cdigeff10 years ago64
979d7bfemax-mironov8 years ago65let waitForSourceMapping = Q<void>(void 0);
66if (sourceMappingUrl) {
67/* handle source map - request it and store it locally */
68waitForSourceMapping = this.writeAppSourceMap(sourceMappingUrl, scriptUrl)
69.then(() => {
70scriptBody = this.sourceMapUtil.updateScriptPaths(scriptBody, <IStrictUrl>sourceMappingUrl);
71});
72}
73
74return waitForSourceMapping
2743f19cdlebu10 years ago75.then(() => this.writeAppScript(scriptBody, scriptUrl))
4677921cdigeff10 years ago76.then((scriptFilePath: string) => {
0a68f8dbArtem Egorov8 years ago77logger.verbose(`Script ${overriddenScriptUrlString} downloaded to ${scriptFilePath}`);
4677921cdigeff10 years ago78return { contents: scriptBody, filepath: scriptFilePath };
876df2a0dlebu10 years ago79});
979d7bfemax-mironov8 years ago80});
e00f7325unknown10 years ago81});
82}
83
a1324704Artem Egorov8 years ago84public downloadDebuggerWorker(sourcesStoragePath: string, projectRootPath: string): Q.Promise<void> {
0a68f8dbArtem Egorov8 years ago85const errPackagerNotRunning = new RangeError(`Cannot attach to packager. Are you sure there is a packager and it is running in the port ${this.packagerPort}? If your packager is configured to run in another port make sure to add that to the setting.json.`);
86
6eeec3c0Serge Svekolnikov8 years ago87return ensurePackagerRunning(this.packagerAddress, this.packagerPort, errPackagerNotRunning)
0a68f8dbArtem Egorov8 years ago88.then(() => {
a1324704Artem Egorov8 years ago89return ReactNativeProjectHelper.getReactNativeVersion(projectRootPath);
90})
91.then((rnVersion: string) => {
92let newPackager = "";
bb869343Serge Svekolnikov8 years ago93const isHaulProject = ReactNativeProjectHelper.isHaulProject(projectRootPath);
94if (semver.gte(rnVersion, "0.50.0") && !isHaulProject) {
a1324704Artem Egorov8 years ago95newPackager = "debugger-ui/";
96}
97let debuggerWorkerURL = `http://${this.packagerAddress}:${this.packagerPort}/${newPackager}${ScriptImporter.DEBUGGER_WORKER_FILENAME}`;
0a68f8dbArtem Egorov8 years ago98let debuggerWorkerLocalPath = path.join(sourcesStoragePath, ScriptImporter.DEBUGGER_WORKER_FILENAME);
99logger.verbose("About to download: " + debuggerWorkerURL + " to: " + debuggerWorkerLocalPath);
100
101return Request.request(debuggerWorkerURL, true)
102.then((body: string) => {
299b0557Patricio Beltran10 years ago103return new FileSystem().writeFile(debuggerWorkerLocalPath, body);
104});
105});
2743f19cdlebu10 years ago106}
107
e00f7325unknown10 years ago108/**
109* Writes the script file to the project temporary location.
110*/
5c8365a6Artem Egorov8 years ago111private writeAppScript(scriptBody: string, scriptUrl: IStrictUrl): Q.Promise<String> {
bb77358cMark Oswald10 years ago112let scriptFilePath = path.join(this.sourcesStoragePath, path.basename(scriptUrl.pathname)); // scriptFilePath = "$TMPDIR/index.ios.bundle"
f218397cdlebu10 years ago113return new FileSystem().writeFile(scriptFilePath, scriptBody)
114.then(() => scriptFilePath);
3fb37ad5unknown10 years ago115}
116
e00f7325unknown10 years ago117/**
118* Writes the source map file to the project temporary location.
119*/
5c8365a6Artem Egorov8 years ago120private writeAppSourceMap(sourceMapUrl: IStrictUrl, scriptUrl: IStrictUrl): Q.Promise<void> {
833e37c7Vladimir Kotikov8 years ago121return Request.request(sourceMapUrl.href, true)
e00f7325unknown10 years ago122.then((sourceMapBody: string) => {
bb77358cMark Oswald10 years ago123let sourceMappingLocalPath = path.join(this.sourcesStoragePath, path.basename(sourceMapUrl.pathname)); // sourceMappingLocalPath = "$TMPDIR/index.ios.map"
124let scriptFileRelativePath = path.basename(scriptUrl.pathname); // scriptFileRelativePath = "index.ios.bundle"
6eeec3c0Serge Svekolnikov8 years ago125let updatedContent = this.sourceMapUtil.updateSourceMapFile(sourceMapBody, scriptFileRelativePath, this.sourcesStoragePath, this.packagerRemoteRoot, this.packagerLocalRoot);
f218397cdlebu10 years ago126return new FileSystem().writeFile(sourceMappingLocalPath, updatedContent);
e00f7325unknown10 years ago127});
3fb37ad5unknown10 years ago128}
5e651f3edigeff10 years ago129
130/**
131* Changes the port of the url to be the one configured as this.packagerPort
132*/
133private overridePackagerPort(urlToOverride: string): string {
134let components = url.parse(urlToOverride);
135components.port = this.packagerPort.toString();
136delete components.host; // We delete the host, if not the port change will be ignored
137return url.format(components);
138}
3fb37ad5unknown10 years ago139}