Skip to content

feat: introduce -error versions of configs that have all rules configured to error #2796

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
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
5 changes: 5 additions & 0 deletions .changeset/brown-eels-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"eslint-plugin-vue": minor
---

Use `error` instead of `warn` in configs when `VUE_ESLINT_ALWAYS_ERROR` env variable is `"true"`
6 changes: 6 additions & 0 deletions docs/user-guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,20 @@ You can use the following configs by adding them to `extends`.
- Configurations for using Vue.js 3.x:
- `"plugin:vue/essential"` ... `base`, plus rules to prevent errors or unintended behavior.
- `"plugin:vue/strongly-recommended"` ... Above, plus rules to considerably improve code readability and/or dev experience.
- `"plugin:vue/strongly-recommended-error"` ... Above, except with all rules configured to error instead of warn.
- `"plugin:vue/recommended"` ... Above, plus rules to enforce subjective community defaults to ensure consistency.
- `"plugin:vue/recommended-error"` ... Above, except with all rules configured to error instead of warn.
- Configurations for using Vue.js 2.x:
- `"plugin:vue/vue2-essential"` ... `base`, plus rules to prevent errors or unintended behavior.
- `"plugin:vue/vue2-strongly-recommended"` ... Above, plus rules to considerably improve code readability and/or dev experience.
- `"plugin:vue/vue2-strongly-recommended-error"` ... Above, except with all rules configured to error instead of warn.
- `"plugin:vue/vue2-recommended"` ... Above, plus rules to enforce subjective community defaults to ensure consistency.
- `"plugin:vue/vue2-recommended-error"` ... Above, except with all rules configured to error instead of warn.

:::warning Reporting rules
By default, all rules from **base** and **essential** categories report ESLint errors. Other rules - because they're not covering potential bugs in the application - report warnings. What does it mean? By default - nothing, but if you want - you can set up a threshold and break the build after a certain amount of warnings, instead of any. More information [here](https://eslint.org/docs/user-guide/command-line-interface#handling-warnings).

Alternatively, there are versions of the configs with all rules set to error suffixed with `-error` that you can use.
:::

:::warning Status of Vue.js 3.x supports
Expand Down
24 changes: 24 additions & 0 deletions lib/configs/flat/vue2-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
'use strict'
const config = require('./vue2-strongly-recommended-error.js')

module.exports = [
...config,
{
name: 'vue/vue2-recommended/rules',
rules: {
'vue/attributes-order': 'error',
'vue/block-order': 'error',
'vue/no-lone-template': 'error',
'vue/no-multiple-slot-args': 'error',
'vue/no-required-prop-with-default': 'error',
'vue/no-v-html': 'error',
'vue/order-in-components': 'error',
'vue/this-in-template': 'error'
}
}
]
39 changes: 39 additions & 0 deletions lib/configs/flat/vue2-strongly-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
'use strict'
const config = require('./vue2-essential.js')

module.exports = [
...config,
{
name: 'vue/vue2-strongly-recommended/rules',
rules: {
'vue/attribute-hyphenation': 'error',
'vue/component-definition-name-casing': 'error',
'vue/first-attribute-linebreak': 'error',
'vue/html-closing-bracket-newline': 'error',
'vue/html-closing-bracket-spacing': 'error',
'vue/html-end-tags': 'error',
'vue/html-indent': 'error',
'vue/html-quotes': 'error',
'vue/html-self-closing': 'error',
'vue/max-attributes-per-line': 'error',
'vue/multiline-html-element-content-newline': 'error',
'vue/mustache-interpolation-spacing': 'error',
'vue/no-multi-spaces': 'error',
'vue/no-spaces-around-equal-signs-in-attribute': 'error',
'vue/no-template-shadow': 'error',
'vue/one-component-per-file': 'error',
'vue/prop-name-casing': 'error',
'vue/require-default-prop': 'error',
'vue/require-prop-types': 'error',
'vue/singleline-html-element-content-newline': 'error',
'vue/v-bind-style': 'error',
'vue/v-on-style': 'error',
'vue/v-slot-style': 'error'
}
}
]
24 changes: 24 additions & 0 deletions lib/configs/flat/vue3-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
'use strict'
const config = require('./vue3-strongly-recommended-error.js')

module.exports = [
...config,
{
name: 'vue/recommended/rules',
rules: {
'vue/attributes-order': 'error',
'vue/block-order': 'error',
'vue/no-lone-template': 'error',
'vue/no-multiple-slot-args': 'error',
'vue/no-required-prop-with-default': 'error',
'vue/no-v-html': 'error',
'vue/order-in-components': 'error',
'vue/this-in-template': 'error'
}
}
]
47 changes: 47 additions & 0 deletions lib/configs/flat/vue3-strongly-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
'use strict'
const config = require('./vue3-essential.js')

module.exports = [
...config,
{
name: 'vue/strongly-recommended/rules',
rules: {
'vue/attribute-hyphenation': 'error',
'vue/component-definition-name-casing': 'error',
'vue/first-attribute-linebreak': 'error',
'vue/html-closing-bracket-newline': 'error',
'vue/html-closing-bracket-spacing': 'error',
'vue/html-end-tags': 'error',
'vue/html-indent': 'error',
'vue/html-quotes': 'error',
'vue/html-self-closing': 'error',
'vue/max-attributes-per-line': 'error',
'vue/multiline-html-element-content-newline': 'error',
'vue/mustache-interpolation-spacing': 'error',
'vue/no-multi-spaces': 'error',
'vue/no-spaces-around-equal-signs-in-attribute': 'error',
'vue/no-template-shadow': 'error',
'vue/one-component-per-file': 'error',
'vue/prop-name-casing': 'error',
'vue/require-default-prop': 'error',
'vue/require-explicit-emits': 'error',
'vue/require-prop-types': 'error',
'vue/singleline-html-element-content-newline': 'error',
'vue/v-bind-style': 'error',
'vue/v-on-event-hyphenation': [
'error',
'always',
{
autofix: true
}
],
'vue/v-on-style': 'error',
'vue/v-slot-style': 'error'
}
}
]
18 changes: 18 additions & 0 deletions lib/configs/vue2-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
module.exports = {
extends: require.resolve('./vue2-strongly-recommended-error'),
rules: {
'vue/attributes-order': 'error',
'vue/block-order': 'error',
'vue/no-lone-template': 'error',
'vue/no-multiple-slot-args': 'error',
'vue/no-required-prop-with-default': 'error',
'vue/no-v-html': 'error',
'vue/order-in-components': 'error',
'vue/this-in-template': 'error'
}
}
33 changes: 33 additions & 0 deletions lib/configs/vue2-strongly-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
module.exports = {
extends: require.resolve('./vue2-essential'),
rules: {
'vue/attribute-hyphenation': 'error',
'vue/component-definition-name-casing': 'error',
'vue/first-attribute-linebreak': 'error',
'vue/html-closing-bracket-newline': 'error',
'vue/html-closing-bracket-spacing': 'error',
'vue/html-end-tags': 'error',
'vue/html-indent': 'error',
'vue/html-quotes': 'error',
'vue/html-self-closing': 'error',
'vue/max-attributes-per-line': 'error',
'vue/multiline-html-element-content-newline': 'error',
'vue/mustache-interpolation-spacing': 'error',
'vue/no-multi-spaces': 'error',
'vue/no-spaces-around-equal-signs-in-attribute': 'error',
'vue/no-template-shadow': 'error',
'vue/one-component-per-file': 'error',
'vue/prop-name-casing': 'error',
'vue/require-default-prop': 'error',
'vue/require-prop-types': 'error',
'vue/singleline-html-element-content-newline': 'error',
'vue/v-bind-style': 'error',
'vue/v-on-style': 'error',
'vue/v-slot-style': 'error'
}
}
18 changes: 18 additions & 0 deletions lib/configs/vue3-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
module.exports = {
extends: require.resolve('./vue3-strongly-recommended-error'),
rules: {
'vue/attributes-order': 'error',
'vue/block-order': 'error',
'vue/no-lone-template': 'error',
'vue/no-multiple-slot-args': 'error',
'vue/no-required-prop-with-default': 'error',
'vue/no-v-html': 'error',
'vue/order-in-components': 'error',
'vue/this-in-template': 'error'
}
}
41 changes: 41 additions & 0 deletions lib/configs/vue3-strongly-recommended-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
module.exports = {
extends: require.resolve('./vue3-essential'),
rules: {
'vue/attribute-hyphenation': 'error',
'vue/component-definition-name-casing': 'error',
'vue/first-attribute-linebreak': 'error',
'vue/html-closing-bracket-newline': 'error',
'vue/html-closing-bracket-spacing': 'error',
'vue/html-end-tags': 'error',
'vue/html-indent': 'error',
'vue/html-quotes': 'error',
'vue/html-self-closing': 'error',
'vue/max-attributes-per-line': 'error',
'vue/multiline-html-element-content-newline': 'error',
'vue/mustache-interpolation-spacing': 'error',
'vue/no-multi-spaces': 'error',
'vue/no-spaces-around-equal-signs-in-attribute': 'error',
'vue/no-template-shadow': 'error',
'vue/one-component-per-file': 'error',
'vue/prop-name-casing': 'error',
'vue/require-default-prop': 'error',
'vue/require-explicit-emits': 'error',
'vue/require-prop-types': 'error',
'vue/singleline-html-element-content-newline': 'error',
'vue/v-bind-style': 'error',
'vue/v-on-event-hyphenation': [
'error',
'always',
{
autofix: true
}
],
'vue/v-on-style': 'error',
'vue/v-slot-style': 'error'
}
}
32 changes: 26 additions & 6 deletions tools/update-lib-configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ const extendsCategories = {
'vue3-use-with-caution': 'vue3-recommended'
}

function formatRules(rules, categoryId) {
function formatRules(rules, categoryId, alwaysError) {
const obj = Object.fromEntries(
rules.map((rule) => {
let options = errorCategories.has(categoryId) ? 'error' : 'warn'
let options =
alwaysError || errorCategories.has(categoryId) ? 'error' : 'warn'
const defaultOptions =
rule.meta && rule.meta.docs && rule.meta.docs.defaultOptions
if (defaultOptions) {
Expand All @@ -47,8 +48,16 @@ function formatRules(rules, categoryId) {
return JSON.stringify(obj, null, 2)
}

function formatCategory(category) {
const extendsCategoryId = extendsCategories[category.categoryId]
function hasWarningRules(categoryId) {
return (
categoryId !== 'base' &&
categoryId !== 'vue3-essential' &&
categoryId !== 'vue2-essential'
)
}

function formatCategory(category, alwaysError = false) {
let extendsCategoryId = extendsCategories[category.categoryId]
if (extendsCategoryId == null) {
return `/*
* IMPORTANT!
Expand All @@ -63,7 +72,7 @@ module.exports = {
plugins: [
'vue'
],
rules: ${formatRules(category.rules, category.categoryId)},
rules: ${formatRules(category.rules, category.categoryId, alwaysError)},
overrides: [
{
files: '*.vue',
Expand All @@ -73,14 +82,18 @@ module.exports = {
}
`
}
if (alwaysError && hasWarningRules(extendsCategoryId)) {
extendsCategoryId += '-error'
}

return `/*
* IMPORTANT!
* This file has been automatically generated,
* in order to update its content execute "npm run update"
*/
module.exports = {
extends: require.resolve('./${extendsCategoryId}'),
rules: ${formatRules(category.rules, category.categoryId)}
rules: ${formatRules(category.rules, category.categoryId, alwaysError)}
}
`
}
Expand All @@ -92,6 +105,13 @@ for (const category of categories) {
const content = formatCategory(category)

fs.writeFileSync(filePath, content)

if (hasWarningRules(category.categoryId)) {
fs.writeFileSync(
path.join(ROOT, `${category.categoryId}-error.js`),
formatCategory(category, true)
)
}
}

// Format files.
Expand Down
Loading