microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
4b124a08cf4726fc4b6b1f843dcd24e31f33db5e

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/rn-extension.ts

168lines · 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";
5
6// @ifdef DEBUG
7try {
8 fs.statSync(`${__filename}.map`); // We check if source maps are available
9 /* tslint:disable:no-var-requires */
10 require("source-map-support").install(); // If they are, we enable stack traces translation to typescript
11 /* tslint:enable:no-var-requires */
12} catch (exceptions) {
13 // If something goes wrong, we just ignore the errors
14}
15// @endif
16
17import * as Q from "q";
18import * as path from "path";
19import * as vscode from "vscode";
20
21import {FileSystem} from "../common/node/fileSystem";
22import {CommandPaletteHandler} from "./commandPaletteHandler";
23import {Packager} from "../common/packager";
24import {EntryPointHandler, ProcessType} from "../common/entryPointHandler";
25import {ErrorHelper} from "../common/error/errorHelper";
26import {InternalError} from "../common/error/internalError";
27import {InternalErrorCode} from "../common/error/internalErrorCode";
28import {Log} from "../common/log/log";
29import {PackagerStatusIndicator} from "./packagerStatusIndicator";
30import {ReactNativeProjectHelper} from "../common/reactNativeProjectHelper";
31import {ReactDirManager} from "./reactDirManager";
32import {IntellisenseHelper} from "./intellisenseHelper";
33import {Telemetry} from "../common/telemetry";
34import {TelemetryHelper} from "../common/telemetryHelper";
35import {ExtensionServer} from "./extensionServer";
36import {OutputChannelLogger} from "./outputChannelLogger";
37
38/* all components use the same packager instance */
39const projectRootPath = vscode.workspace.rootPath;
40const globalPackager = new Packager(projectRootPath);
41const packagerStatusIndicator = new PackagerStatusIndicator();
42const commandPaletteHandler = new CommandPaletteHandler(projectRootPath, globalPackager, packagerStatusIndicator);
43
44const outputChannelLogger = new OutputChannelLogger(vscode.window.createOutputChannel("React-Native"));
45const entryPointHandler = new EntryPointHandler(ProcessType.Extension, outputChannelLogger);
46const reactNativeProjectHelper = new ReactNativeProjectHelper(projectRootPath);
47const fsUtil = new FileSystem();
48
49interface ISetupableDisposable extends vscode.Disposable {
50 setup(): Q.Promise<any>;
51}
52
53export function activate(context: vscode.ExtensionContext): void {
54 entryPointHandler.runApp("react-native", () => <string>require("../../package.json").version,
55 ErrorHelper.getInternalError(InternalErrorCode.ExtensionActivationFailed), projectRootPath, () => {
56 return reactNativeProjectHelper.isReactNativeProject()
57 .then(isRNProject => {
58 if (isRNProject) {
59 let activateExtensionEvent = TelemetryHelper.createTelemetryEvent("activate");
60 Telemetry.send(activateExtensionEvent);
61
62 warnWhenReactNativeVersionIsNotSupported();
63 entryPointHandler.runFunction("debugger.setupLauncherStub",
64 ErrorHelper.getInternalError(InternalErrorCode.DebuggerStubLauncherFailed), () =>
65 setupReactNativeDebugger()
66 .then(() =>
67 setupAndDispose(new ReactDirManager(), context))
68 .then(() =>
69 setupAndDispose(new ExtensionServer(projectRootPath, globalPackager, packagerStatusIndicator), context))
70 .then(() => {}));
71 entryPointHandler.runFunction("intelliSense.setup",
72 ErrorHelper.getInternalError(InternalErrorCode.IntellisenseSetupFailed), () =>
73 IntellisenseHelper.setupReactNativeIntellisense());
74 }
75 entryPointHandler.runFunction("debugger.setupNodeDebuggerLocation",
76 ErrorHelper.getInternalError(InternalErrorCode.NodeDebuggerConfigurationFailed), () =>
77 configureNodeDebuggerLocation());
78 registerReactNativeCommands(context);
79 });
80 });
81}
82
83export function deactivate(): void {
84 // Kill any packager processes that we spawned
85 entryPointHandler.runFunction("extension.deactivate",
86 ErrorHelper.getInternalError(InternalErrorCode.FailedToStopPackagerOnExit),
87 () => {
88 commandPaletteHandler.stopPackager();
89 }, /*errorsAreFatal*/ true);
90}
91
92function configureNodeDebuggerLocation(): Q.Promise<void> {
93 const nodeDebugExtension = vscode.extensions.getExtension("ms-vscode.node-debug") // We try to get the new version
94 || vscode.extensions.getExtension("andreweinand.node-debug"); // If it's not available, we try to get the old version
95 if (!nodeDebugExtension) {
96 return Q.reject<void>(ErrorHelper.getInternalError(InternalErrorCode.CouldNotFindLocationOfNodeDebugger));
97 }
98 const nodeDebugPath = nodeDebugExtension.extensionPath;
99 return fsUtil.writeFile(path.resolve(__dirname, "../", "debugger", "nodeDebugLocation.json"), JSON.stringify({ nodeDebugPath }));
100}
101
102function setupAndDispose<T extends ISetupableDisposable>(setuptableDisposable: T, context: vscode.ExtensionContext): Q.Promise<T> {
103 return setuptableDisposable.setup()
104 .then(() => {
105 context.subscriptions.push(setuptableDisposable);
106 return setuptableDisposable;
107 });
108}
109
110function warnWhenReactNativeVersionIsNotSupported(): void {
111 return reactNativeProjectHelper.validateReactNativeVersion().done(() => { }, reason => {
112 TelemetryHelper.sendSimpleEvent("unsupportedRNVersion", { rnVersion: reason });
113 const shortMessage = `React Native Tools need React Native version 0.19.0 or later to be installed in <PROJECT_ROOT>/node_modules/`;
114 const longMessage = `${shortMessage}: ${reason}`;
115 vscode.window.showWarningMessage(shortMessage);
116 Log.logMessage(longMessage);
117 });
118}
119
120function registerReactNativeCommands(context: vscode.ExtensionContext): void {
121 // Register React Native commands
122 registerVSCodeCommand(context, "runAndroid", ErrorHelper.getInternalError(InternalErrorCode.FailedToRunOnAndroid), () => commandPaletteHandler.runAndroid());
123 registerVSCodeCommand(context, "runIos", ErrorHelper.getInternalError(InternalErrorCode.FailedToRunOnIos), () => commandPaletteHandler.runIos());
124 registerVSCodeCommand(context, "startPackager", ErrorHelper.getInternalError(InternalErrorCode.FailedToStartPackager), () => commandPaletteHandler.startPackager());
125 registerVSCodeCommand(context, "stopPackager", ErrorHelper.getInternalError(InternalErrorCode.FailedToStopPackager), () => commandPaletteHandler.stopPackager());
126}
127
128function registerVSCodeCommand(
129 context: vscode.ExtensionContext, commandName: string,
130 error: InternalError, commandHandler: () => Q.Promise<void>): void {
131 context.subscriptions.push(vscode.commands.registerCommand(
132 `reactNative.${commandName}`,
133 () =>
134 entryPointHandler.runFunction(
135 `commandPalette.${commandName}`, error,
136 commandHandler)));
137}
138
139/**
140 * Sets up the debugger for the React Native project by dropping
141 * the debugger stub into the workspace
142 */
143function setupReactNativeDebugger(): Q.Promise<void> {
144 const launcherPath = require.resolve("../debugger/launcher");
145 const pkg = require("../../package.json");
146 const extensionVersionNumber = pkg.version;
147 const extensionName = pkg.name;
148
149 let debuggerEntryCode =
150 `// This file is automatically generated by ${extensionName}@${extensionVersionNumber}
151// Please do not modify it manually. All changes will be lost.
152try {
153 var path = require("path");
154 var Launcher = require(${JSON.stringify(launcherPath)}).Launcher;
155 new Launcher(path.resolve(__dirname, "..")).launch();
156} catch (e) {
157 throw new Error("Unable to launch application. Try deleting .vscode/launchReactNative.js and restarting vscode.");
158}`;
159
160 const vscodeFolder = path.join(projectRootPath, ".vscode");
161 const debugStub = path.join(vscodeFolder, "launchReactNative.js");
162
163 return fsUtil.ensureDirectory(vscodeFolder)
164 .then(() => fsUtil.ensureFileWithContents(debugStub, debuggerEntryCode))
165 .catch((err: Error) => {
166 vscode.window.showErrorMessage(err.message);
167 });
168}