mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Addressing some comments
- Use result value instead of try/catch (`ImportPluginResult`) - Add awaits - Add logging
This commit is contained in:
parent
34a83a370d
commit
51680a1faa
@ -1545,7 +1545,7 @@ namespace ts.server {
|
||||
return !!this.program && this.program.isSourceOfProjectReferenceRedirect(fileName);
|
||||
}
|
||||
|
||||
protected enableGlobalPlugins(options: CompilerOptions, pluginConfigOverrides: Map<any> | undefined) {
|
||||
protected async enableGlobalPlugins(options: CompilerOptions, pluginConfigOverrides: Map<any> | undefined): Promise<void> {
|
||||
const host = this.projectService.host;
|
||||
|
||||
if (!host.require) {
|
||||
@ -1555,9 +1555,9 @@ namespace ts.server {
|
||||
|
||||
// Search any globally-specified probe paths, then our peer node_modules
|
||||
const searchPaths = [
|
||||
...this.projectService.pluginProbeLocations,
|
||||
// ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
|
||||
combinePaths(this.projectService.getExecutingFilePath(), "../../.."),
|
||||
...this.projectService.pluginProbeLocations,
|
||||
// ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/
|
||||
combinePaths(this.projectService.getExecutingFilePath(), "../../.."),
|
||||
];
|
||||
|
||||
if (this.projectService.globalPlugins) {
|
||||
@ -1572,12 +1572,12 @@ namespace ts.server {
|
||||
// Provide global: true so plugins can detect why they can't find their config
|
||||
this.projectService.logger.info(`Loading global plugin ${globalPluginName}`);
|
||||
|
||||
this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths, pluginConfigOverrides);
|
||||
await this.enablePlugin({ name: globalPluginName, global: true } as PluginImport, searchPaths, pluginConfigOverrides);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected async enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map<any> | undefined) {
|
||||
protected async enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[], pluginConfigOverrides: Map<any> | undefined): Promise<void> {
|
||||
this.projectService.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
|
||||
if (!pluginConfigEntry.name || parsePackageName(pluginConfigEntry.name).rest) {
|
||||
this.projectService.logger.info(`Skipped loading plugin ${pluginConfigEntry.name || JSON.stringify(pluginConfigEntry)} because only package name is allowed plugin name`);
|
||||
@ -1593,21 +1593,20 @@ namespace ts.server {
|
||||
let resolvedModule: any | undefined;
|
||||
if (this.projectService.host.importServicePlugin) {
|
||||
for (const searchPath of searchPaths) {
|
||||
try {
|
||||
resolvedModule = await this.projectService.host.importServicePlugin(searchPath, pluginConfigEntry.name);
|
||||
const result = await this.projectService.host.importServicePlugin(searchPath, pluginConfigEntry.name);
|
||||
if (result.error) {
|
||||
logError(result.error.toString());
|
||||
}
|
||||
catch (e) {
|
||||
// TODO: log this?
|
||||
continue;
|
||||
}
|
||||
if (resolvedModule) {
|
||||
else {
|
||||
resolvedModule = result.module;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
resolvedModule = firstDefined(searchPaths, searchPath =>
|
||||
Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log, logError) as PluginModuleFactory | undefined);
|
||||
Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log, logError) as PluginModuleFactory | undefined);
|
||||
}
|
||||
|
||||
if (resolvedModule) {
|
||||
@ -2290,7 +2289,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
enablePluginsWithOptions(options: CompilerOptions, pluginConfigOverrides: ESMap<string, any> | undefined) {
|
||||
async enablePluginsWithOptions(options: CompilerOptions, pluginConfigOverrides: ESMap<string, any> | undefined): Promise<void> {
|
||||
const host = this.projectService.host;
|
||||
|
||||
if (!host.require) {
|
||||
@ -2311,11 +2310,11 @@ namespace ts.server {
|
||||
// Enable tsconfig-specified plugins
|
||||
if (options.plugins) {
|
||||
for (const pluginConfigEntry of options.plugins) {
|
||||
this.enablePlugin(pluginConfigEntry, searchPaths, pluginConfigOverrides);
|
||||
await this.enablePlugin(pluginConfigEntry, searchPaths, pluginConfigOverrides);
|
||||
}
|
||||
}
|
||||
|
||||
this.enableGlobalPlugins(options, pluginConfigOverrides);
|
||||
return this.enableGlobalPlugins(options, pluginConfigOverrides);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -6,6 +6,8 @@ declare namespace ts.server {
|
||||
}
|
||||
|
||||
export type RequireResult = { module: {}, error: undefined } | { module: undefined, error: { stack?: string, message?: string } };
|
||||
export type ImportPluginResult = { module: {}, error: undefined } | { module: undefined, error: { stack?: string, message: string } };
|
||||
|
||||
export interface ServerHost extends System {
|
||||
watchFile(path: string, callback: FileWatcherCallback, pollingInterval?: number, options?: WatchOptions): FileWatcher;
|
||||
watchDirectory(path: string, callback: DirectoryWatcherCallback, recursive?: boolean, options?: WatchOptions): FileWatcher;
|
||||
@ -16,6 +18,6 @@ declare namespace ts.server {
|
||||
gc?(): void;
|
||||
trace?(s: string): void;
|
||||
require?(initialPath: string, moduleName: string): RequireResult;
|
||||
importServicePlugin?(root: string, moduleName: string): Promise<any>;
|
||||
importServicePlugin?(root: string, moduleName: string): Promise<ImportPluginResult>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,21 +139,34 @@ namespace ts.server {
|
||||
/* eslint-enable no-restricted-globals */
|
||||
|
||||
require: () => ({ module: undefined, error: new Error("Not implemented") }),
|
||||
importServicePlugin: async (root: string, moduleName: string) => {
|
||||
importServicePlugin: async (root: string, moduleName: string): Promise<ImportPluginResult> => {
|
||||
const packageRoot = combinePaths(root, "node_modules", moduleName);
|
||||
|
||||
const packageJsonResponse = await fetch(combinePaths(packageRoot, "package.json"));
|
||||
const packageJson = await packageJsonResponse.json();
|
||||
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) {
|
||||
throw new Error("Could not load plugin. No 'browser' field found in package.json.");
|
||||
return { module: undefined, error: new Error("Could not load plugin. No 'browser' field found in package.json.") };
|
||||
}
|
||||
|
||||
const scriptPath = combinePaths(packageRoot, browser);
|
||||
|
||||
// TODO: TS rewrites `import(...)` to `require`. Use eval to bypass this
|
||||
// eslint-disable-next-line no-eval
|
||||
return (await eval(`import(${JSON.stringify(scriptPath)})`)).default;
|
||||
try {
|
||||
const module = (await eval(`import(${JSON.stringify(scriptPath)})`)).default;
|
||||
return { module, error: undefined };
|
||||
}
|
||||
catch (e) {
|
||||
return { module: undefined, error: e };
|
||||
}
|
||||
},
|
||||
exit: notImplemented,
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user