Repository: vuejs/eslint-plugin-vue
Pull request #1118 (2020-05-09 09:55:58)

Add `vue/no-deprecated-vue-config-keycodes` rule
This PR adds `vue/no-deprecated-vue-config-keycodes` rule that reports use of deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)


Patch:
diff --git a/docs/rules/README.md b/docs/rules/README.md
index 4357d7e9..24c7edf8 100644
--- a/docs/rules/README.md
+++ b/docs/rules/README.md
@@ -49,6 +49,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
 | [vue/no-deprecated-slot-scope-attribute](./no-deprecated-slot-scope-attribute.md) | disallow deprecated `slot-scope` attribute (in Vue.js 2.6.0+) | :wrench: |
 | [vue/no-deprecated-v-bind-sync](./no-deprecated-v-bind-sync.md) | disallow use of deprecated `.sync` modifier on `v-bind` directive (in Vue.js 3.0.0+) | :wrench: |
 | [vue/no-deprecated-v-on-number-modifiers](./no-deprecated-v-on-number-modifiers.md) | disallow using deprecated number (keycode) modifiers (in Vue.js 3.0.0+) | :wrench: |
+| [vue/no-deprecated-vue-config-keycodes](./no-deprecated-vue-config-keycodes.md) | disallow using deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+) |  |
 | [vue/no-dupe-keys](./no-dupe-keys.md) | disallow duplication of field names |  |
 | [vue/no-duplicate-attributes](./no-duplicate-attributes.md) | disallow duplication of attributes |  |
 | [vue/no-lifecycle-after-await](./no-lifecycle-after-await.md) | disallow asynchronously registered lifecycle hooks |  |
diff --git a/docs/rules/no-deprecated-vue-config-keycodes.md b/docs/rules/no-deprecated-vue-config-keycodes.md
new file mode 100644
index 00000000..16caa0ef
--- /dev/null
+++ b/docs/rules/no-deprecated-vue-config-keycodes.md
@@ -0,0 +1,46 @@
+---
+pageClass: rule-details
+sidebarDepth: 0
+title: vue/no-deprecated-vue-config-keycodes
+description: disallow using deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)
+---
+# vue/no-deprecated-vue-config-keycodes
+> disallow using deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)
+
+- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `"plugin:vue/vue3-strongly-recommended"` and `"plugin:vue/vue3-recommended"`.
+
+## :book: Rule Details
+
+This rule reports use of deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)
+
+<eslint-code-block filename="a.js" language="javascript ":rules="{'vue/no-deprecated-vue-config-keycodes': ['error']}">
+
+```js
+/* ✗ BAD */
+Vue.config.keyCodes = {
+  // ...
+}
+```
+
+</eslint-code-block>
+
+## :wrench: Options
+
+Nothing.
+
+## :couple: Related rules
+
+- [vue/no-deprecated-v-on-number-modifiers]
+- [API - Global Config - keyCodes]
+
+[vue/no-deprecated-v-on-number-modifiers]: ./no-deprecated-v-on-number-modifiers.md
+[API - Global Config - keyCodes]: https://vuejs.org/v2/api/#keyCodes
+
+## :books: Further reading
+
+- [Vue RFCs - 0014-drop-keycode-support](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0014-drop-keycode-support.md)
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-deprecated-vue-config-keycodes.js)
+- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-deprecated-vue-config-keycodes.js)
diff --git a/lib/configs/vue3-essential.js b/lib/configs/vue3-essential.js
index f21d544c..305146f2 100644
--- a/lib/configs/vue3-essential.js
+++ b/lib/configs/vue3-essential.js
@@ -17,6 +17,7 @@ module.exports = {
     'vue/no-deprecated-slot-scope-attribute': 'error',
     'vue/no-deprecated-v-bind-sync': 'error',
     'vue/no-deprecated-v-on-number-modifiers': 'error',
+    'vue/no-deprecated-vue-config-keycodes': 'error',
     'vue/no-dupe-keys': 'error',
     'vue/no-duplicate-attributes': 'error',
     'vue/no-lifecycle-after-await': 'error',
diff --git a/lib/index.js b/lib/index.js
index adf6185f..43a34626 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -50,6 +50,7 @@ module.exports = {
     'no-deprecated-slot-scope-attribute': require('./rules/no-deprecated-slot-scope-attribute'),
     'no-deprecated-v-bind-sync': require('./rules/no-deprecated-v-bind-sync'),
     'no-deprecated-v-on-number-modifiers': require('./rules/no-deprecated-v-on-number-modifiers'),
+    'no-deprecated-vue-config-keycodes': require('./rules/no-deprecated-vue-config-keycodes'),
     'no-dupe-keys': require('./rules/no-dupe-keys'),
     'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
     'no-empty-pattern': require('./rules/no-empty-pattern'),
diff --git a/lib/rules/no-deprecated-vue-config-keycodes.js b/lib/rules/no-deprecated-vue-config-keycodes.js
new file mode 100644
index 00000000..9bae48ab
--- /dev/null
+++ b/lib/rules/no-deprecated-vue-config-keycodes.js
@@ -0,0 +1,44 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Rule Definition
+// ------------------------------------------------------------------------------
+
+module.exports = {
+  meta: {
+    type: 'problem',
+    docs: {
+      description: 'disallow using deprecated `Vue.config.keyCodes` (in Vue.js 3.0.0+)',
+      categories: ['vue3-essential'],
+      url: 'https://eslint.vuejs.org/rules/no-deprecated-vue-config-keycodes.html'
+    },
+    fixable: null,
+    schema: [],
+    messages: {
+      unexpected: '`Vue.config.keyCodes` are deprecated.'
+    }
+  },
+
+  create: function (context) {
+    return {
+      "MemberExpression[property.type='Identifier'][property.name='keyCodes']" (node) {
+        const config = node.object
+        if (config.type !== 'MemberExpression' ||
+          config.property.type !== 'Identifier' ||
+          config.property.name !== 'config' ||
+          config.object.type !== 'Identifier' ||
+          config.object.name !== 'Vue') {
+          return
+        }
+        context.report({
+          node,
+          messageId: 'unexpected'
+        })
+      }
+    }
+  }
+}


Test patch:
diff --git a/tests/lib/rules/no-deprecated-html-element-is.js b/tests/lib/rules/no-deprecated-html-element-is.js
index efa52e27..96164494 100644
--- a/tests/lib/rules/no-deprecated-html-element-is.js
+++ b/tests/lib/rules/no-deprecated-html-element-is.js
@@ -20,7 +20,7 @@ const ruleTester = new RuleTester({
   parserOptions: { ecmaVersion: 2019 }
 })
 
-ruleTester.run('no-deprecated-inline-template', rule, {
+ruleTester.run('no-deprecated-html-element-is', rule, {
   valid: [
     {
       filename: 'test.vue',
diff --git a/tests/lib/rules/no-deprecated-vue-config-keycodes.js b/tests/lib/rules/no-deprecated-vue-config-keycodes.js
new file mode 100644
index 00000000..02fc42c4
--- /dev/null
+++ b/tests/lib/rules/no-deprecated-vue-config-keycodes.js
@@ -0,0 +1,55 @@
+/**
+ * @author Yosuke Ota
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+// ------------------------------------------------------------------------------
+// Requirements
+// ------------------------------------------------------------------------------
+
+const rule = require('../../../lib/rules/no-deprecated-vue-config-keycodes')
+const RuleTester = require('eslint').RuleTester
+
+// ------------------------------------------------------------------------------
+// Tests
+// ------------------------------------------------------------------------------
+
+const ruleTester = new RuleTester({
+  parser: require.resolve('vue-eslint-parser'),
+  parserOptions: { ecmaVersion: 2015 }
+})
+
+ruleTester.run('no-deprecated-vue-config-keycodes', rule, {
+
+  valid: [
+    {
+      filename: 'test.js',
+      code: `Vue.config.silent = true`
+    },
+    {
+      filename: 'test.js',
+      code: 'config.keyCodes = {}'
+    },
+    {
+      filename: 'test.js',
+      code: 'V.config.keyCodes = {}'
+    }
+  ],
+
+  invalid: [
+    {
+      filename: 'test.js',
+      code: 'Vue.config.keyCodes = {}',
+      errors: [{
+        message: '`Vue.config.keyCodes` are deprecated.',
+        line: 1,
+        column: 1,
+        type: 'MemberExpression',
+        // messageId: 'unexpected',
+        endLine: 1,
+        endColumn: 20
+      }]
+    }
+  ]
+})