From 89095946cff051c5613b8f54ec722d08cd47c709 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Fri, 7 Nov 2025 19:57:22 +0000 Subject: [PATCH] fix(language-service): address potential memory leak during project creation This addresses a potential memory leak in plugin-factory.ts. The require call inside the create function reloads the entire language service module for every new project, which is inefficient and could be a cause of the memory leak during branch switching. This ensures the module is loaded only once and the same instance is shared across all projects. (cherry picked from commit 440572594358bb3cd04b3e61fa7e8c4ce527f133) --- packages/language-service/plugin-factory.ts | 3 +-- vscode-ng-language-service/server/src/session.ts | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/language-service/plugin-factory.ts b/packages/language-service/plugin-factory.ts index 116059511d2..876ca87f34c 100644 --- a/packages/language-service/plugin-factory.ts +++ b/packages/language-service/plugin-factory.ts @@ -21,8 +21,7 @@ export const factory: ts.server.PluginModuleFactory = (tsModule): PluginModule = return { create(info: ts.server.PluginCreateInfo): NgLanguageService { - // Use a module name based import path to allow it to be marked external. - plugin = require(`@angular/language-service/bundles/language-service.js`)(tsModule); + plugin ??= require(`@angular/language-service/bundles/language-service.js`)(tsModule); return plugin.create(info); }, getExternalFiles(project: ts.server.Project): string[] { diff --git a/vscode-ng-language-service/server/src/session.ts b/vscode-ng-language-service/server/src/session.ts index 2bb75a712e7..440203bfc64 100644 --- a/vscode-ng-language-service/server/src/session.ts +++ b/vscode-ng-language-service/server/src/session.ts @@ -706,6 +706,11 @@ export class Session { this.triggerDiagnostics(event.data.openFiles, event.eventName); break; case ts.server.ProjectLanguageServiceStateEvent: + this.logger.info( + `Project language service state changed for ${event.data.project.getProjectName()}. Enabled: ${ + event.data.languageServiceEnabled + }`, + ); this.connection.sendNotification(ProjectLanguageService, { projectName: event.data.project.getProjectName(), languageServiceEnabled: event.data.languageServiceEnabled, @@ -969,6 +974,7 @@ export class Session { if (!filePath) { return; } + this.logger.info(`Closing file: ${filePath}`); this.openFiles.delete(filePath); this.projectService.closeClientFile(filePath); }