microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
866c9c46d66b8319cb786723bf6c222aa5caddb8

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/debugger/launcher.ts

102lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as fs from "fs";
5import * as path from "path";
6import * as Q from "q";
7import {MultipleLifetimesAppWorker} from "./appWorker";
8import {Log} from "../common/log/log";
9import {ErrorHelper} from "../common/error/errorHelper";
10import {InternalErrorCode} from "../common/error/internalErrorCode";
11import {ScriptImporter} from "./scriptImporter";
12import {PlatformResolver} from "./platformResolver";
13import {TelemetryHelper} from "../common/telemetryHelper";
14import {IRunOptions} from "../common/launchArgs";
15import * as em from "../common/extensionMessaging";
16import {EntryPointHandler} from "../common/entryPointHandler";
17
18export class Launcher {
19 private projectRootPath: string;
20 private extensionMessageSender = new em.ExtensionMessageSender();
21
22 constructor(projectRootPath: string) {
23 this.projectRootPath = projectRootPath;
24 }
25
26 public launch(): void {
27 // Enable telemetry
28 new EntryPointHandler(true).runApp("react-native-debug-process", () => this.getAppVersion(),
29 ErrorHelper.getInternalError(InternalErrorCode.DebuggingFailed), () => {
30 return TelemetryHelper.generate("launch", (generator) => {
31 const resolver = new PlatformResolver();
32 return this.parseRunOptions().then(runOptions => {
33 const mobilePlatform = resolver.resolveMobilePlatform(runOptions.platform);
34 if (!mobilePlatform) {
35 throw new RangeError("The target platform could not be read. Did you forget to add it to the launch.json configuration arguments?");
36 } else {
37 const sourcesStoragePath = path.join(this.projectRootPath, ".vscode", ".react");
38 let extensionMessageSender = new em.ExtensionMessageSender();
39 return Q({})
40 .then(() => {
41 generator.step("startPackager");
42 return extensionMessageSender.sendMessage(em.ExtensionMessage.START_PACKAGER);
43 })
44 .then(() => {
45 let scriptImporter = new ScriptImporter(runOptions.packagerPort, sourcesStoragePath);
46 return scriptImporter.downloadDebuggerWorker(sourcesStoragePath).then(() => {
47 Log.logMessage("Downloaded debuggerWorker.js (Logic to run the React Native app) from the Packager.");
48 });
49 })
50 // We've seen that if we don't prewarm the bundle cache, the app fails on the first attempt to connect to the debugger logic
51 // and the user needs to Reload JS manually. We prewarm it to prevent that issue
52 .then(() => {
53 generator.step("prewarmBundleCache");
54 Log.logMessage("Prewarming bundle cache. This may take a while ...");
55 return extensionMessageSender.sendMessage(em.ExtensionMessage.PREWARM_BUNDLE_CACHE, [runOptions.platform]);
56 })
57 .then(() => {
58 generator.step("mobilePlatform.runApp");
59 Log.logMessage("Building and running application.");
60 return mobilePlatform.runApp(runOptions);
61 })
62 .then(() => {
63 generator.step("Starting App Worker");
64 Log.logMessage("Starting debugger app worker.");
65 return new MultipleLifetimesAppWorker(runOptions.packagerPort, sourcesStoragePath, runOptions.debugAdapterPort).start();
66 }) // Start the app worker
67 .then(() => {
68 generator.step("mobilePlatform.enableJSDebuggingMode");
69 return mobilePlatform.enableJSDebuggingMode(runOptions);
70 }).then(() =>
71 Log.logMessage("Debugging session started successfully."));
72 }
73 });
74 });
75 });
76 }
77
78 private getAppVersion() {
79 return JSON.parse(fs.readFileSync(path.join(__dirname, "..", "..", "package.json"), "utf-8")).version;
80 }
81
82 private getPackagerPort(): Q.Promise<number> {
83 return this.extensionMessageSender.sendMessage(em.ExtensionMessage.GET_PACKAGER_PORT);
84 }
85
86 /**
87 * Parses the launch arguments set in the launch configuration.
88 */
89 private parseRunOptions(): Q.Promise<IRunOptions> {
90 // We expect our debugAdapter to pass in arguments as [platform, debugAdapterPort, target?, logCatArguments?];
91 return this.getPackagerPort().then(packagerPort => {
92 return {
93 projectRoot: this.projectRootPath,
94 platform: process.argv[2].toLowerCase(),
95 debugAdapterPort: parseInt(process.argv[3], 10) || 9090,
96 target: process.argv[4],
97 packagerPort: packagerPort,
98 logCatArguments: process.argv[5],
99 };
100 });
101 }
102}
103