Skip to content

Commit df211fe

Browse files
fix(store): update installation of the NgRx ESLint Plugin (#3259)
1 parent 0640085 commit df211fe

File tree

3 files changed

+71
-26
lines changed

3 files changed

+71
-26
lines changed

modules/store/schematics/ng-add/index.spec.ts

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,16 @@ describe('Store ng-add Schematic', () => {
165165
const eslintContent = tree.readContent(`.eslintrc.json`);
166166
const eslintJson = JSON.parse(eslintContent);
167167
expect(eslintJson).toEqual({
168-
extends: ['plugin:ngrx/recommended'],
169-
plugins: ['ngrx'],
168+
overrides: [
169+
{
170+
files: ['*.ts'],
171+
extends: ['plugin:ngrx/recommended'],
172+
},
173+
],
170174
});
171175
});
172176

173-
it('should register the NgRx ESLint Plugin in overrides when it supports TS', async () => {
177+
it('should register the NgRx ESLint Plugin in an existing config', async () => {
174178
const options = { ...defaultOptions };
175179

176180
// this is a trimmed down version of the default angular-eslint schematic
@@ -221,15 +225,13 @@ describe('Store ng-add Schematic', () => {
221225
project: ['tsconfig.eslint.json'],
222226
createDefaultProgram: true,
223227
},
224-
plugins: ['ngrx'],
225228
extends: [
226229
'plugin:@angular-eslint/recommended',
227230
'eslint:recommended',
228231
'plugin:@typescript-eslint/recommended',
229232
'plugin:@typescript-eslint/recommended-requiring-type-checking',
230233
'plugin:@angular-eslint/template/process-inline-templates',
231234
'plugin:prettier/recommended',
232-
'plugin:ngrx/recommended',
233235
],
234236
},
235237
{
@@ -240,10 +242,40 @@ describe('Store ng-add Schematic', () => {
240242
],
241243
rules: {},
242244
},
245+
{
246+
files: ['*.ts'],
247+
extends: ['plugin:ngrx/recommended'],
248+
},
243249
],
244250
});
245251
});
246252

253+
it('should not register the NgRx ESLint Plugin if already added', async () => {
254+
const options = { ...defaultOptions, skipESLintPlugin: true };
255+
256+
const initialConfig = {
257+
overrides: [
258+
{
259+
files: ['*.ts'],
260+
extends: ['plugin:ngrx/recommended'],
261+
},
262+
],
263+
};
264+
appTree.create('.eslintrc.json', JSON.stringify(initialConfig, null, 2));
265+
266+
const tree = await schematicRunner
267+
.runSchematicAsync('ng-add', options, appTree)
268+
.toPromise();
269+
270+
const packageContent = tree.readContent('package.json');
271+
const packageJson = JSON.parse(packageContent);
272+
expect(packageJson.devDependencies['eslint-plugin-ngrx']).not.toBeDefined();
273+
274+
const eslintContent = tree.readContent(`.eslintrc.json`);
275+
const eslintJson = JSON.parse(eslintContent);
276+
expect(eslintJson).toEqual(initialConfig);
277+
});
278+
247279
it('should not register the NgRx ESLint Plugin when skipped', async () => {
248280
const options = { ...defaultOptions, skipESLintPlugin: true };
249281

modules/store/schematics/ng-add/index.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,20 +130,26 @@ function addNgRxESLintPlugin() {
130130
host,
131131
'devDependencies',
132132
'eslint-plugin-ngrx',
133-
'^1.0.0'
133+
'^2.0.0'
134134
);
135135
context.addTask(new NodePackageInstallTask());
136136

137137
try {
138138
const json = JSON.parse(eslint);
139139
if (json.overrides) {
140-
json.overrides
141-
.filter((override: { files?: string[] }) =>
142-
override.files?.some((file: string) => file.endsWith('*.ts'))
140+
if (
141+
!json.overrides.some((override: any) =>
142+
override.extends?.some((extend: any) =>
143+
extend.startsWith('plugin:ngrx')
144+
)
143145
)
144-
.forEach(configureESLintPlugin);
145-
} else {
146-
configureESLintPlugin(json);
146+
) {
147+
json.overrides.push(configureESLintPlugin());
148+
}
149+
} else if (
150+
!json.extends?.some((extend: any) => extend.startsWith('plugin:ngrx'))
151+
) {
152+
json.overrides = [configureESLintPlugin()];
147153
}
148154

149155
host.overwrite(eslintConfigPath, JSON.stringify(json, null, 2));
@@ -170,9 +176,11 @@ ${err.message}
170176
};
171177
}
172178

173-
function configureESLintPlugin(json: any): void {
174-
json.plugins = [...(json.plugins || []), 'ngrx'];
175-
json.extends = [...(json.extends || []), 'plugin:ngrx/recommended'];
179+
function configureESLintPlugin(): Record<string, unknown> {
180+
return {
181+
files: ['*.ts'],
182+
extends: [`plugin:ngrx/recommended`],
183+
};
176184
}
177185

178186
export default function (options: RootStoreOptions): Rule {

projects/ngrx.io/content/guide/eslint-plugin.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
# ESLint plugin for NgRx
22

3-
## What is it?
4-
53
Use [ESLint](https://eslint.org/) to follow the best practices and to avoid common pitfalls in your application.
64

75
The [NgRx ESLint Plugin](https://github.com/timdeschryver/eslint-plugin-ngrx) is no different and promotes the key concepts to create a maintainable project. It consists of @ngrx/store, @ngrx/effects, and @ngrx/component-store rules and a handful of preconfigured configurations.
86

7+
The plugin comes with a number of rules that help address most popular NgRx malpractices. The rules are configurable so that you can choose the ones you want to follow, and which rules should give a linting error or warning.
98

10-
The plugin comes with a number of rules that help address most popular NgRx malpractices. The rules are configurable so that you can choose the ones you want to follow, and which rules should give a linting error or warning.
11-
12-
A detailed documentation of all the rules with examples can be found on the [documentation page](https://github.com/timdeschryver/eslint-plugin-ngrx/blob/main/README.md#rules).
9+
A detailed documentation of all the rules with examples can be found on the [documentation page](https://github.com/timdeschryver/eslint-plugin-ngrx/blob/main/README.md#rules).
1310

1411
Some rules also allow automatic fixes with `ng lint --fix`.
1512

@@ -49,7 +46,7 @@ Then, add it to your ESLint configuration file (for example, `.eslintrc.json`):
4946
{
5047
"parser": "@typescript-eslint/parser",
5148
"parserOptions": {
52-
"ecmaVersion": 2019,
49+
"ecmaVersion": 2020,
5350
"project": "./tsconfig.json",
5451
"sourceType": "module"
5552
},
@@ -64,19 +61,27 @@ To enable the recommended configuration, add it to your ESLint configuration fil
6461

6562
```json
6663
{
67-
"extends": ["plugin:ngrx/recommended"]
64+
"parser": "@typescript-eslint/parser",
65+
"parserOptions": {
66+
"ecmaVersion": 2020,
67+
"project": "./tsconfig.json",
68+
"sourceType": "module"
69+
},
70+
"overrides" [
71+
{
72+
"files": ["*.ts"],
73+
"extends": ["plugin:ngrx/recommended"]
74+
}
75+
]
6876
}
6977
```
7078

71-
Then you can run
79+
Next, you can run the linter with the following to see the problems are found.
7280

7381
```sh
7482
ng lint
7583
```
7684

77-
And see the problems that the linter found.
78-
7985
## Configuration
8086

8187
There are several levels of configuration that can be implemented with this plugin. You can read more about it in the [plugin documentation page](https://github.com/timdeschryver/eslint-plugin-ngrx#configurations).
82-

0 commit comments

Comments
 (0)