From 6a8a2d9b225022cb59693f9af6aedeeb12466437 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Wed, 3 Mar 2021 21:38:39 -0800 Subject: [PATCH] fix: do not watch directories in google3 In google3, all the dependencies of a TypeScript program are known ahead of time and they are listed in `tsconfig.json`. For this reason, there is no need to watch `node_modules` directory. Tsserver in google3 has additonal patch that explicitly prohibits watching directories that start with `/google/src`. This was not detected during development because we did not actually use the TypeScript module specified in `typescript.tsdk`. The dynamic loading of the `typescript` module requires the server code to be compiled in AMD first, which happens only during the production build. --- server/src/server.ts | 7 ++++--- server/src/server_host.ts | 9 ++++++++- server/src/session.ts | 6 +++--- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/server/src/server.ts b/server/src/server.ts index 194240e6bd..2b0a1cbfcb 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -29,8 +29,10 @@ const logger = createLogger({ const ts = resolveTsServer(options.tsProbeLocations); const ng = resolveNgLangSvc(options.ngProbeLocations, options.ivy); +const isG3 = ts.resolvedPath.includes('/google3/'); + // ServerHost provides native OS functionality -const host = new ServerHost(); +const host = new ServerHost(isG3); // Establish a new server session that encapsulates lsp connection. const session = new Session({ @@ -39,8 +41,7 @@ const session = new Session({ // TypeScript allows only package names as plugin names. ngPlugin: '@angular/language-service', resolvedNgLsPath: ng.resolvedPath, - resolvedTsLsPath: ts.resolvedPath, - ivy: options.ivy, + ivy: isG3 ? true : options.ivy, logToConsole: options.logToConsole, }); diff --git a/server/src/server_host.ts b/server/src/server_host.ts index 698227718c..8407d3d2f9 100644 --- a/server/src/server_host.ts +++ b/server/src/server_host.ts @@ -8,6 +8,10 @@ import * as ts from 'typescript/lib/tsserverlibrary'; +const NOOP_WATCHER: ts.FileWatcher = { + close() {}, +}; + /** * `ServerHost` is a wrapper around `ts.sys` for the Node system. In Node, all * optional methods of `ts.System` are implemented. @@ -19,7 +23,7 @@ export class ServerHost implements ts.server.ServerHost { readonly newLine: string; readonly useCaseSensitiveFileNames: boolean; - constructor() { + constructor(readonly isG3: boolean) { this.args = ts.sys.args; this.newLine = ts.sys.newLine; this.useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames; @@ -56,6 +60,9 @@ export class ServerHost implements ts.server.ServerHost { watchDirectory(path: string, callback: ts.DirectoryWatcherCallback, recursive?: boolean): ts.FileWatcher { + if (this.isG3 && path.startsWith('/google/src')) { + return NOOP_WATCHER; + } return ts.sys.watchDirectory!(path, callback, recursive); } diff --git a/server/src/session.ts b/server/src/session.ts index 840b7b7190..3518273cac 100644 --- a/server/src/session.ts +++ b/server/src/session.ts @@ -7,6 +7,7 @@ */ import {isNgLanguageService, NgLanguageService, PluginConfig} from '@angular/language-service/api'; +import * as assert from 'assert'; import * as ts from 'typescript/lib/tsserverlibrary'; import * as lsp from 'vscode-languageserver/node'; @@ -27,7 +28,6 @@ export interface SessionOptions { logger: ts.server.Logger; ngPlugin: string; resolvedNgLsPath: string; - resolvedTsLsPath: string; ivy: boolean; logToConsole: boolean; } @@ -115,8 +115,8 @@ export class Session { angularOnly: true, ivy: options.ivy, }; - if (options.resolvedTsLsPath.includes('/google3/')) { - pluginConfig.ivy = true; + if (options.host.isG3) { + assert(options.ivy === true, 'Ivy LS must be used in google3'); pluginConfig.forceStrictTemplates = true; } projSvc.configurePlugin({