ESLint runs prettier twice if config in .eslintrc and .prettierrc - eslint

I am trying to solve a problem with battling formatting on save in VSCode.
I do not have prettier installed as a standalone extension. I have eslint installed. I am working with typescript files.
In my editor, I see a warning on trailing commas and when I hit save, I see the trailing comma vanish, then reappear. I realized that I have trailing comma set to "none" in my .eslintrc.js file and set to "always" in my .prettierrc.js file. They are both below.
My have Vetur installed as well, but I think I only have vetur running on save because my vsconfig file specifies this:
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
But prettier is definitely being run twice. Is there some other setting I should be looking for? Or does eslint run prettier once for each set of config it finds.
Here is my eslintrc file:
module.exports = {
root: true,
env: {
node: true,
browser: true
},
extends: [
'plugin:vue/strongly-recommended',
'#vue/airbnb',
'#vue/typescript',
'plugin:prettier/recommended'
],
parserOptions: {
ecmaVersion: 2020,
parser: '#typescript-eslint/parser',
sourceType: 'module'
},
rules: {
'no-console': 'off',
'no-debugger': 'off',
'#typescript-eslint/no-empty-function': 'off',
'#typescript-eslint/no-namespace': 'off',
'#typescript-eslint/no-explicit-any': 'off',
'#typescript-eslint/no-non-null-assertion': 'off',
'#typescript-eslint/no-non-null-asserted-optional-chain': 'off',
'vue/component-name-in-template-casing': ['error', 'PascalCase'],
'vue/no-v-html': 'off',
'prettier/prettier': [
'warn',
{
singleQuote: true,
semi: true,
trailingComma: 'none',
printWidth: 100,
tabWidth: 2,
endOfLine: 'lf',
arrowParens: 'always',
bracketSpacing: true
}
]
},
overrides: [
{
files: ['**/*.test.ts'],
env: {
jest: true
}
}
]
};
and here is my .pretterrc.js file:
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 100,
tabWidth: 2,
endOfLine: 'lf',
arrowParens: 'always',
bracketSpacing: true
};
I know that I could just make the two files consistent and I will get the proper output, but I don't want the formatting to be run twice. Working with typescript files seems to be slow enough as it is without formatting twice all the time.
I think the relevant portions of my settings.json file are:
"eslint.alwaysShowStatus": true,
"eslint.validate": [
"vue",
"html",
"javascript",
"typescript"
],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[vue]": {
"editor.defaultFormatter": "octref.vetur"
},
"[typescript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[html]": {
"editor.defaultFormatter": "vscode.html-language-features"
},
"[javascript]": {
"editor.defaultFormatter": "vscode.typescript-language-features"
},
"editor.formatOnSave": true,
"vetur.experimental.templateInterpolationService": true,
"vetur.format.defaultFormatter.js": "prettier-eslint",
"vetur.format.defaultFormatter.ts": "prettier-tslint",
"vetur.format.defaultFormatterOptions": {
"js-beautify-html": {
"wrap_attributes": "force-expand-multiline"
},
"prettyhtml": {
"printWidth": 100,
"singleQuote": false,
"wrapAttributes": true,
"sortAttributes": true
},
"vetur.grammar.customBlocks": {
"docs": "md",
"i18n": "json"
}
},
Any pointers of which settings to look at would be appreciated.

I believe I have found the answer.
The first round of prettying is done by eslint and it uses the prettier config found in eslintrc.
The second round of prettying is done by vetur on the typescript section of the vue file and it uses the prettier config found in the prettierrc file.
What I did to fix the problem is to tell vetur not to format the typescript code by changing these two lines in the settings.json file for the workspace:
"vetur.format.defaultFormatter.js": "none",
"vetur.format.defaultFormatter.ts": "none",
These were prettier-eslint previously. Once I changed these to none, the typescript portion of the file removed the trailing commas and left them removed. The html template portion of the file was still formatted properly.
I assume this will speed up my file save since vetur can now ignore the typescript portion of the file when saving since it has already been processed by eslint.

You don't need to put the prettier config in the .eslintrc file, as the latest version of ESLint-plugin-prettier will load it from .prettierrc

Related

Display prettier linting errors in vite hmr overlay with svelte

I have a Svelte app with Vite bundler. My linter is Eslint with Prettier and vite-plugin-svelte plugins. Linting works well, but I want to make the app show all the linting errors inside Vite hmr overlay, same way it works with syntax errors as in this picture
My question is: Is it even possible to make something like that with Vite? I found nothing helpful about Vite's hmr overlay in the documentation, or maybe I just missing something in Eslint/Prettier config?
Here is config files:
.eslintrc :
{
"extends": ["eslint:recommended", "airbnb-base", "prettier"],
"plugins": ["svelte3", "prettier"],
"env": {
"es6": true,
"browser": true,
"node": true
},
"overrides": [
{
"files": ["*.svelte"],
"processor": "svelte3/svelte3"
}
],
"parserOptions": {
"project": "./jsconfig.json"
},
"rules": {
"prefer-arrow-callback": "off",
"arrow-body-style": "off",
"import/prefer-default-export": "off",
"import/no-anonymous-default-export": [
"error",
{
"allowArray": true,
"allowArrowFunction": false,
"allowAnonymousClass": false,
"allowAnonymousFunction": false,
"allowCallExpression": true,
"allowLiteral": false,
"allowObject": true
}
],
"dot-notation": "off"
}
}
.prettierrc.js
module.exports = {
arrowParens: 'always',
bracketSpacing: true,
endOfLine: 'lf',
printWidth: 80,
singleQuote: true,
tabWidth: 2,
trailingComma: 'all',
overrides: [
{
files: 'package*.json',
options: {
printWidth: 1000,
},
},
],
};
vite.config.js
export default defineConfig({
plugins: [
svelte({
preprocess: preprocess(),
}),
],
});
If it's possible to write your own vite plugin or modify the one in question, adding throw new Error(YOUR_ERROR) in the right plugin hook will trigger the overlay. e.g: modifying this example
https://vitejs.dev/guide/api-plugin.html#transformindexhtml
const htmlPlugin = () => {
return {
name: 'html-transform',
transformIndexHtml(html) {
// ADD THROW LINE
throw new Error("this will showup in an overlay")
}
}
}
Will lead to...

How to customize HTML formatting with Vue 3 and Prettier?

I have setup a new Vue 3 project with Eslint and Prettier config.
But when reformatting the HelloWorld.vue I see something ugly like this
<a
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
rel="noopener"
target="_blank"
>babel</a
>
I want something more compact and still readable like this:
<a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" rel="noopener"
target="_blank">babel</a>
I searched for a while and also tried out things like "htmlWhitespaceSensitivity": "ignore" but nothing helps.
.eslintrs.js
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'#vue/typescript/recommended',
'#vue/prettier',
'#vue/prettier/#typescript-eslint',
],
parserOptions: {
ecmaVersion: 2020,
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? ['error', {allow: ['warn', 'error']}] : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
},
overrides: [
{
files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
env: {
mocha: true,
},
},
],
}
.prettierrc
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"bracketSpacing": false,
"printWidth": 120,
"jsxBracketSameLine": true,
"htmlWhitespaceSensitivity": "ignore"
}
My Solution
That I wouldn't name an answer, because it doesn't solve the problem with Prettier.
I don't use Prettier any more.
This is my current .eslintrc.js:
module.exports = {
root: true,
env: {
node: true,
},
extends: ['plugin:vue/vue3-essential', '#vue/standard', '#vue/typescript/recommended'],
parserOptions: {
ecmaVersion: 2020,
},
rules: {
'comma-dangle': ['error', 'always-multiline'],
'no-console': process.env.NODE_ENV === 'production' ? ['error', { allow: ['warn', 'error'] }] : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'quotes': ['error', 'single'],
'vue/html-quotes': ['error', 'double'],
},
overrides: [
{
files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
env: {
jest: true,
},
},
],
}
Together with IntelliJ, this configuration leads to code formatting that looks pretty for me...
That formatting is controlled by Prettier's printWidth option. Since you're seeing the wrapping occur even with a printWidth of 120, the problem is likely that the particular line that <a> is on exceeds 120 characters, including surrounding whitespace (as seen in this demo).
Solution 1: Increase printWidth globally
Increase the printWidth value in .prettierrc to cover that line's character length (probably not the best idea, as it defeats the purpose of the option in your entire project).
Solution 2: Disable Prettier for line
Disable all Prettier rules for that particular line in <template>:
<!-- eslint-disable-next-line prettier/prettier -->
babel
Solution 3: Increase printWidth for the component
Use a component-specific printWidth config in <script> that accommodates an acceptable length (currently no way to configure from <template>):
<script>
/* eslint "prettier/prettier": ["warn", { "printWidth": 200 }] */
</script>

How do I disable There should be no space after '{'.eslintobject-curly-spacing in .eslintrc.js

I am using prettier and I initialized my project with firebase init with the eslint option. But when I save my files, the prettier extension adds spacing in the object curly braces like this:
export { basicHTTP } from './http';
which eslint gives me an error: is there anyway to disable this?
This is my .eslintrc.js file that comes with firebase init:
module.exports = {
root: true,
env: {
es6: true,
node: true,
},
extends: [
'eslint:recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
'google',
],
parser: '#typescript-eslint/parser',
parserOptions: {
project: ['tsconfig.json', 'tsconfig.dev.json'],
tsconfigRootDir: __dirname,
sourceType: 'module',
},
ignorePatterns: [
'/lib/**/*', // Ignore built files.
],
plugins: ['#typescript-eslint', 'import'],
rules: {
quotes: ['error'],
},
};
Modify your rules to look like this:
rules: {
'object-curly-spacing': ['error', 'always'],
'quotes': ['error'],
},
After this change you probably have to fix all js files to use same syntax, but that's just a good practice.
See: https://eslint.org/docs/rules/quotes
You can disable adding space in vscode when formatting code.
Open settings.json and add the following line
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false,
"javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false,
This will fix it on both javascript and typescript

ESLint with Mocha

I am trying to use ESLint for mocha, but for some reason the rules don'y apply and the linting passes.
My config file:
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true,
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly",
"expect": "true"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
overrides: [
{
files: [
"**/*.test.js"
],
env: {
mocha: true
},
plugins: ["mocha"],
rules: {
"mocha/no-exclusive-tests": "error",
"mocha/no-pending-tests": "error"
}
}
]
};
My test file only includes one line:
it('should throw a lint error')
The linter should find an error because of the 'no pending tests' rule, yet when I run the test file with eslint the linting passes as a success.
I have no idea why. I looked it up online and it seems like my configuration file is good as it is.
your solution is the same as this post answer.
However, the one that suits you better is the one you only edit the .eslintrc file as shown in eslint-configuration-doc, which would go like this:
module.exports = {
env: {
browser: false,
es6: true,
node: true,
mocha: true
}
// More code to go on that is not relative to your question ...
}
The line you are aiming is the one with
mocha: true
This solution worked for me.
{
"env": {
"browser": true,
"es6": true,
"mocha": true // add mocha as true to your ".eslintrc. *" file
}
}

ESLint rule: Allow whitespace before/after element

I want ESLint to stop removing whitespaces around an element, like this:
I can't seem to find any rule to disable this. I've searched https://eslint.org/docs/rules/ and tried different rules that I thought might solve my problem, but without success. I'm not even 100% sure if it's ESLint or my VS Code settings.
My eslintrc:
root: true,
env: {
node: true
},
extends: [
'plugin:vue/essential',
'plugin:prettier/recommended',
'#vue/prettier'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
and my VS Code user settings:
{
"prettier.eslintIntegration": true,
"prettier.jsxSingleQuote": true,
"vetur.validation.template": false,
"eslint.validate": [
{
"language": "vue",
"autoFix": true
},
{
"language": "html",
"autoFix": true
},
{
"language": "javascript",
"autoFix": true
}
],
"eslint.autoFixOnSave": true,
"editor.formatOnSave": true,
"vetur.completion.useScaffoldSnippets": false,
"diffEditor.ignoreTrimWhitespace": false,
Thank you.
In VSCode you can add .editorconfig file at the root of project and add following code so vscode does not remove whitespace
[*]
trim_trailing_whitespace = false

Resources