ESLint: types for `eslintrc.js` - eslint

I want my eslintrc.js to be typechecked, and to have all the type definitions of allowed rules builtin.
i.e. like:
module.exports = defineESLint({
rules: {
// intellisence: Enforce the consistent use of either backticks, double, or single quotes
// quotes?: 'off' | 'warn' | 'error'
// | ['warn' | 'error', 'single' | 'double', { avoidEscape?: true }]
quotes: ["warn", 'single', {avoidEscape: true}],
}
})
And I generally want this to work with all my eslint extensions
Currently all I can do is
{
"$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/eslintrc.json",
"rules": {
"quotes": [
"warn",
"single",
{
"avoidEscape": true
}
]
}
}
in json, but it barely works

npm:eslint-define-config
usage:
.eslintrc.js
// #ts-check
const { defineConfig } = require('eslint-define-config');
module.exports = defineConfig({
root: true,
rules: {
// rules...
},
});
Improve your eslint configuration experience with:
auto-suggestions
type checking (Use // #ts-check at the first line in your .eslintrc.js)
documentation
deprecation warnings

Related

typescript-eslint/naming-conventions function not being applied?

Given my .eslintrc.js file:
module.exports = {
root: true,
parser: '#typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module',
project: './tsconfig.json',
tsconfigRootDir: __dirname,
createDefaultProgram: true,
},
plugins: ['#typescript-eslint'],
settings: {
'import/resolver': {
// See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below
node: {},
typescript: {},
},
'import/parsers': {
'#typescript-eslint/parser': ['.ts', '.tsx'],
},
},
rules: {
// https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/naming-convention.md
'#typescript-eslint/naming-convention': [
'error',
{
selector: 'default',
format: ['camelCase'],
},
// destructured variables come from other places so no format is enforced
{
selector: 'variable',
modifiers: ['destructured'],
format: null,
},
// functions defined as constants must be constants (not var/let)
{
selector: 'variable',
types: ['function'],
modifiers: ['const'],
format: ['camelCase', 'PascalCase'],
},
// Constants can also be camelCase apart from UPPER_CASE
{
selector: 'variable',
modifiers: ['const'],
format: ['UPPER_CASE', 'camelCase'],
},
// functions can be:
// - regular functions (camelCase)
// - functional components (PascalCase)
{
selector: 'function',
format: ['camelCase', 'PascalCase'],
},
// type definitions (class, interface, typeAlias, enum, typeParameter)
// should be PascalCase
{
selector: 'typeLike',
format: ['PascalCase'],
},
// each member of an enum (const-like) should be UPPER_CASE
{
selector: 'enumMember',
format: ['UPPER_CASE'],
},
{
// Ignore properties that require quotes
selector: [
'classProperty',
'objectLiteralProperty',
'typeProperty',
'classMethod',
'objectLiteralMethod',
'typeMethod',
'accessor',
'enumMember',
],
format: null,
modifiers: ['requiresQuotes'],
},
],
},
};
I think it should detect as errors UPPER_CASE named functions, but it doesn't
function FUNCTION1() {
// this function name should be an error but it isn't
}
const FUNCTION2 = () => {}; // this should be an error too
const function3 = () => {}; // this should be ok
function4() {} // this should be ok too
Am I missing anything in this config?
One of those is easy, in const FUNCTION2 = () => {};, FUNCTION2 is actually a variable, and const.
Helpful tip: you can use error messages to your advantage by forcing a failure condition to see which one it's matching. Adding custom: { regex: 'FUNCTION2', match: false} to that rule adds the caveat "but it can't match FUNCTION2" to it, which will turn that line into the error:
Variable name FUNCTION2 must not match the RegExp: /FUNCTION2/u
which exposes that it's a variable.
Doing that one rule at a time for FUNCTION1 will at least tell you which rule it's matching.

How to disable warn about some unused params, but keep "#typescript-eslint/no-unused-vars" rule

I want to disable no unused params warning in some cases but keep "unused vars" rule.
For example here I would want to leave arguments in place to see what is passed to resolver:
const Query = objectType({
name: 'Query',
definition(t) {
t.field('test', {
type: 'Test',
resolve: (root, args, ctx) => {
const x = 1
return { id: 1, time: new Date().toString() }
},
})
},
})
I get warnings:
26:17 warning 'root' is defined but never used #typescript-eslint/no-unused-vars
26:23 warning 'args' is defined but never used #typescript-eslint/no-unused-vars
26:29 warning 'ctx' is defined but never used #typescript-eslint/no-unused-vars
27:15 warning 'x' is assigned a value but never used #typescript-eslint/no-unused-vars
ESLint config:
module.exports = {
root: true,
parser: '#typescript-eslint/parser',
parserOptions: { ecmaVersion: 2020, ecmaFeatures: { jsx: true } },
env: {
browser: true,
node: true,
},
extends: ['plugin:react-hooks/recommended', 'eslint:recommended', 'plugin:#typescript-eslint/recommended', 'plugin:react/recommended'],
settings: {
react: {
version: 'detect',
},
},
rules: {
'#typescript-eslint/no-empty-function': 'off',
'react/react-in-jsx-scope': 'off',
'#typescript-eslint/no-explicit-any': 'off',
'react/prop-types': 'off',
'#typescript-eslint/no-var-requires': 'off',
'#typescript-eslint/explicit-module-boundary-types': 'off',
'no-unused-vars': 'off',
'#typescript-eslint/no-unused-vars': ['off'],
},
ignorePatterns: ['**/generated/*'],
}
I was trying to disable it somehow, but found only this option that disables everything:
'no-unused-vars': 'off',
'#typescript-eslint/no-unused-vars': ['off'],
Only way that I found is to use ignore pattern argsIgnorePattern in rule options. If your variable is unused, just add underscore _ctx and ESLint will ignore it, but no-unused-vars rule will still work for other values. After you will need to use this value, just remove underscore ctx.
// note you must disable the base rule as it can report incorrect errors
"no-unused-vars": "off",
"#typescript-eslint/no-unused-vars": [
"warn", // or "error"
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_",
"caughtErrorsIgnorePattern": "^_"
}
],
You can change this pattern ^_ as you like using RegExp.
Example:
const _a = 'unused, no warning'
const b = 'unused, warning'

AssertionError 'import' is reserved when writing tests for custom eslint rule

The custom eslint rule runs ok in our project, but I cannot figure out how to run tests for it. My guess is that I am running wrong version of ecmascript and I need to use babel or adjust something in eslintrc.json to make this work with the mocha scripts.
Getting error message:
AssertionError [ERR_ASSERTION]: A fatal parsing error occurred: Parsing error: The keyword 'import' is reserved
The test:
/**
* #fileoverview Prohibit import underscore to help tree
* #author Jason Hocker
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
var rule = require("../../../lib/rules/no-full-lodash-import"),
RuleTester = require("eslint").RuleTester;
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
var ruleTester = new RuleTester();
ruleTester.run("no-full-lodash-import", rule, {
valid: [
{code: "import os from \"os\";\nimport fs from \"fs\";" },
{code: "import { merge } from \"lodash-es\";"}
],
invalid: [
{
code: "import _ from 'lodash';",
errors: [{
message: "Fill me in.",
type: "Me too"
}]
}
]
});
One of the .jslintrc.json files I tried:
{
"env": {
"browser": true,
"es6": true,
"mocha": true // add mocha as true to your ".eslintrc. *" file
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": "error"
}
}
ESLint docs suggest that you can pass a configuration object to the RuleTester constructor.
In your case it should probably look like this:
var config = {
env: {
browser: true,
es6: true,
mocha: true, // add mocha as true to your ".eslintrc. *" file
},
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
}
var ruleTester = new RuleTester()

Nuxt.js: importing `vuex` emits eslint(import/no-extraneous-dependencies) error

Nuxt.js is shipped with vuex as dependency so importing it doesn't require me to specify it in package.json.
But as vuex is not in package.json, whenever I try to import vuex, eslint emits import/no-extraneous-dependencies error.
In this case, how can I tell eslint to vuex is already included in nuxt module? Or is there any workaround to ignore some modules, ie. vuex, vue...
Below is my current eslint rules.
// .eslintrc.js
const path = require('path')
module.exports = {
env: {
browser: true,
es6: true,
jest: true
},
extends: [
'airbnb-base',
'plugin:vue/recommended',
'plugin:vue-types/strongly-recommended',
'plugin:prettier/recommended',
'#vue/prettier'
],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly'
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module'
},
plugins: ['prettier', 'vue'],
rules: {
'prettier/prettier': 'error',
'no-console': 0,
'import/prefer-default-export': 0,
'import/no-unresolved': 0,
'vue/max-attributes-per-line': 0
}
}
You can specify vuex as core-modules.
reference
// .eslintrc.js
settings: {
'import/core-modules': ['vue', 'vuex'] // these modules are included in nuxt.js
}
You can ignore these modules as following:
'node/no-extraneous-import': [
'error',
{
allowModules: ['vue', 'vuex']
}
]

grunt-autoprefixer to grunt-postcss

The grunt-autoprefixer said "This project has been deprecated in favour of grunt-postcss." So, I want to change it to grunt-postcss.
My current setting in Gruntfile.js for grunt-autoprefixer
autoprefixer: {
options: {
browsers: ['last 1 version']
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
If upgrade to grunt-postcss. How can I write my settings in Gruntfile.js?
I saw the README in grunt-postcss, but I didn't get it. Seems some values cannnot mapping to the new settings for grunt-postcss.
It is done like any other postcss processors. See this for example:
var autoprefixer = require('autoprefixer-core');
grunt.initConfig({
postcss: {
options: {
processors: [
autoprefixer({
browsers: ['> 0.5%', 'last 2 versions']
}).postcss
]
},
dist: {
files: {
'dist/': 'css/*.css'
}
}
}
});
Warning from 2020:
The usage of browsers option in autoprefixer processor has changed.
Now you need to move the browsers option into your package.json file:
Gruntfile.js
...
processors: [
...
// No autoprefixer 'browsers' option
require('autoprefixer')(),
...
]
...
package.json
{
...
// 'browserslist' option at the end of the file just above the last curly brace
'browserslist': [
'last 2 versions',
'> 0.5%'
]
}
See: https://github.com/browserslist/browserslist#browserslist-
(This answer I took from the part of my similar answer here: https://stackoverflow.com/a/64079551/12320578)
An example of working postcss-autoprefixer usage:
Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
postcss: {
options: {
processors: [
require('autoprefixer')({grid: 'autoplace'}),
],
map: {
inline: false, // save all sourcemaps as separate files...
annotation: 'assets/css/' // ...to the specified directory
}
},
dist: {
files: {
// Generated file target location and source location
'assets/css/style.min.css': 'assets/css/style.css',
'assets/css/info.min.css': 'assets/css/info.css'
}
// or:
/*files: [
{
expand: true,
src: ['assets/css/*.css', '!**/*.min.css'],
ext: '.min.css',
extDot: 'first'
}
]*/
}
},
watch: {
styles: {
files: ['assets/css/style.css', 'assets/css/info.css'],
// or:
/*files: ['assets/css/*.css', '!assets/css/*.min.css'],*/
tasks: ['postcss']
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-postcss');
};
package.json
{
... // Other already existing options
"browserslist": [
"last 4 versions",
"> 0.5%"
]
}
See https://gruntjs.com/configuring-tasks#building-the-files-object-dynamically

Resources