diff --git a/build/gulpfile.extensions.js b/build/gulpfile.extensions.js index 3c5f90f16d6..c0b79bc0f9d 100644 --- a/build/gulpfile.extensions.js +++ b/build/gulpfile.extensions.js @@ -64,7 +64,6 @@ const compilations = [ 'references-view/tsconfig.json', 'simple-browser/tsconfig.json', 'typescript-language-features/test-workspace/tsconfig.json', - 'typescript-language-features/web/tsconfig.json', 'typescript-language-features/tsconfig.json', 'vscode-api-tests/tsconfig.json', 'vscode-colorize-tests/tsconfig.json', diff --git a/build/lib/extensions.js b/build/lib/extensions.js index ed38a475c61..8e7f238bb3c 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -414,14 +414,19 @@ async function webpackExtensions(taskName, isWatch, webpackConfigLocations) { const webpackConfigs = []; for (const { configPath, outputRoot } of webpackConfigLocations) { const configOrFnOrArray = require(configPath); - function addConfig(configOrFnOrArray) { - for (const configOrFn of Array.isArray(configOrFnOrArray) ? configOrFnOrArray : [configOrFnOrArray]) { - const config = typeof configOrFn === 'function' ? configOrFn({}, {}) : configOrFn; - if (outputRoot) { - config.output.path = path.join(outputRoot, path.relative(path.dirname(configPath), config.output.path)); - } + function addConfig(configOrFn) { + let config; + if (typeof configOrFn === 'function') { + config = configOrFn({}, {}); webpackConfigs.push(config); } + else { + config = configOrFn; + } + if (outputRoot) { + config.output.path = path.join(outputRoot, path.relative(path.dirname(configPath), config.output.path)); + } + webpackConfigs.push(configOrFn); } addConfig(configOrFnOrArray); } diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 71513ae1f58..6cad21018d0 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -506,14 +506,20 @@ export async function webpackExtensions(taskName: string, isWatch: boolean, webp for (const { configPath, outputRoot } of webpackConfigLocations) { const configOrFnOrArray = require(configPath); - function addConfig(configOrFnOrArray: webpack.Configuration | ((env: unknown,args: unknown) => webpack.Configuration) | webpack.Configuration[]) { - for (const configOrFn of Array.isArray(configOrFnOrArray) ? configOrFnOrArray : [configOrFnOrArray]) { - const config = typeof configOrFn === 'function' ? configOrFn({}, {}) : configOrFn; - if (outputRoot) { - config.output!.path = path.join(outputRoot, path.relative(path.dirname(configPath), config.output!.path!)); - } + function addConfig(configOrFn: webpack.Configuration | Function) { + let config; + if (typeof configOrFn === 'function') { + config = (configOrFn as Function)({}, {}); webpackConfigs.push(config); + } else { + config = configOrFn; } + + if (outputRoot) { + config.output.path = path.join(outputRoot, path.relative(path.dirname(configPath), config.output.path)); + } + + webpackConfigs.push(configOrFn); } addConfig(configOrFnOrArray); } diff --git a/extensions/.vscodeignore b/extensions/.vscodeignore deleted file mode 100644 index 6e4d8fc1118..00000000000 --- a/extensions/.vscodeignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules/typescript/lib/tsc.js -node_modules/typescript/lib/typescriptServices.js -node_modules/typescript/lib/tsserverlibrary.js diff --git a/extensions/postinstall.mjs b/extensions/postinstall.mjs index 04e54dd6e2c..110b9b3b476 100644 --- a/extensions/postinstall.mjs +++ b/extensions/postinstall.mjs @@ -26,6 +26,7 @@ function processRoot() { function processLib() { const toDelete = new Set([ 'tsc.js', + 'tsserverlibrary.js', 'typescriptServices.js', ]); diff --git a/extensions/typescript-language-features/.vscodeignore b/extensions/typescript-language-features/.vscodeignore index 76d64ae8237..079f06f08d9 100644 --- a/extensions/typescript-language-features/.vscodeignore +++ b/extensions/typescript-language-features/.vscodeignore @@ -1,6 +1,5 @@ build/** src/** -web/** test/** test-workspace/** out/** diff --git a/extensions/typescript-language-features/extension-browser.webpack.config.js b/extensions/typescript-language-features/extension-browser.webpack.config.js index 9cbf6903725..7fb010d0448 100644 --- a/extensions/typescript-language-features/extension-browser.webpack.config.js +++ b/extensions/typescript-language-features/extension-browser.webpack.config.js @@ -7,6 +7,8 @@ 'use strict'; const CopyPlugin = require('copy-webpack-plugin'); +const Terser = require('terser'); +const fs = require('fs'); const path = require('path'); const defaultConfig = require('../shared.webpack.config'); @@ -28,7 +30,8 @@ const languages = [ 'tr', 'zh-cn', ]; -module.exports = [withBrowserDefaults({ + +module.exports = withBrowserDefaults({ context: __dirname, entry: { extension: './src/extension.browser.ts', @@ -57,21 +60,30 @@ module.exports = [withBrowserDefaults({ })) ], }), + // @ts-ignore + new CopyPlugin({ + patterns: [ + { + from: '../node_modules/typescript/lib/tsserver.js', + to: 'typescript/tsserver.web.js', + transform: async (content) => { + const dynamicImportCompatPath = path.join(__dirname, '..', 'node_modules', 'typescript', 'lib', 'dynamicImportCompat.js'); + const prefix = fs.existsSync(dynamicImportCompatPath) ? fs.readFileSync(dynamicImportCompatPath) : undefined; + const output = await Terser.minify(content.toString()); + if (!output.code) { + throw new Error('Terser returned undefined code'); + } + + if (prefix) { + return prefix.toString() + '\n' + output.code; + } + return output.code; + }, + transformPath: (targetPath) => { + return targetPath.replace('tsserver.js', 'tsserver.web.js'); + } + } + ], + }), ], -}), withBrowserDefaults({ - context: __dirname, - entry: { - 'typescript/tsserver.web': './web/webServer.ts' - }, - ignoreWarnings: [/Critical dependency: the request of a dependency is an expression/], - output: { - // all output goes into `dist`. - // packaging depends on that and this must always be like it - filename: '[name].js', - path: path.join(__dirname, 'dist', 'browser'), - libraryTarget: undefined, - }, - externals: { - 'perf_hooks': 'commonjs perf_hooks', - } -})]; +}); diff --git a/extensions/typescript-language-features/web/tsconfig.json b/extensions/typescript-language-features/web/tsconfig.json deleted file mode 100644 index 9944d5b63d8..00000000000 --- a/extensions/typescript-language-features/web/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "../../out", - "module": "nodenext", - "moduleDetection": "legacy", - "experimentalDecorators": true, - "types": [ - "node" - ] - }, - "files": [ - "webServer.ts" - ] -} diff --git a/extensions/typescript-language-features/web/webServer.ts b/extensions/typescript-language-features/web/webServer.ts deleted file mode 100644 index 680228881fa..00000000000 --- a/extensions/typescript-language-features/web/webServer.ts +++ /dev/null @@ -1,528 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -/// -/// -import * as ts from 'typescript/lib/tsserverlibrary'; -// BEGIN misc internals -const hasArgument: (argumentName: string) => boolean = (ts as any).server.hasArgument; -const findArgument: (argumentName: string) => string | undefined = (ts as any).server.findArgument; -const nowString: () => string = (ts as any).server.nowString; -const noop = () => { }; -const perfLogger = { - logEvent: noop, - logErrEvent(_: any) { }, - logPerfEvent(_: any) { }, - logInfoEvent(_: any) { }, - logStartCommand: noop, - logStopCommand: noop, - logStartUpdateProgram: noop, - logStopUpdateProgram: noop, - logStartUpdateGraph: noop, - logStopUpdateGraph: noop, - logStartResolveModule: noop, - logStopResolveModule: noop, - logStartParseSourceFile: noop, - logStopParseSourceFile: noop, - logStartReadFile: noop, - logStopReadFile: noop, - logStartBindFile: noop, - logStopBindFile: noop, - logStartScheduledOperation: noop, - logStopScheduledOperation: noop, -}; -const assertNever: (member: never) => never = (ts as any).Debug.assertNever; -const memoize: (callback: () => T) => () => T = (ts as any).memoize; -const ensureTrailingDirectorySeparator: (path: string) => string = (ts as any).ensureTrailingDirectorySeparator; -const getDirectoryPath: (path: string) => string = (ts as any).getDirectoryPath; -const directorySeparator: string = (ts as any).directorySeparator; -const combinePaths: (path: string, ...paths: (string | undefined)[]) => string = (ts as any).combinePaths; -const noopFileWatcher: ts.FileWatcher = { close: noop }; -const returnNoopFileWatcher = () => noopFileWatcher; -function getLogLevel(level: string | undefined) { - if (level) { - const l = level.toLowerCase(); - for (const name in ts.server.LogLevel) { - if (isNaN(+name) && l === name.toLowerCase()) { - return ts.server.LogLevel[name] as any as ts.server.LogLevel; - } - } - } - return undefined; -} - -const notImplemented: () => never = (ts as any).notImplemented; -const returnFalse: () => false = (ts as any).returnFalse; -const returnUndefined: () => undefined = (ts as any).returnUndefined; -const identity: (x: T) => T = (ts as any).identity; -const indent: (str: string) => string = (ts as any).server.indent; -const setSys: (s: ts.System) => void = (ts as any).setSys; -const validateLocaleAndSetLanguage: ( - locale: string, - sys: { getExecutingFilePath(): string; resolvePath(path: string): string; fileExists(fileName: string): boolean; readFile(fileName: string): string | undefined }, -) => void = (ts as any).validateLocaleAndSetLanguage; -const setStackTraceLimit: () => void = (ts as any).setStackTraceLimit; - -// End misc internals -// BEGIN webServer/webServer.ts -interface HostWithWriteMessage { - writeMessage(s: any): void; -} -interface WebHost extends HostWithWriteMessage { - readFile(path: string): string | undefined; - fileExists(path: string): boolean; -} - -class BaseLogger implements ts.server.Logger { - private seq = 0; - private inGroup = false; - private firstInGroup = true; - constructor(protected readonly level: ts.server.LogLevel) { - } - static padStringRight(str: string, padding: string) { - return (str + padding).slice(0, padding.length); - } - close() { - } - getLogFileName(): string | undefined { - return undefined; - } - perftrc(s: string) { - this.msg(s, ts.server.Msg.Perf); - } - info(s: string) { - this.msg(s, ts.server.Msg.Info); - } - err(s: string) { - this.msg(s, ts.server.Msg.Err); - } - startGroup() { - this.inGroup = true; - this.firstInGroup = true; - } - endGroup() { - this.inGroup = false; - } - loggingEnabled() { - return true; - } - hasLevel(level: ts.server.LogLevel) { - return this.loggingEnabled() && this.level >= level; - } - msg(s: string, type: ts.server.Msg = ts.server.Msg.Err) { - switch (type) { - case ts.server.Msg.Info: - perfLogger.logInfoEvent(s); - break; - case ts.server.Msg.Perf: - perfLogger.logPerfEvent(s); - break; - default: // Msg.Err - perfLogger.logErrEvent(s); - break; - } - - if (!this.canWrite()) { return; } - - s = `[${nowString()}] ${s}\n`; - if (!this.inGroup || this.firstInGroup) { - const prefix = BaseLogger.padStringRight(type + ' ' + this.seq.toString(), ' '); - s = prefix + s; - } - this.write(s, type); - if (!this.inGroup) { - this.seq++; - } - } - protected canWrite() { - return true; - } - protected write(_s: string, _type: ts.server.Msg) { - } -} - -type MessageLogLevel = 'info' | 'perf' | 'error'; -interface LoggingMessage { - readonly type: 'log'; - readonly level: MessageLogLevel; - readonly body: string; -} -class MainProcessLogger extends BaseLogger { - constructor(level: ts.server.LogLevel, private host: HostWithWriteMessage) { - super(level); - } - protected override write(body: string, type: ts.server.Msg) { - let level: MessageLogLevel; - switch (type) { - case ts.server.Msg.Info: - level = 'info'; - break; - case ts.server.Msg.Perf: - level = 'perf'; - break; - case ts.server.Msg.Err: - level = 'error'; - break; - default: - assertNever(type); - } - this.host.writeMessage({ - type: 'log', - level, - body, - } as LoggingMessage); - } -} - -function serverCreateWebSystem(host: WebHost, args: string[], getExecutingFilePath: () => string): - ts.server.ServerHost & { - importPlugin?(root: string, moduleName: string): Promise; - getEnvironmentVariable(name: string): string; - } { - const returnEmptyString = () => ''; - const getExecutingDirectoryPath = memoize(() => memoize(() => ensureTrailingDirectorySeparator(getDirectoryPath(getExecutingFilePath())))); - // Later we could map ^memfs:/ to do something special if we want to enable more functionality like module resolution or something like that - const getWebPath = (path: string) => path.startsWith(directorySeparator) ? path.replace(directorySeparator, getExecutingDirectoryPath()) : undefined; - - return { - args, - newLine: '\r\n', // This can be configured by clients - useCaseSensitiveFileNames: false, // Use false as the default on web since that is the safest option - readFile: path => { - const webPath = getWebPath(path); - return webPath && host.readFile(webPath); - }, - write: host.writeMessage.bind(host), - watchFile: returnNoopFileWatcher, - watchDirectory: returnNoopFileWatcher, - - getExecutingFilePath: () => directorySeparator, - getCurrentDirectory: returnEmptyString, // For inferred project root if projectRoot path is not set, normalizing the paths - - /* eslint-disable no-restricted-globals */ - setTimeout: (cb, ms, ...args) => setTimeout(cb, ms, ...args), - clearTimeout: handle => clearTimeout(handle), - setImmediate: x => setTimeout(x, 0), - clearImmediate: handle => clearTimeout(handle), - /* eslint-enable no-restricted-globals */ - - importPlugin: async (initialDir: string, moduleName: string): Promise => { - const packageRoot = combinePaths(initialDir, moduleName); - - let packageJson: any | undefined; - try { - const packageJsonResponse = await fetch(combinePaths(packageRoot, 'package.json')); - packageJson = await packageJsonResponse.json(); - } - catch (e) { - return { module: undefined, error: new Error('Could not load plugin. Could not load "package.json".') }; - } - - const browser = packageJson.browser; - if (!browser) { - return { module: undefined, error: new Error('Could not load plugin. No "browser" field found in package.json.') }; - } - - const scriptPath = combinePaths(packageRoot, browser); - try { - const { default: module } = await import(/* webpackIgnore: true */scriptPath); - return { module, error: undefined }; - } - catch (e) { - return { module: undefined, error: e }; - } - }, - exit: notImplemented, - - // Debugging related - getEnvironmentVariable: returnEmptyString, // TODO:: Used to enable debugging info - // tryEnableSourceMapsForHost?(): void; - // debugMode?: boolean; - - // For semantic server mode - fileExists: path => { - const webPath = getWebPath(path); - return !!webPath && host.fileExists(webPath); - }, - directoryExists: returnFalse, // Module resolution - readDirectory: notImplemented, // Configured project, typing installer - getDirectories: () => [], // For automatic type reference directives - createDirectory: notImplemented, // compile On save - writeFile: notImplemented, // compile on save - resolvePath: identity, // Plugins - // realpath? // Module resolution, symlinks - // getModifiedTime // File watching - // createSHA256Hash // telemetry of the project - - // Logging related - // /*@internal*/ bufferFrom?(input: string, encoding?: string): Buffer; - // gc?(): void; - // getMemoryUsage?(): number; - }; -} - -interface StartSessionOptions { - globalPlugins: ts.server.SessionOptions['globalPlugins']; - pluginProbeLocations: ts.server.SessionOptions['pluginProbeLocations']; - allowLocalPluginLoads: ts.server.SessionOptions['allowLocalPluginLoads']; - useSingleInferredProject: ts.server.SessionOptions['useSingleInferredProject']; - useInferredProjectPerProjectRoot: ts.server.SessionOptions['useInferredProjectPerProjectRoot']; - suppressDiagnosticEvents: ts.server.SessionOptions['suppressDiagnosticEvents']; - noGetErrOnBackgroundUpdate: ts.server.SessionOptions['noGetErrOnBackgroundUpdate']; - syntaxOnly: ts.server.SessionOptions['syntaxOnly']; - serverMode: ts.server.SessionOptions['serverMode']; -} -class ServerWorkerSession extends ts.server.Session<{}> { - constructor( - host: ts.server.ServerHost, - private webHost: HostWithWriteMessage, - options: StartSessionOptions, - logger: ts.server.Logger, - cancellationToken: ts.server.ServerCancellationToken, - hrtime: ts.server.SessionOptions['hrtime'] - ) { - super({ - host, - cancellationToken, - ...options, - typingsInstaller: ts.server.nullTypingsInstaller, - byteLength: notImplemented, // Formats the message text in send of Session which is overriden in this class so not needed - hrtime, - logger, - canUseEvents: true, - }); - } - - public override send(msg: ts.server.protocol.Message) { - if (msg.type === 'event' && !this.canUseEvents) { - if (this.logger.hasLevel(ts.server.LogLevel.verbose)) { - this.logger.info(`Session does not support events: ignored event: ${JSON.stringify(msg)}`); - } - return; - } - if (this.logger.hasLevel(ts.server.LogLevel.verbose)) { - this.logger.info(`${msg.type}:${indent(JSON.stringify(msg))}`); - } - this.webHost.writeMessage(msg); - } - - protected override parseMessage(message: {}): ts.server.protocol.Request { - return message as ts.server.protocol.Request; - } - - protected override toStringMessage(message: {}) { - return JSON.stringify(message, undefined, 2); - } -} -// END webServer/webServer.ts -// BEGIN tsserver/webServer.ts -const nullLogger: ts.server.Logger = { - close: noop, - hasLevel: returnFalse, - loggingEnabled: returnFalse, - perftrc: noop, - info: noop, - msg: noop, - startGroup: noop, - endGroup: noop, - getLogFileName: returnUndefined, -}; - -function parseServerMode(): ts.LanguageServiceMode | string | undefined { - const mode = findArgument('--serverMode'); - if (!mode) { return undefined; } - switch (mode.toLowerCase()) { - case 'partialsemantic': - return ts.LanguageServiceMode.PartialSemantic; - case 'syntactic': - return ts.LanguageServiceMode.Syntactic; - default: - return mode; - } -} - -function initializeWebSystem(args: string[]): StartInput { - createWebSystem(args); - const modeOrUnknown = parseServerMode(); - let serverMode: ts.LanguageServiceMode | undefined; - let unknownServerMode: string | undefined; - if (typeof modeOrUnknown === 'number') { serverMode = modeOrUnknown; } - else { unknownServerMode = modeOrUnknown; } - const logger = createLogger(); - - // enable deprecation logging - (ts as any).Debug.loggingHost = { - log(level: unknown, s: string) { - switch (level) { - case (ts as any).LogLevel.Error: - case (ts as any).LogLevel.Warning: - return logger.msg(s, ts.server.Msg.Err); - case (ts as any).LogLevel.Info: - case (ts as any).LogLevel.Verbose: - return logger.msg(s, ts.server.Msg.Info); - } - } - }; - - return { - args, - logger, - cancellationToken: ts.server.nullCancellationToken, - // Webserver defaults to partial semantic mode - serverMode: serverMode ?? ts.LanguageServiceMode.PartialSemantic, - unknownServerMode, - startSession: startWebSession - }; -} - -function createLogger() { - const cmdLineVerbosity = getLogLevel(findArgument('--logVerbosity')); - return cmdLineVerbosity !== undefined ? new MainProcessLogger(cmdLineVerbosity, { writeMessage }) : nullLogger; -} - -function writeMessage(s: any) { - postMessage(s); -} - -function createWebSystem(args: string[]) { - (ts as any).Debug.assert(ts.sys === undefined); - const webHost: WebHost = { - readFile: webPath => { - const request = new XMLHttpRequest(); - request.open('GET', webPath, /* asynchronous */ false); - request.send(); - return request.status === 200 ? request.responseText : undefined; - }, - fileExists: webPath => { - const request = new XMLHttpRequest(); - request.open('HEAD', webPath, /* asynchronous */ false); - request.send(); - return request.status === 200; - }, - writeMessage, - }; - // Do this after sys has been set as findArguments is going to work only then - const sys = serverCreateWebSystem(webHost, args, () => findArgument('--executingFilePath') || location + ''); - setSys(sys); - const localeStr = findArgument('--locale'); - if (localeStr) { - validateLocaleAndSetLanguage(localeStr, sys); - } -} - -function hrtime(previous?: number[]) { - const now = self.performance.now() * 1e-3; - let seconds = Math.floor(now); - let nanoseconds = Math.floor((now % 1) * 1e9); - // NOTE: This check is added probably because it's missed without strictFunctionTypes on - if (previous?.[0] !== undefined && previous?.[1] !== undefined) { - seconds = seconds - previous[0]; - nanoseconds = nanoseconds - previous[1]; - if (nanoseconds < 0) { - seconds--; - nanoseconds += 1e9; - } - } - return [seconds, nanoseconds]; -} - -function startWebSession(options: StartSessionOptions, logger: ts.server.Logger, cancellationToken: ts.server.ServerCancellationToken) { - class WorkerSession extends ServerWorkerSession { - constructor() { - super( - ts.sys as ts.server.ServerHost & { tryEnableSourceMapsForHost?(): void; getEnvironmentVariable(name: string): string }, - { writeMessage }, - options, - logger, - cancellationToken, - hrtime); - } - - override exit() { - this.logger.info('Exiting...'); - this.projectService.closeLog(); - close(); - } - - listen() { - addEventListener('message', (message: any) => { - this.onMessage(message.data); - }); - } - } - - const session = new WorkerSession(); - - // Start listening - session.listen(); -} -// END tsserver/webServer.ts -// BEGIN tsserver/server.ts -function findArgumentStringArray(argName: string): readonly string[] { - const arg = findArgument(argName); - if (arg === undefined) { - return []; - } - return arg.split(',').filter(name => name !== ''); -} - -interface StartInput { - args: readonly string[]; - logger: ts.server.Logger; - cancellationToken: ts.server.ServerCancellationToken; - serverMode: ts.LanguageServiceMode | undefined; - unknownServerMode?: string; - startSession: (option: StartSessionOptions, logger: ts.server.Logger, cancellationToken: ts.server.ServerCancellationToken) => void; -} -function start({ args, logger, cancellationToken, serverMode, unknownServerMode, startSession: startServer }: StartInput, platform: string) { - const syntaxOnly = hasArgument('--syntaxOnly'); - - logger.info(`Starting TS Server`); - logger.info(`Version: Moved from Typescript 5.0.0-dev`); - logger.info(`Arguments: ${args.join(' ')}`); - logger.info(`Platform: ${platform} NodeVersion: N/A CaseSensitive: ${ts.sys.useCaseSensitiveFileNames}`); - logger.info(`ServerMode: ${serverMode} syntaxOnly: ${syntaxOnly} hasUnknownServerMode: ${unknownServerMode}`); - - setStackTraceLimit(); - - if ((ts as any).Debug.isDebugging) { - (ts as any).Debug.enableDebugInfo(); - } - - if ((ts as any).sys.tryEnableSourceMapsForHost && /^development$/i.test((ts as any).sys.getEnvironmentVariable('NODE_ENV'))) { - (ts as any).sys.tryEnableSourceMapsForHost(); - } - - // Overwrites the current console messages to instead write to - // the log. This is so that language service plugins which use - // console.log don't break the message passing between tsserver - // and the client - console.log = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(', '), ts.server.Msg.Info); - console.warn = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(', '), ts.server.Msg.Err); - console.error = (...args) => logger.msg(args.length === 1 ? args[0] : args.join(', '), ts.server.Msg.Err); - - startServer( - { - globalPlugins: findArgumentStringArray('--globalPlugins'), - pluginProbeLocations: findArgumentStringArray('--pluginProbeLocations'), - allowLocalPluginLoads: hasArgument('--allowLocalPluginLoads'), - useSingleInferredProject: hasArgument('--useSingleInferredProject'), - useInferredProjectPerProjectRoot: hasArgument('--useInferredProjectPerProjectRoot'), - suppressDiagnosticEvents: hasArgument('--suppressDiagnosticEvents'), - noGetErrOnBackgroundUpdate: hasArgument('--noGetErrOnBackgroundUpdate'), - syntaxOnly, - serverMode - }, - logger, - cancellationToken - ); -} -// Get args from first message -const listener = (e: any) => { - removeEventListener('message', listener); - const args = e.data; - start(initializeWebSystem(args), 'web'); -}; -addEventListener('message', listener); -// END tsserver/server.ts