microsoft/vscode-react-native

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
db80cd4e10b83524bc77c15018effab72cbabeb8

Branches

Tags

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

Clone

HTTPS

Download ZIP

src/common/packager.ts

153lines · 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
c9b4fa6cMeena Kunnathur Balakrishnan10 years ago4import {ChildProcess} from "child_process";
b0061ac6Meena Kunnathur Balakrishnan10 years ago5import {CommandExecutor} from "./commandExecutor";
6import {Log, LogLevel} from "./log";
7import {Node} from "./node/node";
bef522ffMeena Kunnathur Balakrishnan10 years ago8import {OutputChannel} from "vscode";
35390151Meena Kunnathur Balakrishnan10 years ago9import {Package} from "./node/package";
b0061ac6Meena Kunnathur Balakrishnan10 years ago10import {PromiseUtil} from "./node/promise";
11import {Request} from "./node/request";
24aab397Meena Kunnathur Balakrishnan10 years ago12
3fb37ad5unknown10 years ago13import * as Q from "q";
4677921cdigeff10 years ago14import * as path from "path";
3fb37ad5unknown10 years ago15
16export class Packager {
418d8ac5digeff10 years ago17// TODO: Make the port configurable via a launch argument
18public static PORT = "8081";
19public static HOST = `localhost:${Packager.PORT}`;
1011f2a8Meena Kunnathur Balakrishnan10 years ago20
3fb37ad5unknown10 years ago21private projectPath: string;
c9b4fa6cMeena Kunnathur Balakrishnan10 years ago22private packagerProcess: ChildProcess;
3fb37ad5unknown10 years ago23
1011f2a8Meena Kunnathur Balakrishnan10 years ago24private static JS_INJECTOR_FILENAME = "opn-main.js";
e952a6f3Meena Kunnathur Balakrishnan10 years ago25private static JS_INJECTOR_FILEPATH = path.resolve(path.dirname(path.dirname(__dirname)), "js-patched", Packager.JS_INJECTOR_FILENAME);
1011f2a8Meena Kunnathur Balakrishnan10 years ago26private static NODE_MODULES_FODLER_NAME = "node_modules";
27private static OPN_PACKAGE_NAME = "opn";
28private static REACT_NATIVE_PACKAGE_NAME = "react-native";
29private static OPN_PACKAGE_MAIN_FILENAME = "index.js";
30
2743f19cdlebu10 years ago31constructor(projectPath: string) {
3fb37ad5unknown10 years ago32this.projectPath = projectPath;
33}
34
10873e11digeff10 years ago35
ec6e115dMeena Kunnathur Balakrishnan10 years ago36public start(outputChannel?: OutputChannel): Q.Promise<void> {
6126d899Meena Kunnathur Balakrishnan10 years ago37let executedStartPackagerCmd = false;
10873e11digeff10 years ago38return this.isRunning()
39.then(running => {
40if (!running) {
41return this.monkeyPatchOpnForRNPackager()
42.then(() => {
43let args = ["--port", Packager.PORT];
44let childEnvForDebugging = Object.assign({}, process.env, { REACT_DEBUGGER: "echo A debugger is not needed: " });
45
46Log.logMessage("Starting Packager", outputChannel);
47// The packager will continue running while we debug the application, so we can"t
48// wait for this command to finish
3fb37ad5unknown10 years ago49
10873e11digeff10 years ago50let spawnOptions = { env: childEnvForDebugging };
51
65fd8e85digeff10 years ago52// TODO #83 - PROMISE: We need to consume the result of this spawn
10873e11digeff10 years ago53new CommandExecutor(this.projectPath).spawnReactPackager(args, spawnOptions, outputChannel).then((packagerProcess) => {
54this.packagerProcess = packagerProcess;
55executedStartPackagerCmd = true;
56});
b031edc7digeff10 years ago57});
6126d899Meena Kunnathur Balakrishnan10 years ago58}
10873e11digeff10 years ago59})
60.then(() =>
61this.awaitStart())
62.then(() => {
63if (executedStartPackagerCmd) {
64Log.logMessage("Packager started.", outputChannel);
65} else {
66Log.logMessage("Packager is already running.", outputChannel);
67if (!outputChannel) {
65fd8e85digeff10 years ago68// TODO #83: This warning is printted incorrectly when the packager was started from the command palette. Fix it.
ce591c62digeff10 years ago69Log.logWarning("Debugging is not supported if the React Native Packager is not started within VS Code. If debugging fails, please kill other active React Native packager processes and retry.", outputChannel);
10873e11digeff10 years ago70}
71}
72});
3fb37ad5unknown10 years ago73}
2e15926eMeena Kunnathur Balakrishnan10 years ago74
a822ac85dlebu10 years ago75public stop(outputChannel?: OutputChannel): Q.Promise<void> {
10873e11digeff10 years ago76return new CommandExecutor(this.projectPath).killReactPackager(this.packagerProcess, outputChannel).then(() =>
77this.packagerProcess = null);
2e15926eMeena Kunnathur Balakrishnan10 years ago78}
b3a793eeNisheet Jain10 years ago79
418d8ac5digeff10 years ago80public prewarmBundleCache(platform: string) {
81let bundleURL = `http://${Packager.HOST}/index.${platform}.bundle`;
ea8a5f88digeff10 years ago82Log.logInternalMessage(LogLevel.Info, "About to get: " + bundleURL);
418d8ac5digeff10 years ago83return new Request().request(bundleURL, true).then(() => {
84Log.logMessage("The Bundle Cache was prewarmed.");
1b27c1ccJimmy Thomson10 years ago85}).catch(() => {
86// The attempt to prefetch the bundle failed.
87// This may be because the bundle is not index.* so we shouldn't treat this as fatal.
418d8ac5digeff10 years ago88});
89}
2ec44b6dNisheet Jain10 years ago90
b3a793eeNisheet Jain10 years ago91private isRunning(): Q.Promise<boolean> {
92let statusURL = `http://${Packager.HOST}/status`;
93
94return new Request().request(statusURL)
95.then((body: string) => {
96return body === "packager-status:running";
97},
98(error: any) => {
99return false;
100});
101}
102
103private awaitStart(retryCount = 30, delay = 2000): Q.Promise<boolean> {
104let pu: PromiseUtil = new PromiseUtil();
105return pu.retryAsync(() => this.isRunning(), (running) => running, retryCount, delay, "Could not start the packager.");
106}
107
1011f2a8Meena Kunnathur Balakrishnan10 years ago108private findOpnPackage(): Q.Promise<string> {
109try {
110let flatDependencyPackagePath = path.resolve(this.projectPath, Packager.NODE_MODULES_FODLER_NAME,
111Packager.OPN_PACKAGE_NAME, Packager.OPN_PACKAGE_MAIN_FILENAME);
112
113let nestedDependencyPackagePath = path.resolve(this.projectPath, Packager.NODE_MODULES_FODLER_NAME,
114Packager.REACT_NATIVE_PACKAGE_NAME, Packager.NODE_MODULES_FODLER_NAME, Packager.OPN_PACKAGE_NAME, Packager.OPN_PACKAGE_MAIN_FILENAME);
115
116let fsHelper = new Node.FileSystem();
117
118// Attempt to find the 'opn' package directly under the project's node_modules folder (node4 +)
119// Else, attempt to find the package within the dependent node_modules of react-native package
61c4db14Meena Kunnathur Balakrishnan10 years ago120let possiblePaths = [flatDependencyPackagePath, nestedDependencyPackagePath];
e33d2cabdigeff10 years ago121return Q.any(possiblePaths.map(path =>
122fsHelper.exists(path).then(exists =>
123exists
124? Q.resolve(path)
125: Q.reject<string>("opn package location not found"))));
1011f2a8Meena Kunnathur Balakrishnan10 years ago126} catch (err) {
b031edc7digeff10 years ago127console.error("The package \'opn\' was not found." + err);
1011f2a8Meena Kunnathur Balakrishnan10 years ago128}
129}
130
131private monkeyPatchOpnForRNPackager(): Q.Promise<void> {
61c4db14Meena Kunnathur Balakrishnan10 years ago132let opnPackage: Package;
1011f2a8Meena Kunnathur Balakrishnan10 years ago133let destnFilePath: string;
134
135// Finds the 'opn' package
136return this.findOpnPackage()
b031edc7digeff10 years ago137.then((opnIndexFilePath) => {
138destnFilePath = opnIndexFilePath;
139// Read the package's "package.json"
140opnPackage = new Package(path.resolve(path.dirname(destnFilePath)));
141return opnPackage.parsePackageInformation();
142}).then((packageJson) => {
143if (packageJson.main !== Packager.JS_INJECTOR_FILENAME) {
144// Copy over the patched 'opn' main file
145return new Node.FileSystem().copyFile(Packager.JS_INJECTOR_FILEPATH, path.resolve(path.dirname(destnFilePath), Packager.JS_INJECTOR_FILENAME))
146.then(() => {
147// Write/over-write the "main" attribute with the new file
148return opnPackage.setMainFile(Packager.JS_INJECTOR_FILENAME);
149});
150}
151});
1011f2a8Meena Kunnathur Balakrishnan10 years ago152}
eb113a1fdlebu10 years ago153}