Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions .eslintrc

This file was deleted.

1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
yarn format && yarn lint && yarn test
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,35 @@ $ npm install --save-dev @salesforce/eslint-plugin-lwc-graph-analyzer

## Configuration

Here's an example snippet of a `.eslintrc.json` configuration file, that will configure the `eslint-plugin-lwc-graph-analyzer` plugin. Extending the `plugin:@salesforce/lwc-graph-analyzer/recommended` ESLint configuration will enable static analysis on all `.js` and `.html` files used in your Lightning web components.
ESLint version-specific configuration examples are provided below. Here are some additional considerations for configuring the plugin.

- In an SFDX project, you would most commonly add your configuration at the root of your LWC "tree"—which by default resides at `force-app/main/default/lwc/`—since the plugin's analysis applies specifically to Lightning web components.
- Extending the appropriate `recommended` config based on your ESLint version will enable static analysis on all `.js` and `.html` files used in your Lightning web components.

### ESLint >= 9

The default configurations are now in the flat config format supported by ESLint 9 and beyond. Here's how to include the `recommended` config in your flat config:

```javascript
// eslint.config.mjs
import js from '@eslint/js';
import lwcGraphAnalyzerPlugin from '@salesforce/eslint-plugin-lwc-graph-analyzer';

export default [
{ plugins: { '@salesforce/lwc-graph-analyzer': lwcGraphAnalyzerPlugin } },
js.configs.recommended,
lwcGraphAnalyzerPlugin.configs.recommended
];
```

### ESLint < 9

Configurations for legacy ESLint have moved to `-legacy` extensions. Here's an `.eslintrc.json` configuration file that will configure the `eslint-plugin-lwc-graph-analyzer` plugin with the `recommended-legacy` config:

```json
{
"extends": ["eslint:recommended", "plugin:@salesforce/lwc-graph-analyzer/recommended"]
"extends": ["eslint:recommended", "plugin:@salesforce/lwc-graph-analyzer/recommended-legacy"]
}
```

In an SFDX project, you would most commonly add this configuration at the root of your LWC "tree"—which by default resides at `force-app/main/default/lwc/`—since the plugin's analysis applies specifically to Lightning web components.

**Note:** If you have a `.eslintignore` configuration in your project, do _not_ add an entry to ignore HTML files. This will cause the plugin to skip linting on LWC bundles that include HTML templates. There are a number of Komaci-based static analysis rules that apply specifically to the HTML template of a Lightning web component bundle.
54 changes: 54 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2025, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

const js = require('@eslint/js');
const nodePlugin = require('eslint-plugin-n');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eslint-plugin-node is a project that has apparently fallen by the wayside. So the ESLint community forked it and went with eslint-plugin-n. This project, by contrast, gets a goodly amount of attention.

const eslintPlugin = require('eslint-plugin-eslint-plugin');
const tseslint = require('typescript-eslint');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TypeScript linting for the index.d.ts type declarations.


module.exports = [
{
ignores: ['test/**/test.js', 'reports/**']
},
{
...js.configs.recommended,
...nodePlugin.configs['flat/recommended-script'],
files: ['**/*.js'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: {
// jest globals
jest: 'readonly',
describe: 'readonly',
it: 'readonly',
expect: 'readonly',
beforeEach: 'readonly',
afterEach: 'readonly',
beforeAll: 'readonly',
afterAll: 'readonly'
}
},
rules: {
strict: ['error', 'global']
}
},
...tseslint.configs.recommended.map((config) => ({
...config,
files: ['**/*.d.ts']
})),
{
files: ['lib/rules/*.js'],
plugins: {
'eslint-plugin': eslintPlugin
},
...eslintPlugin.configs['flat/recommended'],
rules: {
'eslint-plugin/prefer-message-ids': 'off' // Messages come straight from Komaci.
}
}
];
10 changes: 0 additions & 10 deletions index.js

This file was deleted.

2 changes: 0 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

'use strict';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are going to be a lot of these to ignore, unfortunately. Apparently this isn't required for modules, and throws linting exceptions if you keep them.


module.exports = {
displayName: 'Unit Tests',
setupFilesAfterEnv: ['jest-extended', 'jest-chain'],
Expand Down
21 changes: 21 additions & 0 deletions lib/configs/base-legacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base.js was migrated into base-legacy.js. This is the configuration that ESLint 8.x consumers will need to use.

* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

module.exports = {
plugins: ['@salesforce/lwc-graph-analyzer'],
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 'latest',
requireConfigFile: false,
sourceType: 'module',
babelOptions: {
parserOpts: {
plugins: [['decorators', { decoratorsBeforeExport: false }]]
}
}
}
};
23 changes: 13 additions & 10 deletions lib/configs/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,21 @@
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

'use strict';
const bundleAnalyzer = require('../processor');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

base.js is now the ESLint flat config, supported by ESLint 9. ESLint 9 support is now the default.


module.exports = {
plugins: ['@salesforce/lwc-graph-analyzer'],
parser: '@babel/eslint-parser',
parserOptions: {
ecmaVersion: 'latest',
requireConfigFile: false,
sourceType: 'module',
babelOptions: {
parserOpts: {
plugins: [['decorators', { decoratorsBeforeExport: false }]]
files: ['*.html', '**/*.html', '*.js', '**/*.js'],
processor: bundleAnalyzer,
languageOptions: {
parser: require('@babel/eslint-parser'),
parserOptions: {
ecmaVersion: 'latest',
requireConfigFile: false,
sourceType: 'module',
babelOptions: {
parserOpts: {
plugins: [['decorators', { decoratorsBeforeExport: false }]]
}
}
}
}
Expand Down
83 changes: 83 additions & 0 deletions lib/configs/recommended-legacy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2022, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/

module.exports = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

recommended-legacy.js is the same as base-legacy.js. ESLint 8.x consumers will need to use these configs.

extends: ['./configs/base-legacy'],
rules: {},
overrides: [
{
files: ['*.html', '**/*.html', '*.js', '**/*.js'],
processor: '@salesforce/lwc-graph-analyzer/bundleAnalyzer',
rules: {
'@salesforce/lwc-graph-analyzer/no-getter-contains-more-than-return-statement':
'warn',
'@salesforce/lwc-graph-analyzer/no-assignment-expression-assigns-value-to-member-variable':
'warn',
'@salesforce/lwc-graph-analyzer/no-wire-config-references-non-local-property-reactive-value':
'warn',
'@salesforce/lwc-graph-analyzer/no-private-wire-config-property': 'warn',
'@salesforce/lwc-graph-analyzer/no-unresolved-parent-class-reference': 'warn',
'@salesforce/lwc-graph-analyzer/no-class-refers-to-parent-class-from-unsupported-namespace':
'warn',
'@salesforce/lwc-graph-analyzer/no-reference-to-unsupported-namespace-reference':
'warn',
'@salesforce/lwc-graph-analyzer/no-wire-config-property-uses-getter-function-returning-inaccessible-import':
'warn',
'@salesforce/lwc-graph-analyzer/no-wire-config-property-uses-getter-function-returning-non-literal':
'warn',
'@salesforce/lwc-graph-analyzer/no-wire-config-property-circular-wire-dependency':
'warn',
'@salesforce/lwc-graph-analyzer/no-wire-configuration-property-using-output-of-non-primeable-wire':
'warn',
'@salesforce/lwc-graph-analyzer/no-missing-resource-cannot-prime-wire-adapter':
'warn',
'@salesforce/lwc-graph-analyzer/no-wire-config-property-uses-imported-artifact-from-unsupported-namespace':
'warn',
'@salesforce/lwc-graph-analyzer/no-wire-adapter-of-resource-cannot-be-primed':
'warn',
'@salesforce/lwc-graph-analyzer/no-unsupported-member-variable-in-member-expression':
'warn',
'@salesforce/lwc-graph-analyzer/no-multiple-template-files': 'warn',
'@salesforce/lwc-graph-analyzer/no-assignment-expression-for-external-components':
'warn',
'@salesforce/lwc-graph-analyzer/no-tagged-template-expression-contains-unsupported-namespace':
'warn',
'@salesforce/lwc-graph-analyzer/no-expression-contains-module-level-variable-ref':
'warn',
'@salesforce/lwc-graph-analyzer/no-call-expression-references-unsupported-namespace':
'warn',
'@salesforce/lwc-graph-analyzer/no-eval-usage': 'warn',
'@salesforce/lwc-graph-analyzer/no-reference-to-class-functions': 'warn',
'@salesforce/lwc-graph-analyzer/no-reference-to-module-functions': 'warn',
'@salesforce/lwc-graph-analyzer/no-functions-declared-within-getter-method': 'warn',
'@salesforce/lwc-graph-analyzer/no-member-expression-reference-to-non-existent-member-variable':
'warn',
'@salesforce/lwc-graph-analyzer/no-member-expression-reference-to-unsupported-namespace-reference':
'warn',
'@salesforce/lwc-graph-analyzer/no-member-expression-contains-non-portable-identifier':
'warn',
'@salesforce/lwc-graph-analyzer/no-member-expression-reference-to-super-class':
'warn',
'@salesforce/lwc-graph-analyzer/no-member-expression-reference-to-unsupported-global':
'warn',
'@salesforce/lwc-graph-analyzer/no-composition-on-unanalyzable-getter-property':
'warn',
'@salesforce/lwc-graph-analyzer/no-composition-on-unanalyzable-property-from-unresolvable-wire':
'warn',
'@salesforce/lwc-graph-analyzer/no-composition-on-unanalyzable-property-missing':
'warn',
'@salesforce/lwc-graph-analyzer/no-composition-on-unanalyzable-property-non-public':
'warn',
'@salesforce/lwc-graph-analyzer/no-render-function-contains-more-than-return-statement':
'warn',
'@salesforce/lwc-graph-analyzer/no-render-function-return-statement-not-returning-imported-template':
'warn',
'@salesforce/lwc-graph-analyzer/no-render-function-return-statement': 'warn'
}
}
]
};
Loading