From 2202d82e6ad58400d4ca3f801315f190ddb51a6c Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 27 Oct 2023 18:03:00 +0800 Subject: [PATCH 1/6] feat: Import typescript from CDN --- packages/language-server/src/browser/index.ts | 12 +++++++++++- packages/language-server/src/common/server.ts | 18 +++++++++++------- packages/language-server/src/types.ts | 2 +- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/language-server/src/browser/index.ts b/packages/language-server/src/browser/index.ts index 6985499a..7ce2a441 100644 --- a/packages/language-server/src/browser/index.ts +++ b/packages/language-server/src/browser/index.ts @@ -29,7 +29,7 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L }, }, loadTypescript() { - return require('typescript'); // force bundle because not support load by user config in web + return importTsFromCdn(); }, async loadTypescriptLocalized(tsdk, locale) { try { @@ -45,6 +45,16 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L })); } +async function importTsFromCdn(tsVersion = 'latest') { + const _module = globalThis.module + ; (globalThis as any).module = { exports: {} }; + const tsUrl = `https://cdn.jsdelivr.net/npm/typescript@${tsVersion}/lib/typescript.js`; + await import(/* @vite-ignore */ tsUrl); + const ts = globalThis.module.exports; + globalThis.module = _module; + return ts as typeof import('typescript/lib/tsserverlibrary'); +} + /** * To avoid hitting the API hourly limit, we keep requests as low as possible. */ diff --git a/packages/language-server/src/common/server.ts b/packages/language-server/src/common/server.ts index 191110f3..e7f4614d 100644 --- a/packages/language-server/src/common/server.ts +++ b/packages/language-server/src/common/server.ts @@ -31,6 +31,9 @@ export function startCommonLanguageServer(connection: vscode.Connection, _plugin let plugins: ReturnType[]; let documents: ReturnType; let context: ServerContext; + let ts: typeof import('typescript/lib/tsserverlibrary') | undefined; + let tsLocalized: {} | undefined; + let cancelTokenHost: ReturnType; const didChangeWatchedFilesCallbacks = new Set>(); @@ -59,9 +62,14 @@ export function startCommonLanguageServer(connection: vscode.Connection, _plugin }, }, }; - plugins = context.server.plugins.map(plugin => plugin(options, { - typescript: options.typescript ? context.server.runtimeEnv.loadTypescript(options.typescript.tsdk) : undefined - })); + ts = options.typescript + ? await context.server.runtimeEnv.loadTypescript(options.typescript.tsdk) + : undefined; + tsLocalized = options.typescript && initParams.locale + ? await context.server.runtimeEnv.loadTypescriptLocalized(options.typescript.tsdk, initParams.locale) + : undefined; + cancelTokenHost = createCancellationTokenHost(options.cancellationPipeName); + plugins = context.server.plugins.map(plugin => plugin(options, { typescript: ts })); documents = createDocuments(context.server.runtimeEnv, connection); if (options.l10n) { @@ -232,10 +240,6 @@ export function startCommonLanguageServer(connection: vscode.Connection, _plugin async function createLanguageServiceHost() { - const ts = options.typescript ? context.server.runtimeEnv.loadTypescript(options.typescript.tsdk) : undefined; - const tsLocalized = options.typescript && initParams.locale ? await context.server.runtimeEnv.loadTypescriptLocalized(options.typescript.tsdk, initParams.locale) : undefined; - const cancelTokenHost = createCancellationTokenHost(options.cancellationPipeName); - workspaces = createWorkspaces({ ...context, workspaces: { diff --git a/packages/language-server/src/types.ts b/packages/language-server/src/types.ts index a8c19e47..b6e4eefd 100644 --- a/packages/language-server/src/types.ts +++ b/packages/language-server/src/types.ts @@ -14,7 +14,7 @@ export interface Timer { export interface RuntimeEnvironment { uriToFileName(uri: string): string; fileNameToUri(fileName: string): string; - loadTypescript(tsdk: string): typeof import('typescript/lib/tsserverlibrary'); + loadTypescript(tsdk: string): Promise; loadTypescriptLocalized(tsdk: string, locale: string): Promise<{} | undefined>; fs: FileSystem; // https://github.com/microsoft/vscode/blob/7927075f89db213bc6e2182fa684d514d69e2359/extensions/html-language-features/server/src/htmlServer.ts#L53-L56 From a0ce2521d876f45ac50193c00f2afd81d9644d0a Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Fri, 27 Oct 2023 18:14:08 +0800 Subject: [PATCH 2/6] Update index.ts --- packages/language-server/src/browser/index.ts | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/language-server/src/browser/index.ts b/packages/language-server/src/browser/index.ts index 7ce2a441..ac1b26e4 100644 --- a/packages/language-server/src/browser/index.ts +++ b/packages/language-server/src/browser/index.ts @@ -28,8 +28,15 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L return { dispose: () => clearTimeout(handle) }; }, }, - loadTypescript() { - return importTsFromCdn(); + async loadTypescript() { + const _module = globalThis.module; + globalThis.module = { exports: {} } as typeof _module; + const tsVersion = 'latest'; + const tsUrl = `https://cdn.jsdelivr.net/npm/typescript@${tsVersion}/lib/typescript.js`; + await import(tsUrl); + const ts = globalThis.module.exports; + globalThis.module = _module; + return ts as typeof import('typescript/lib/tsserverlibrary'); }, async loadTypescriptLocalized(tsdk, locale) { try { @@ -45,16 +52,6 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L })); } -async function importTsFromCdn(tsVersion = 'latest') { - const _module = globalThis.module - ; (globalThis as any).module = { exports: {} }; - const tsUrl = `https://cdn.jsdelivr.net/npm/typescript@${tsVersion}/lib/typescript.js`; - await import(/* @vite-ignore */ tsUrl); - const ts = globalThis.module.exports; - globalThis.module = _module; - return ts as typeof import('typescript/lib/tsserverlibrary'); -} - /** * To avoid hitting the API hourly limit, we keep requests as low as possible. */ From ddf1b2ebc5e11973c96ff94e6fcc3862e0c929b3 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 31 Oct 2023 04:06:44 +0800 Subject: [PATCH 3/6] add `typescript.tsdkUri` option --- packages/language-server/src/browser/index.ts | 18 ++++++++++++------ packages/language-server/src/common/server.ts | 8 +++----- packages/language-server/src/node/index.ts | 12 ++++++++++-- packages/language-server/src/types.ts | 10 +++++++--- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/packages/language-server/src/browser/index.ts b/packages/language-server/src/browser/index.ts index ac1b26e4..78fd3c5a 100644 --- a/packages/language-server/src/browser/index.ts +++ b/packages/language-server/src/browser/index.ts @@ -28,19 +28,25 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L return { dispose: () => clearTimeout(handle) }; }, }, - async loadTypescript() { + async loadTypeScript(options) { + const tsdkUri = options.typescript?.tsdkUri; + if (!tsdkUri) { + return; + } const _module = globalThis.module; globalThis.module = { exports: {} } as typeof _module; - const tsVersion = 'latest'; - const tsUrl = `https://cdn.jsdelivr.net/npm/typescript@${tsVersion}/lib/typescript.js`; - await import(tsUrl); + await import(`${tsdkUri}/lib/typescript.js`); const ts = globalThis.module.exports; globalThis.module = _module; return ts as typeof import('typescript/lib/tsserverlibrary'); }, - async loadTypescriptLocalized(tsdk, locale) { + async loadTypeScriptLocalized(options, locale) { + const tsdkUri = options.typescript?.tsdkUri; + if (!tsdkUri) { + return; + } try { - const uri = fileNameToUri(`${tsdk}/${locale}/diagnosticMessages.generated.json`); + const uri = fileNameToUri(`${tsdkUri}/${locale}/diagnosticMessages.generated.json`); const json = await httpSchemaRequestHandler(uri); if (json) { return JSON.parse(json); diff --git a/packages/language-server/src/common/server.ts b/packages/language-server/src/common/server.ts index e7f4614d..aa517f20 100644 --- a/packages/language-server/src/common/server.ts +++ b/packages/language-server/src/common/server.ts @@ -62,11 +62,9 @@ export function startCommonLanguageServer(connection: vscode.Connection, _plugin }, }, }; - ts = options.typescript - ? await context.server.runtimeEnv.loadTypescript(options.typescript.tsdk) - : undefined; - tsLocalized = options.typescript && initParams.locale - ? await context.server.runtimeEnv.loadTypescriptLocalized(options.typescript.tsdk, initParams.locale) + ts = await context.server.runtimeEnv.loadTypeScript(options); + tsLocalized = initParams.locale + ? await context.server.runtimeEnv.loadTypeScriptLocalized(options, initParams.locale) : undefined; cancelTokenHost = createCancellationTokenHost(options.cancellationPipeName); plugins = context.server.plugins.map(plugin => plugin(options, { typescript: ts })); diff --git a/packages/language-server/src/node/index.ts b/packages/language-server/src/node/index.ts index e7c98104..d4ae92d1 100644 --- a/packages/language-server/src/node/index.ts +++ b/packages/language-server/src/node/index.ts @@ -92,7 +92,11 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L return { dispose: () => clearImmediate(handle) }; }, }, - loadTypescript(tsdk) { + loadTypeScript(options) { + const tsdk = options.typescript?.tsdk; + if (!tsdk) { + return; + } for (const name of ['./typescript.js', './tsserverlibrary.js']) { try { return require(require.resolve(name, { paths: [tsdk] })); @@ -108,7 +112,11 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L throw new Error(`Can't find typescript.js or tsserverlibrary.js in ${tsdk}`); }, - async loadTypescriptLocalized(tsdk, locale) { + async loadTypeScriptLocalized(options, locale) { + const tsdk = options.typescript?.tsdk; + if (!tsdk) { + return; + } try { const path = require.resolve(`./${locale}/diagnosticMessages.generated.json`, { paths: [tsdk] }); return require(path); diff --git a/packages/language-server/src/types.ts b/packages/language-server/src/types.ts index b6e4eefd..bc5845e4 100644 --- a/packages/language-server/src/types.ts +++ b/packages/language-server/src/types.ts @@ -14,8 +14,8 @@ export interface Timer { export interface RuntimeEnvironment { uriToFileName(uri: string): string; fileNameToUri(fileName: string): string; - loadTypescript(tsdk: string): Promise; - loadTypescriptLocalized(tsdk: string, locale: string): Promise<{} | undefined>; + loadTypeScript(options: InitializationOptions): Promise; + loadTypeScriptLocalized(options: InitializationOptions, locale: string): Promise<{} | undefined>; fs: FileSystem; // https://github.com/microsoft/vscode/blob/7927075f89db213bc6e2182fa684d514d69e2359/extensions/html-language-features/server/src/htmlServer.ts#L53-L56 timer: Timer; @@ -53,9 +53,13 @@ export enum DiagnosticModel { export interface InitializationOptions { typescript?: { /** - * Absolute path to node_modules/typescript/lib + * Absolute path to node_modules/typescript/lib, available for node */ tsdk: string; + /** + * URI to node_modules/typescript/lib, available for web + */ + tsdkUri: string; }; l10n?: { location: string; // uri From b27390568565eab7bff60c1561adf8aade9a31d0 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 31 Oct 2023 04:12:45 +0800 Subject: [PATCH 4/6] tsdkUri -> tsdkUrl --- packages/language-server/src/browser/index.ts | 4 ++-- packages/language-server/src/types.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/language-server/src/browser/index.ts b/packages/language-server/src/browser/index.ts index 78fd3c5a..82555323 100644 --- a/packages/language-server/src/browser/index.ts +++ b/packages/language-server/src/browser/index.ts @@ -29,7 +29,7 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L }, }, async loadTypeScript(options) { - const tsdkUri = options.typescript?.tsdkUri; + const tsdkUri = options.typescript?.tsdkUrl; if (!tsdkUri) { return; } @@ -41,7 +41,7 @@ export function startLanguageServer(connection: vscode.Connection, ...plugins: L return ts as typeof import('typescript/lib/tsserverlibrary'); }, async loadTypeScriptLocalized(options, locale) { - const tsdkUri = options.typescript?.tsdkUri; + const tsdkUri = options.typescript?.tsdkUrl; if (!tsdkUri) { return; } diff --git a/packages/language-server/src/types.ts b/packages/language-server/src/types.ts index bc5845e4..83bdddc0 100644 --- a/packages/language-server/src/types.ts +++ b/packages/language-server/src/types.ts @@ -59,7 +59,7 @@ export interface InitializationOptions { /** * URI to node_modules/typescript/lib, available for web */ - tsdkUri: string; + tsdkUrl: string; }; l10n?: { location: string; // uri From 7d536161abe392aa6b5968161a5606258f45d6e3 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 31 Oct 2023 04:14:24 +0800 Subject: [PATCH 5/6] Update types.ts --- packages/language-server/src/types.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/language-server/src/types.ts b/packages/language-server/src/types.ts index 83bdddc0..d12cb724 100644 --- a/packages/language-server/src/types.ts +++ b/packages/language-server/src/types.ts @@ -58,6 +58,9 @@ export interface InitializationOptions { tsdk: string; /** * URI to node_modules/typescript/lib, available for web + * @example "https://cdn.jsdelivr.net/npm/typescript" + * @example "https://cdn.jsdelivr.net/npm/typescript@latest" + * @example "https://cdn.jsdelivr.net/npm/typescript@5.0.0" */ tsdkUrl: string; }; From 69a454f74badf197be8165a80fbe357c64692dc8 Mon Sep 17 00:00:00 2001 From: Johnson Chu Date: Tue, 31 Oct 2023 04:27:50 +0800 Subject: [PATCH 6/6] Delete .npmrc --- .npmrc | 3 --- pnpm-lock.yaml | 5 ++++- 2 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 .npmrc diff --git a/.npmrc b/.npmrc deleted file mode 100644 index b458878a..00000000 --- a/.npmrc +++ /dev/null @@ -1,3 +0,0 @@ -modules-cache-max-age=0 -prefer-frozen-lockfile=true -auto-install-peers=false diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a02313e0..46d5e505 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,7 +1,7 @@ lockfileVersion: '6.0' settings: - autoInstallPeers: false + autoInstallPeers: true excludeLinksFromLockfile: false importers: @@ -39,6 +39,9 @@ importers: typesafe-path: specifier: ^0.2.2 version: 0.2.2 + typescript: + specifier: '*' + version: 5.2.2 vscode-languageserver-textdocument: specifier: ^1.0.11 version: 1.0.11