microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
8408d326facd026be34282fa91cc873b2abd7246

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/extension/rn-extension.ts

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