or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bulk-suppressions.mdcustom-config-package-names.mdindex.mdmodern-module-resolution.md

modern-module-resolution.mddocs/

0

# Modern Module Resolution

1

2

Modern Module Resolution patch solves the longstanding issue where ESLint requires plugins to be installed as peer dependencies in every project that uses a shareable config, even when the config package itself provides those plugins.

3

4

## Capabilities

5

6

### Module Resolution Patch

7

8

Applies runtime patches to ESLint's ConfigArrayFactory to resolve plugins relative to the config file instead of the project root.

9

10

```javascript { .api }

11

/**

12

* Applies the modern module resolution patch to ESLint

13

* Must be required before ESLint processes any configuration

14

*/

15

require("@rushstack/eslint-patch/modern-module-resolution");

16

```

17

18

**Usage Example:**

19

20

```javascript

21

// .eslintrc.js

22

require("@rushstack/eslint-patch/modern-module-resolution");

23

24

module.exports = {

25

extends: ['@your-company/eslint-config'], // This config can now provide its own plugins

26

parserOptions: { tsconfigRootDir: __dirname }

27

};

28

```

29

30

### ESLint Version Support

31

32

The patch automatically detects and handles different ESLint versions:

33

34

- **ESLint 6.x**: Patches `_loadPlugin` method with importerPath parameter

35

- **ESLint 7.x/8.x**: Patches `_loadPlugin` method with context object

36

- **ESLint 9.x**: Supports both legacy and flat config modes

37

38

### Plugin Resolution Behavior

39

40

When ESLint attempts to load a plugin:

41

42

1. **Primary Resolution**: Tries to resolve plugin relative to the config file location

43

2. **Fallback Resolution**: If primary fails with MODULE_NOT_FOUND or invalid path, falls back to original ESLint behavior

44

3. **Error Propagation**: Non-resolution errors are re-thrown unchanged

45

46

```javascript { .api }

47

// Internal patch behavior (not directly callable)

48

interface ModuleResolver {

49

resolve(moduleName: string, relativeToPath: string): string;

50

}

51

```

52

53

### Config Package Structure

54

55

With this patch, config packages can be structured as follows:

56

57

```json

58

{

59

"name": "@your-company/eslint-config",

60

"dependencies": {

61

"@typescript-eslint/eslint-plugin": "^5.0.0",

62

"eslint-plugin-react": "^7.0.0"

63

},

64

"peerDependencies": {

65

"eslint": "^8.0.0"

66

}

67

}

68

```

69

70

Consumer projects only need:

71

72

```json

73

{

74

"devDependencies": {

75

"@rushstack/eslint-patch": "^1.12.0",

76

"@your-company/eslint-config": "^1.0.0",

77

"eslint": "^8.0.0"

78

}

79

}

80

```

81

82

### Compatibility Notes

83

84

- **ESLint Flat Config**: ESLint 8.21.0+ includes native flat config mode (`ESLINT_USE_FLAT_CONFIG`) that may reduce need for this patch

85

- **Editor Extensions**: Works with VS Code ESLint extension, WebStorm, and other editor integrations

86

- **Monorepo Support**: Particularly useful in Rush Stack monorepos and similar setups

87

88

### Error Handling

89

90

The patch handles several error scenarios:

91

92

- **MODULE_NOT_FOUND**: Falls back to original resolution

93

- **ERR_INVALID_ARG_VALUE**: Falls back to original resolution (invalid importer path)

94

- **Other errors**: Re-thrown unchanged to preserve original ESLint error handling