This PR updates our generators to use `eslint.config.cjs` instead of `eslint.config.js` so that Node resolution will treat it as CommonJS. This solves an issue where having `"type": "module"` in `package.json` will result in an error when Node tries to resolve the config file as ESM. Also allows us to clean up out Remix generators to not have to rename to `eslint.config.cjs` to solve the same issue. <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
4.9 KiB
Switching to ESLint's flat config format
Version 8 of ESLint introduced a new configuration format called Flat Config. The next major version will use this config format by default. The purpose of this format is to:
- push towards a single configuration format (in contrast to the existing
JSON,YamlandJS-based configs) - enforce explicit native loading (instead of the implicit imports in
JSONandYaml) - use a flat cascading of rules (instead of a mix of rules and overrides)
See below a direct comparison between JSON, JS and Flat config:
{% tabs %}
{% tab label="Flat" %}
// the older versions were magically interpreting all the imports
// in flat config we do it explicitly
const nxPlugin = require('@nx/eslint-plugin');
const js = require('@eslint/js');
const baseConfig = require('./eslint.base.config.cjs');
const globals = require('globals');
const jsoncParser = require('jsonc-eslint-parser');
const tsParser = require('@typescript-eslint/parser');
module.exports = [
js.configs.recommended,
// this will spread the export blocks from the base config
...baseConfig,
{ plugins: { '@nx': nxPlugin } },
{
languageOptions: {
parser: tsParser,
globals: {
...globals.node,
},
},
rules: {
'@typescript-eslint/explicit-module-boundary-types': ['error'],
},
},
// there are no overrides, all the config blocks are "flat"
{
files: ['*.json'],
languageOptions: {
parser: jsoncParser,
},
rules: {},
},
{
files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
rules: {
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: '*',
onlyDependOnLibsWithTags: ['*'],
},
],
},
],
},
},
];
{% /tab %} {% tab label="JSON" %}
{
"root": true,
"parser": "@typescript-eslint/parser",
"env": {
"node": true
},
"extends": ["eslint:recommended", "./.eslintrc.base.json"],
"plugins": ["@nx"],
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "error"
},
"overrides": [
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {}
},
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"@nx/enforce-module-boundaries": [
"error",
{
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [
{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}
]
}
]
}
}
]
}
{% /tab %} {% tab label="JS" %}
module.exports = {
root: true,
env: {
node: true,
},
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', './.eslintrc.base.js'],
plugins: ['@nx'],
rules: {
'@typescript-eslint/explicit-module-boundary-types': ['error'],
},
overrides: [
{
files: ['*.json'],
parser: 'jsonc-eslint-parser',
rules: {},
},
{
files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
rules: {
'@nx/enforce-module-boundaries': [
'error',
{
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [
{
sourceTag: '*',
onlyDependOnLibsWithTags: ['*'],
},
],
},
],
},
},
],
};
{% /tab %} {% /tabs %}
For additional details, head over to ESLint's official blog post.
Since version 16.8.0, Nx supports the usage of flat config in the @nx/eslint:lint executor and @nx/* generators, and provides an automated config conversion from .eslintrc.json config files.
Converting workspace from .eslintrc.json to flat config
To convert workspace ESLint configurations from the default .eslintrc.json to the new flat config you need to run:
nx g @nx/eslint:convert-to-flat-config
The generator will go through all the projects and convert their configurations to the new format. It will also convert the base .eslintrc.json and .eslintignore.
Correctness and best practices
The purpose of this generator is to create a flat config that works the same way as the original JSON config did. Depending on the complexity of your original config, it may be using the FlatCompat utility to provide a compatibility wrapper around parts of the original config. You can improve those by following the official migration guide.