Skip to content

Commit

Permalink
feat: adjust how configurations are exposed for flexibility
Browse files Browse the repository at this point in the history
Now that ESLint favors a flat config, which is essentially just an array of
JS objects, consumers will be able to import just the parts of a config
that they need. For convenience, exposing complete and discrete configs
makes it easier to simply adopt a config when no customization is needed,
or import just the parts that are neccessary when a good deal of
additional configuration will be done by the consuming project.
  • Loading branch information
pbredenberg committed Sep 19, 2024
1 parent 7dbe02b commit 376dcae
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 58 deletions.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Example:
## Migration to ESLint flag config

ESLint version 8.57 and later enable support for ESLint's flat config. As opposed
to use a customized configuration engine, this enables users to configure ESLint
to using a customized configuration engine, this enables users to configure ESLint
using JS objects and results in more flexibility and control over configuration.

Add a file named `eslint.config.js` to the root of your project and import our
Expand All @@ -46,6 +46,46 @@ configuration like so:
// TODO: add example config
```

## Using Specific Configurations

We maintain specific configurations for various project scenarios, such as
Node.js, Mocha.js test suites, Vue3, and Vue2.

These configs export two JS objects:

* `complete`: A configuration that includes our base config, and overrides or
additions relevant to your project scenario.
* `discrete`: Just the overrides or additions relevant to your
project scenario.

Use these configurations in your project's `eslint.config.js` file:

```js
const { discrete } = require('@silvermine/eslint-config/node-tests');

module.exports = [
{
files: [ 'tests/**.ts' ],
...discrete
}
]
```

```js
const { complete } = require('@silvermine/eslint-config/node-tests');

module.exports = [
...complete
]
```

If you need to use multiple discrete configs or override the import variable
name, use object destructuring like so:

```js
const { complete: nodeTests } = require('@silvermine/eslint-config/node-tests');
```

### VS Code Support

For VS Code users, switch to the prerelease version of the VS Code ESLint extension,
Expand Down
6 changes: 2 additions & 4 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
'use strict';

const config = require('./node');
const { complete } = require('./node');

module.exports = [
...config,
];
module.exports = complete;
10 changes: 3 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ const getVueRules = require('./partials/vue').getVueRules,
esLintPluginSilvermine = require('@silvermine/eslint-plugin-silvermine'),
typescriptESLint = require('typescript-eslint'),
typescriptESLintParser = require('@typescript-eslint/parser'),
vue = require('eslint-plugin-vue'),
vueESLintParser = require('vue-eslint-parser');
eslintPluginVue = require('eslint-plugin-vue');

module.exports = [
esLint.configs.recommended,
{
'ignorePatterns': [
'ignores': [
'cdk.out',
// ESLint by default ignores directories with dot prefixes. Some of our projects use

Check failure on line 26 in index.js

View workflow job for this annotation

GitHub Actions / build

This line has a comment length of 93. Maximum allowed is 90
// VuePress which maintains its source code in a `.vuepress` directory. This negated

Check failure on line 27 in index.js

View workflow job for this annotation

GitHub Actions / build

This line has a comment length of 93. Maximum allowed is 90
Expand All @@ -32,7 +31,6 @@ module.exports = [

'plugins': {
'@silvermine/eslint-plugin-silvermine': esLintPluginSilvermine, // Our custom rules
'vue': vue, // Vue-specific rules
},

'languageOptions': {
Expand Down Expand Up @@ -493,14 +491,12 @@ module.exports = [
'@typescript-eslint/no-empty-interface': 'off',
},
},
...eslintPluginVue.configs['flat/recommended'],
{
files: [ '**/*.vue' ],

languageOptions: {
parser: vueESLintParser,
parserOptions: {
parser: typescriptESLintParser,
ecmaVersion: 2020,
sourceType: 'module',
},
globals: {
Expand Down
27 changes: 16 additions & 11 deletions node-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,21 @@
const config = require('./index'),
globals = require('globals');

module.exports = [
...config,
{
languageOptions: {
globals: {
...globals.mocha,
},
},
rules: {
'no-empty-function': 'off',
const testConfig = {
languageOptions: {
globals: {
...globals.mocha,
},
},
];
rules: {
'no-empty-function': 'off',
},
};

module.exports = {
complete: [
...config,
testConfig,
],
discrete: testConfig,
};
21 changes: 13 additions & 8 deletions node.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@
const config = require('./index'),
globals = require('globals');

module.exports = [
...config,
{
languageOptions: {
globals: {
...globals.node,
},
const nodeConfig = {
languageOptions: {
globals: {
...globals.node,
},
},
];
};

module.exports = {
complete: [
...config,
nodeConfig,
],
discrete: nodeConfig,
};
54 changes: 28 additions & 26 deletions partials/vue.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
'use strict';
const vueRulesBase = require('eslint-plugin-vue/lib/configs/base').rules,
vueRulesEssentials = require('eslint-plugin-vue/lib/configs/essential').rules,
vue3RulesEssentials = require('eslint-plugin-vue/lib/configs/vue3-essential').rules,
vueRulesStronglyRecommended = require('eslint-plugin-vue/lib/configs/strongly-recommended').rules,
vue3RulesStronglyRecommended = require('eslint-plugin-vue/lib/configs/vue3-strongly-recommended').rules,
vueRulesRecommended = require('eslint-plugin-vue/lib/configs/recommended').rules,
vue3RulesRecommended = require('eslint-plugin-vue/lib/configs/vue3-recommended').rules;

const pluginVue = require('eslint-plugin-vue');

const silvermineRulesUniversal = {
// Priority B: Strongly Recommended
Expand Down Expand Up @@ -181,28 +175,39 @@ const silvermineRulesVue3Only = {
module.exports = {

getVueRules: function(vueVersion) {
// Always start with the base rules
let ruleSets = [ {}, vueRulesBase ];
const extractRulesFromConfig = (config) => {
return config
.filter((prop) => {
return prop.rules;
})
.map((obj) => {
return obj.rules;
})
.flat()
.reduce((prev, next) => {
return { ...prev, ...next };
}, {});
};

// Add in version dependent rules
let rules = {};

// Combine version dependent rules
switch (vueVersion) {
case 2: {
ruleSets = ruleSets.concat([
vueRulesEssentials,
vueRulesStronglyRecommended,
vueRulesRecommended,
silvermineRulesVue2Only,
]);
rules = {
...extractRulesFromConfig(pluginVue.configs['flat/vue2-strongly-recommended']),
...silvermineRulesUniversal,
...silvermineRulesVue2Only,
};
break;
}

case 3: {
ruleSets = ruleSets.concat([
vue3RulesEssentials,
vue3RulesStronglyRecommended,
vue3RulesRecommended,
silvermineRulesVue3Only,
]);
rules = {
...extractRulesFromConfig(pluginVue.configs['flat/strongly-recommended']),
...silvermineRulesUniversal,
...silvermineRulesVue3Only,
};
break;
}

Expand All @@ -212,9 +217,6 @@ module.exports = {
}

// Lastly, always add our custom rules.
ruleSets.push(silvermineRulesUniversal);

// Assemble into an object ready to be passed to eslint.
return Object.assign.apply(Object, ruleSets);
return rules;
},
};
7 changes: 6 additions & 1 deletion vue2.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,9 @@ const overrides = baseConfig.map((configObject) => {
);
});

module.exports = overrides;
module.exports = {
complete: overrides,
discrete: {
rules: getVueRules(2),
},
};

0 comments on commit 376dcae

Please sign in to comment.