8000 feat(typescript-estree): disable plugin loading by default in project… · ronami/typescript-eslint@8651a07 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8651a07

Browse files
feat(typescript-estree): disable plugin loading by default in project service (typescript-eslint#9964)
* feat(typescript-estree): disable plugin loading by default in project service * Apply suggestions from code review Co-authored-by: Kirk Waiblinger <kirk.waiblinger@gmail.com> --------- Co-authored-by: Kirk Waiblinger <kirk.waiblinger@gmail.com>
1 parent ef3384e commit 8651a07

File tree

5 files changed

+72
-2
lines changed

5 files changed

+72
-2
lines changed

docs/packages/Parser.mdx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,24 @@ It takes in a string path that will be resolved relative to the [`tsconfigRootDi
369369

370370
`projectService.defaultProject` only impacts the "out-of-project" files included by [`allowDefaultProject`](#allowdefaultproject).
371371

372+
##### `loadTypeScriptPlugins`
373+
374+
> Default `false`
375+
376+
Whether the project service should be allowed to load [TypeScript plugins](https://www.typescriptlang.org/tsconfig/plugins.html).
377+
This is `false` by default to prevent plugins from registering persistent file watchers or other operations that might prevent ESLint processes from exiting when run on the command-line.
378+
379+
If your project is configured with custom rules that interact with TypeScript plugins, it may be useful to turn this on in your editor.
380+
For example, only enabling this option when running within VS Code:
381+
382+
```js
383+
parserOptions: {
384+
projectService: {
385+
loadTypeScriptPlugins: !!process.env.VSCODE_PID,
386+
}
387+
}
388+
```
389+
372390
##### `maximumDefaultProjectFileMatchCount_THIS_WILL_SLOW_DOWN_LINTING`
373391

374392
> Default: `8`.

docs/packages/TypeScript_ESTree.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,11 @@ interface ProjectServiceOptions {
279279
*/
280280
defaultProject?: string;
281281

282+
/**
283+
* Whether to load TypeScript plugins as configured in the TSConfig.
284+
*/
285+
loadTypeScriptPlugins?: boolean;
286+
282287
/**
283288
* The maximum number of files {@link allowDefaultProject} may match.
284289
* Each file match slows down linting, so if you do need to use this, please

packages/types/src/parser-options.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ interface ProjectServiceOptions {
5454
*/
5555
defaultProject?: string;
5656

57+
/**
58+
* Whether to allow TypeScript plugins as configured in the TSConfig.
59+
*/
60+
loadTypeScriptPlugins?: boolean;
61+
5762
/**
5863
* The maximum number of files {@link allowDefaultProject} may match.
5964
* Each file match slows down linting, so if you do need to use this, please

packages/typescript-estree/src/create-program/createProjectService.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@ export function createProjectService(
6666
setTimeout,
6767
watchDirectory: createStubFileWatcher,
6868
watchFile: createStubFileWatcher,
69+
70+
// We stop loading any TypeScript plugins by default, to prevent them from attaching disk watchers
71+
// See https://github.com/typescript-eslint/typescript-eslint/issues/9905
72+
...(!options.loadTypeScriptPlugins && {
73+
require: () => ({
74+
module: undefined,
75+
error: {
76+
message:
77+
'TypeScript plugins are not required when using parserOptions.projectService.',
78+
},
79+
}),
80+
}),
6981
};
7082

7183
const logger: ts.server.Logger = {

packages/typescript-estree/tests/lib/createProjectService.test.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ jest.mock('typescript/lib/tsserverlibrary', () => ({
1414
server: {
1515
...jest.requireActual('typescript/lib/tsserverlibrary').server,
1616
ProjectService: class {
17-
logger: ts.server.Logger;
1817
eventHandler: ts.server.ProjectServiceEventHandler | undefined;
18+
host: ts.server.ServerHost;
19+
logger: ts.server.Logger;
1920
constructor(
2021
...args: ConstructorParameters<typeof ts.server.ProjectService>
2122
) {
22-
this.logger = args[0].logger;
2323
this.eventHandler = args[0].eventHandler;
24+
this.host = args[0].host;
25+
this.logger = args[0].logger;
2426
if (this.eventHandler) {
2527
this.eventHandler({
2628
eventName: 'projectLoadingStart',
@@ -310,6 +312,34 @@ describe('createProjectService', () => {
310312
expect(process.stderr.write).toHaveBeenCalledTimes(0);
311313
});
312314

315+
it('provides a stub require to the host system when loadTypeScriptPlugins is falsy', () => {
316+
const { service } = createProjectService({}, undefined, undefined);
317+
318+
const required = service.host.require();
319+
320+
expect(required).toEqual({
321+
module: undefined,
322+
error: {
323+
message:
324+
'TypeScript plugins are not required when using parserOptions.projectService.',
325+
},
326+
});
327+
});
328+
329+
it('does not provide a require to the host system when loadTypeScriptPlugins is truthy', () => {
330+
const { service } = createProjectService(
331+
{
332+
loadTypeScriptPlugins: true,
333+
},
334+
undefined,
335+
undefined,
336+
);
337+
338+
expect(service.host.require).toBe(
339+
jest.requireActual('typescript/lib/tsserverlibrary').sys.require,
340+
);
341+
});
342+
313343
it('sets a host configuration', () => {
314344
const { service } = createProjectService(
315345
{

0 commit comments

Comments
 (0)
0