From 80d9baadc0e2728ac91e701d1787ca0313b745c8 Mon Sep 17 00:00:00 2001 From: Asher Date: Fri, 22 Feb 2019 18:54:02 -0600 Subject: [PATCH] Attempt to require spdlog and node-pty --- packages/protocol/src/common/helpers.ts | 48 +++++++++++++++++++++---- packages/vscode/src/fill/node-pty.ts | 8 ++--- packages/vscode/src/fill/spdlog.ts | 4 +-- 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/packages/protocol/src/common/helpers.ts b/packages/protocol/src/common/helpers.ts index 20d89dd..1a3f082 100644 --- a/packages/protocol/src/common/helpers.ts +++ b/packages/protocol/src/common/helpers.ts @@ -7,6 +7,9 @@ import { logger } from "@coder/logger"; // tslint:disable no-any +declare var __non_webpack_require__: typeof require; +declare var __webpack_require__: typeof require; + export type ForkProvider = (modulePath: string, args: string[], options: ForkOptions) => ChildProcess; export interface Disposer extends IDisposable { @@ -20,7 +23,7 @@ interface ActiveEvalEmitter { } /** - * Helper class for evaluations. + * Helper class for server-side evaluations. */ export class EvalHelper { /** @@ -35,15 +38,36 @@ export class EvalHelper { options.env = { ...process.env, ...options.env }; } } + + /** + * Try a non-webpack require, then a webpack require if that fails. + */ + public require(modulePath: string): any { + logger.info(`Attempting to require ${modulePath}`); + try { + return __non_webpack_require__(modulePath); + } catch (error) { /* Nothing. */ } + + logger.warn(`Non-webpack require failed for ${modulePath}`); + try { + return __webpack_require__(modulePath); + } catch (error) { /* Nothing. */ } + + logger.warn(`Webpack require failed for ${modulePath}`); + try { + return require(modulePath); + } catch (error) { + logger.error(`Failed to require ${modulePath}`); + throw error; + } + } } /** - * Helper class for active evaluations. + * Helper class for client-side active evaluations. */ -export class ActiveEvalHelper extends EvalHelper implements ActiveEvalEmitter { - public constructor(private readonly emitter: ActiveEvalEmitter) { - super(); - } +export class ActiveEvalHelper implements ActiveEvalEmitter { + public constructor(private readonly emitter: ActiveEvalEmitter) {} public removeAllListeners(event?: string): void { this.emitter.removeAllListeners(event); @@ -100,9 +124,19 @@ export class ActiveEvalHelper extends EvalHelper implements ActiveEvalEmitter { /** * Helper class for server-side active evaluations. */ -export class ServerActiveEvalHelper extends ActiveEvalHelper { +export class ServerActiveEvalHelper extends ActiveEvalHelper implements EvalHelper { + private readonly evalHelper: EvalHelper; public constructor(emitter: ActiveEvalEmitter, public readonly fork: ForkProvider) { super(emitter); + this.evalHelper = new EvalHelper(); + } + + public preserveEnv(options: SpawnOptions | ForkOptions): void { + this.evalHelper.preserveEnv(options); + } + + public require(modulePath: string): any { + return this.evalHelper.require(modulePath); } /** diff --git a/packages/vscode/src/fill/node-pty.ts b/packages/vscode/src/fill/node-pty.ts index ae2e1db..4da5934 100644 --- a/packages/vscode/src/fill/node-pty.ts +++ b/packages/vscode/src/fill/node-pty.ts @@ -2,9 +2,7 @@ import { client } from "@coder/ide/src/fill/client"; import { EventEmitter } from "events"; import * as nodePty from "node-pty"; import { ActiveEvalHelper } from "@coder/protocol"; - -// Use this to prevent Webpack from hijacking require. -declare var __non_webpack_require__: typeof require; +import { logger } from "@coder/logger"; /** * Implementation of nodePty for the browser. @@ -17,7 +15,7 @@ class Pty implements nodePty.IPty { public constructor(file: string, args: string[] | string, options: nodePty.IPtyForkOptions) { this.ae = client.run((ae, file, args, options) => { - const nodePty = __non_webpack_require__("node-pty") as typeof import("node-pty"); + const nodePty = ae.require("node-pty") as typeof import("node-pty"); ae.preserveEnv(options); @@ -54,6 +52,8 @@ class Pty implements nodePty.IPty { }; }, file, args, options); + this.ae.on("error", (error) => logger.error(error.message)); + this.ae.on("pid", (pid) => this._pid = pid); this.ae.on("process", (process) => this._process = process); diff --git a/packages/vscode/src/fill/spdlog.ts b/packages/vscode/src/fill/spdlog.ts index 4be1f75..876dfa6 100644 --- a/packages/vscode/src/fill/spdlog.ts +++ b/packages/vscode/src/fill/spdlog.ts @@ -3,10 +3,8 @@ import { RotatingLogger as NodeRotatingLogger } from "spdlog"; import { logger } from "@coder/logger"; import { client } from "@coder/ide/src/fill/client"; -declare var __non_webpack_require__: typeof require; - const ae = client.run((ae) => { - const spdlog = __non_webpack_require__("spdlog") as typeof import("spdlog"); + const spdlog = ae.require("spdlog") as typeof import("spdlog"); const loggers = new Map(); ae.on("new", (id: number, name: string, filePath: string, fileSize: number, fileCount: number) => {