Repository: vuejs/eslint-plugin-vue
Pull request #332 (2018-01-07 11:02:05)

Chore: rewrite 'npm run update'
I realized `Uncategorized` section is duplicate: [README.md](https://github.com/vuejs/eslint-plugin-vue/blob/41e7eeee11e1ec9bed45e04aad8bbedcfec37644/README.md#uncategorized).
`npm run update` seems wrong, but it's difficult to identify the cause.

This PR rewrites the `npm run update` script to be readable.

- `tools/lib/rules.js` provides the rule list to be used by update scripts.
- `tools/lib/categories.js` provides the category list to be used by update scripts.
- `tools/update-docs.js` updates the header of `docs/rules/*.md` files.
- `tools/update-lib-configs.js` updates `lib/configs/*.js` files.
- `tools/update-lib-index.js` updates `lib/index.js` file.
- `tools/update-readme.js` updates the rule tables of `lib/README.md` file.

Additionally, this PR changes this internal structure a bit.

- This removes `lib/*-rules.js` files and `npm run update` updates `lib/configs/*.js` directly. Because we don't have `lib/config/use-with-caution.js` before, but the script seems to make `lib/use-with-caution-rules.js` if rules exist. This can cause mistakes in future.
- This removes dependency to file system from this plugin. (`npm run update` updates `lib/index.js` instead of using `require-all` at runtime.)  
  It will make easy to use this plugin in browsers.

And this PR changes documents a bit:

- This adds a new note into `docs/rules/*.md` files to show which config includes each rule.
- This adds lacking `vue/` prefix to rule IDs in the doc.

  


Patch:
diff --git a/.eslintignore b/.eslintignore
index e0072d13..1fd04daf 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,4 +1,3 @@
 node_modules
-lib/*-rules.js
 coverage
 .nyc_output
diff --git a/README.md b/README.md
index a5ffa65d..fe69fa9d 100644
--- a/README.md
+++ b/README.md
@@ -103,111 +103,107 @@ Rules are grouped by priority to help you understand their purpose. The `--fix`
 
 Enforce all the rules in this category, as well as all higher priority rules, with:
 
-``` json
-"extends": "plugin:vue/base"
+```json
+{
+  "extends": "plugin:vue/base"
+}
 ```
 
 |    | Rule ID | Description |
 |:---|:--------|:------------|
-|  | [comment-directive](./docs/rules/comment-directive.md) | support comment-directives in `<template>` |
-|  | [jsx-uses-vars](./docs/rules/jsx-uses-vars.md) | prevent variables used in JSX to be marked as unused |
-
+|  | [vue/comment-directive](./docs/rules/comment-directive.md) | support comment-directives in `<template>` |
+|  | [vue/jsx-uses-vars](./docs/rules/jsx-uses-vars.md) | prevent variables used in JSX to be marked as unused |
 
 ### Priority A: Essential (Error Prevention)
 
 Enforce all the rules in this category, as well as all higher priority rules, with:
 
-``` json
-"extends": "plugin:vue/essential"
+```json
+{
+  "extends": "plugin:vue/essential"
+}
 ```
 
 |    | Rule ID | Description |
 |:---|:--------|:------------|
-|  | [no-async-in-computed-properties](./docs/rules/no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties |
-|  | [no-dupe-keys](./docs/rules/no-dupe-keys.md) | disallow duplication of field names |
-|  | [no-duplicate-attributes](./docs/rules/no-duplicate-attributes.md) | disallow duplication of attributes |
-|  | [no-parsing-error](./docs/rules/no-parsing-error.md) | disallow parsing errors in `<template>` |
-|  | [no-reserved-keys](./docs/rules/no-reserved-keys.md) | disallow overwriting reserved keys |
-| :wrench: | [no-shared-component-data](./docs/rules/no-shared-component-data.md) | enforce component's data property to be a function |
-|  | [no-side-effects-in-computed-properties](./docs/rules/no-side-effects-in-computed-properties.md) | disallow side effects in computed properties |
-|  | [no-template-key](./docs/rules/no-template-key.md) | disallow `key` attribute on `<template>` |
-|  | [no-textarea-mustache](./docs/rules/no-textarea-mustache.md) | disallow mustaches in `<textarea>` |
-|  | [no-unused-vars](./docs/rules/no-unused-vars.md) | disallow unused variable definitions of v-for directives or scope attributes |
-|  | [require-component-is](./docs/rules/require-component-is.md) | require `v-bind:is` of `<component>` elements |
-|  | [require-render-return](./docs/rules/require-render-return.md) | enforce render function to always return value |
-|  | [require-v-for-key](./docs/rules/require-v-for-key.md) | require `v-bind:key` with `v-for` directives |
-|  | [require-valid-default-prop](./docs/rules/require-valid-default-prop.md) | enforce props default values to be valid |
-|  | [return-in-computed-property](./docs/rules/return-in-computed-property.md) | enforce that a return statement is present in computed property |
-|  | [valid-template-root](./docs/rules/valid-template-root.md) | enforce valid template root |
-|  | [valid-v-bind](./docs/rules/valid-v-bind.md) | enforce valid `v-bind` directives |
-|  | [valid-v-cloak](./docs/rules/valid-v-cloak.md) | enforce valid `v-cloak` directives |
-|  | [valid-v-else-if](./docs/rules/valid-v-else-if.md) | enforce valid `v-else-if` directives |
-|  | [valid-v-else](./docs/rules/valid-v-else.md) | enforce valid `v-else` directives |
-|  | [valid-v-for](./docs/rules/valid-v-for.md) | enforce valid `v-for` directives |
-|  | [valid-v-html](./docs/rules/valid-v-html.md) | enforce valid `v-html` directives |
-|  | [valid-v-if](./docs/rules/valid-v-if.md) | enforce valid `v-if` directives |
-|  | [valid-v-model](./docs/rules/valid-v-model.md) | enforce valid `v-model` directives |
-|  | [valid-v-on](./docs/rules/valid-v-on.md) | enforce valid `v-on` directives |
-|  | [valid-v-once](./docs/rules/valid-v-once.md) | enforce valid `v-once` directives |
-|  | [valid-v-pre](./docs/rules/valid-v-pre.md) | enforce valid `v-pre` directives |
-|  | [valid-v-show](./docs/rules/valid-v-show.md) | enforce valid `v-show` directives |
-|  | [valid-v-text](./docs/rules/valid-v-text.md) | enforce valid `v-text` directives |
-
+|  | [vue/no-async-in-computed-properties](./docs/rules/no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties |
+|  | [vue/no-dupe-keys](./docs/rules/no-dupe-keys.md) | disallow duplication of field names |
+|  | [vue/no-duplicate-attributes](./docs/rules/no-duplicate-attributes.md) | disallow duplication of attributes |
+|  | [vue/no-parsing-error](./docs/rules/no-parsing-error.md) | disallow parsing errors in `<template>` |
+|  | [vue/no-reserved-keys](./docs/rules/no-reserved-keys.md) | disallow overwriting reserved keys |
+| :wrench: | [vue/no-shared-component-data](./docs/rules/no-shared-component-data.md) | enforce component's data property to be a function |
+|  | [vue/no-side-effects-in-computed-properties](./docs/rules/no-side-effects-in-computed-properties.md) | disallow side effects in computed properties |
+|  | [vue/no-template-key](./docs/rules/no-template-key.md) | disallow `key` attribute on `<template>` |
+|  | [vue/no-textarea-mustache](./docs/rules/no-textarea-mustache.md) | disallow mustaches in `<textarea>` |
+|  | [vue/no-unused-vars](./docs/rules/no-unused-vars.md) | disallow unused variable definitions of v-for directives or scope attributes |
+|  | [vue/require-component-is](./docs/rules/require-component-is.md) | require `v-bind:is` of `<component>` elements |
+|  | [vue/require-render-return](./docs/rules/require-render-return.md) | enforce render function to always return value |
+|  | [vue/require-v-for-key](./docs/rules/require-v-for-key.md) | require `v-bind:key` with `v-for` directives |
+|  | [vue/require-valid-default-prop](./docs/rules/require-valid-default-prop.md) | enforce props default values to be valid |
+|  | [vue/return-in-computed-property](./docs/rules/return-in-computed-property.md) | enforce that a return statement is present in computed property |
+|  | [vue/valid-template-root](./docs/rules/valid-template-root.md) | enforce valid template root |
+|  | [vue/valid-v-bind](./docs/rules/valid-v-bind.md) | enforce valid `v-bind` directives |
+|  | [vue/valid-v-cloak](./docs/rules/valid-v-cloak.md) | enforce valid `v-cloak` directives |
+|  | [vue/valid-v-else-if](./docs/rules/valid-v-else-if.md) | enforce valid `v-else-if` directives |
+|  | [vue/valid-v-else](./docs/rules/valid-v-else.md) | enforce valid `v-else` directives |
+|  | [vue/valid-v-for](./docs/rules/valid-v-for.md) | enforce valid `v-for` directives |
+|  | [vue/valid-v-html](./docs/rules/valid-v-html.md) | enforce valid `v-html` directives |
+|  | [vue/valid-v-if](./docs/rules/valid-v-if.md) | enforce valid `v-if` directives |
+|  | [vue/valid-v-model](./docs/rules/valid-v-model.md) | enforce valid `v-model` directives |
+|  | [vue/valid-v-on](./docs/rules/valid-v-on.md) | enforce valid `v-on` directives |
+|  | [vue/valid-v-once](./docs/rules/valid-v-once.md) | enforce valid `v-once` directives |
+|  | [vue/valid-v-pre](./docs/rules/valid-v-pre.md) | enforce valid `v-pre` directives |
+|  | [vue/valid-v-show](./docs/rules/valid-v-show.md) | enforce valid `v-show` directives |
+|  | [vue/valid-v-text](./docs/rules/valid-v-text.md) | enforce valid `v-text` directives |
 
 ### Priority B: Strongly Recommended (Improving Readability)
 
 Enforce all the rules in this category, as well as all higher priority rules, with:
 
-``` json
-"extends": "plugin:vue/strongly-recommended"
+```json
+{
+  "extends": "plugin:vue/strongly-recommended"
+}
 ```
 
 |    | Rule ID | Description |
 |:---|:--------|:------------|
-| :wrench: | [attribute-hyphenation](./docs/rules/attribute-hyphenation.md) | enforce attribute naming style in template |
-| :wrench: | [html-end-tags](./docs/rules/html-end-tags.md) | enforce end tag style |
-| :wrench: | [html-indent](./docs/rules/html-indent.md) | enforce consistent indentation in `<template>` |
-| :wrench: | [html-self-closing](./docs/rules/html-self-closing.md) | enforce self-closing style |
-|  | [max-attributes-per-line](./docs/rules/max-attributes-per-line.md) | enforce the maximum number of attributes per line |
-| :wrench: | [mustache-interpolation-spacing](./docs/rules/mustache-interpolation-spacing.md) | enforce unified spacing in mustache interpolations |
-| :wrench: | [name-property-casing](./docs/rules/name-property-casing.md) | enforce specific casing for the name property in Vue components |
-| :wrench: | [no-multi-spaces](./docs/rules/no-multi-spaces.md) | disallow multiple spaces |
-|  | [require-default-prop](./docs/rules/require-default-prop.md) | require default value for props |
-|  | [require-prop-types](./docs/rules/require-prop-types.md) | require type definitions in props |
-| :wrench: | [v-bind-style](./docs/rules/v-bind-style.md) | enforce `v-bind` directive style |
-| :wrench: | [v-on-style](./docs/rules/v-on-style.md) | enforce `v-on` directive style |
-
+| :wrench: | [vue/attribute-hyphenation](./docs/rules/attribute-hyphenation.md) | enforce attribute naming style in template |
+| :wrench: | [vue/html-end-tags](./docs/rules/html-end-tags.md) | enforce end tag style |
+| :wrench: | [vue/html-indent](./docs/rules/html-indent.md) | enforce consistent indentation in `<template>` |
+| :wrench: | [vue/html-self-closing](./docs/rules/html-self-closing.md) | enforce self-closing style |
+|  | [vue/max-attributes-per-line](./docs/rules/max-attributes-per-line.md) | enforce the maximum number of attributes per line |
+| :wrench: | [vue/mustache-interpolation-spacing](./docs/rules/mustache-interpolation-spacing.md) | enforce unified spacing in mustache interpolations |
+| :wrench: | [vue/name-property-casing](./docs/rules/name-property-casing.md) | enforce specific casing for the name property in Vue components |
+| :wrench: | [vue/no-multi-spaces](./docs/rules/no-multi-spaces.md) | disallow multiple spaces |
+|  | [vue/require-default-prop](./docs/rules/require-default-prop.md) | require default value for props |
+|  | [vue/require-prop-types](./docs/rules/require-prop-types.md) | require type definitions in props |
+| :wrench: | [vue/v-bind-style](./docs/rules/v-bind-style.md) | enforce `v-bind` directive style |
+| :wrench: | [vue/v-on-style](./docs/rules/v-on-style.md) | enforce `v-on` directive style |
 
 ### Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
 
 Enforce all the rules in this category, as well as all higher priority rules, with:
 
-``` json
-"extends": "plugin:vue/recommended"
+```json
+{
+  "extends": "plugin:vue/recommended"
+}
 ```
 
 |    | Rule ID | Description |
 |:---|:--------|:------------|
-| :wrench: | [html-quotes](./docs/rules/html-quotes.md) | enforce quotes style of HTML attributes |
-|  | [no-confusing-v-for-v-if](./docs/rules/no-confusing-v-for-v-if.md) | disallow confusing `v-for` and `v-if` on the same element |
-|  | [order-in-components](./docs/rules/order-in-components.md) | enforce order of properties in components |
-|  | [this-in-template](./docs/rules/this-in-template.md) | enforce usage of `this` in template |
-
-
-### Uncategorized
-
-|    | Rule ID | Description |
-|:---|:--------|:------------|
-| :wrench: | [html-closing-bracket-newline](./docs/rules/html-closing-bracket-newline.md) | require or disallow a line break before tag's closing brackets |
-| :wrench: | [html-closing-bracket-spacing](./docs/rules/html-closing-bracket-spacing.md) | require or disallow a space before tag's closing brackets |
-
+| :wrench: | [vue/html-quotes](./docs/rules/html-quotes.md) | enforce quotes style of HTML attributes |
+|  | [vue/no-confusing-v-for-v-if](./docs/rules/no-confusing-v-for-v-if.md) | disallow confusing `v-for` and `v-if` on the same element |
+|  | [vue/order-in-components](./docs/rules/order-in-components.md) | enforce order of properties in components |
+|  | [vue/this-in-template](./docs/rules/this-in-template.md) | enforce usage of `this` in template |
 
 ### Uncategorized
 
 |    | Rule ID | Description |
 |:---|:--------|:------------|
-| :wrench: | [html-closing-bracket-newline](./docs/rules/html-closing-bracket-newline.md) | require or disallow a line break before tag's closing brackets |
-| :wrench: | [html-closing-bracket-spacing](./docs/rules/html-closing-bracket-spacing.md) | require or disallow a space before tag's closing brackets |
+| :wrench: | [vue/html-closing-bracket-newline](./docs/rules/html-closing-bracket-newline.md) | require or disallow a line break before tag's closing brackets |
+| :wrench: | [vue/html-closing-bracket-spacing](./docs/rules/html-closing-bracket-spacing.md) | require or disallow a space before tag's closing brackets |
 
 <!--RULES_TABLE_END-->
 
diff --git a/docs/rules/attribute-hyphenation.md b/docs/rules/attribute-hyphenation.md
index 7decbece..e161172f 100644
--- a/docs/rules/attribute-hyphenation.md
+++ b/docs/rules/attribute-hyphenation.md
@@ -1,5 +1,6 @@
-# enforce attribute naming style in template (attribute-hyphenation)
+# enforce attribute naming style in template (vue/attribute-hyphenation)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 ## :wrench: Options
diff --git a/docs/rules/comment-directive.md b/docs/rules/comment-directive.md
index fd03e101..42a12a86 100644
--- a/docs/rules/comment-directive.md
+++ b/docs/rules/comment-directive.md
@@ -1,4 +1,6 @@
-# support comment-directives in `<template>` (comment-directive)
+# support comment-directives in `<template>` (vue/comment-directive)
+
+- :gear: This rule is included in all of `"plugin:vue/base"`, `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 Sole purpose of this rule is to provide `eslint-disable` functionality in `<template>`.
 It supports usage of the following comments:
diff --git a/docs/rules/html-closing-bracket-newline.md b/docs/rules/html-closing-bracket-newline.md
index f1c5327d..4d2e9aed 100644
--- a/docs/rules/html-closing-bracket-newline.md
+++ b/docs/rules/html-closing-bracket-newline.md
@@ -1,4 +1,4 @@
-# require or disallow a line break before tag's closing brackets (html-closing-bracket-newline)
+# require or disallow a line break before tag's closing brackets (vue/html-closing-bracket-newline)
 
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
diff --git a/docs/rules/html-closing-bracket-spacing.md b/docs/rules/html-closing-bracket-spacing.md
index 52799dd0..4e92f547 100644
--- a/docs/rules/html-closing-bracket-spacing.md
+++ b/docs/rules/html-closing-bracket-spacing.md
@@ -1,4 +1,4 @@
-# require or disallow a space before tag's closing brackets (html-closing-bracket-spacing)
+# require or disallow a space before tag's closing brackets (vue/html-closing-bracket-spacing)
 
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
diff --git a/docs/rules/html-end-tags.md b/docs/rules/html-end-tags.md
index 9355213f..d15f4060 100644
--- a/docs/rules/html-end-tags.md
+++ b/docs/rules/html-end-tags.md
@@ -1,5 +1,6 @@
-# enforce end tag style (html-end-tags)
+# enforce end tag style (vue/html-end-tags)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/html-indent.md b/docs/rules/html-indent.md
index 51d7cca6..4b816eab 100644
--- a/docs/rules/html-indent.md
+++ b/docs/rules/html-indent.md
@@ -1,5 +1,6 @@
-# enforce consistent indentation in `<template>` (html-indent)
+# enforce consistent indentation in `<template>` (vue/html-indent)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/html-quotes.md b/docs/rules/html-quotes.md
index bb1f0042..16cce04e 100644
--- a/docs/rules/html-quotes.md
+++ b/docs/rules/html-quotes.md
@@ -1,5 +1,6 @@
-# enforce quotes style of HTML attributes (html-quotes)
+# enforce quotes style of HTML attributes (vue/html-quotes)
 
+- :gear: This rule is included in `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 You can choose quotes of HTML attributes from:
diff --git a/docs/rules/html-self-closing.md b/docs/rules/html-self-closing.md
index 448e495d..4c269b2f 100644
--- a/docs/rules/html-self-closing.md
+++ b/docs/rules/html-self-closing.md
@@ -1,5 +1,6 @@
-# enforce self-closing style (html-self-closing)
+# enforce self-closing style (vue/html-self-closing)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 In Vue.js template, we can use either two styles for elements which don't have their content.
diff --git a/docs/rules/jsx-uses-vars.md b/docs/rules/jsx-uses-vars.md
index 512f386d..5f02a04b 100644
--- a/docs/rules/jsx-uses-vars.md
+++ b/docs/rules/jsx-uses-vars.md
@@ -1,4 +1,6 @@
-# prevent variables used in JSX to be marked as unused (jsx-uses-vars)
+# prevent variables used in JSX to be marked as unused (vue/jsx-uses-vars)
+
+- :gear: This rule is included in all of `"plugin:vue/base"`, `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 Since 0.17.0 the ESLint `no-unused-vars` rule does not detect variables used in JSX ([see details](http://eslint.org/blog/2015/03/eslint-0.17.0-released#changes-to-jsxreact-handling)).
 This rule will find variables used in JSX and mark them as used.
diff --git a/docs/rules/max-attributes-per-line.md b/docs/rules/max-attributes-per-line.md
index 308f4342..0fd4d918 100644
--- a/docs/rules/max-attributes-per-line.md
+++ b/docs/rules/max-attributes-per-line.md
@@ -1,4 +1,6 @@
-# enforce the maximum number of attributes per line (max-attributes-per-line)
+# enforce the maximum number of attributes per line (vue/max-attributes-per-line)
+
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 Limits the maximum number of attributes/properties per line to improve readability.
 
diff --git a/docs/rules/mustache-interpolation-spacing.md b/docs/rules/mustache-interpolation-spacing.md
index 1ad2bdc5..25efd4fa 100644
--- a/docs/rules/mustache-interpolation-spacing.md
+++ b/docs/rules/mustache-interpolation-spacing.md
@@ -1,5 +1,6 @@
-# enforce unified spacing in mustache interpolations (mustache-interpolation-spacing)
+# enforce unified spacing in mustache interpolations (vue/mustache-interpolation-spacing)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 ## :book: Rule Details
diff --git a/docs/rules/name-property-casing.md b/docs/rules/name-property-casing.md
index 1d0e2598..3349351e 100644
--- a/docs/rules/name-property-casing.md
+++ b/docs/rules/name-property-casing.md
@@ -1,5 +1,6 @@
-# enforce specific casing for the name property in Vue components (name-property-casing)
+# enforce specific casing for the name property in Vue components (vue/name-property-casing)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 Define a style for the `name` property casing for consistency purposes.
diff --git a/docs/rules/no-async-in-computed-properties.md b/docs/rules/no-async-in-computed-properties.md
index a4b32c5f..1cc1ece0 100644
--- a/docs/rules/no-async-in-computed-properties.md
+++ b/docs/rules/no-async-in-computed-properties.md
@@ -1,4 +1,6 @@
-# disallow asynchronous actions in computed properties (no-async-in-computed-properties)
+# disallow asynchronous actions in computed properties (vue/no-async-in-computed-properties)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 Computed properties should be synchronous. Asynchronous actions inside them may not work as expected and can lead to an unexpected behaviour, that's why you should avoid them.
 If you need async computed properties you might want to consider using additional plugin [vue-async-computed]
diff --git a/docs/rules/no-confusing-v-for-v-if.md b/docs/rules/no-confusing-v-for-v-if.md
index 55ab658e..c08732cb 100644
--- a/docs/rules/no-confusing-v-for-v-if.md
+++ b/docs/rules/no-confusing-v-for-v-if.md
@@ -1,4 +1,6 @@
-# disallow confusing `v-for` and `v-if` on the same element (no-confusing-v-for-v-if)
+# disallow confusing `v-for` and `v-if` on the same element (vue/no-confusing-v-for-v-if)
+
+- :gear: This rule is included in `"plugin:vue/recommended"`.
 
 > When they exist on the same node, `v-for` has a higher priority than `v-if`. That means the `v-if` will be run on each iteration of the loop separately.
 >
diff --git a/docs/rules/no-dupe-keys.md b/docs/rules/no-dupe-keys.md
index e2d839eb..aa86d0f5 100644
--- a/docs/rules/no-dupe-keys.md
+++ b/docs/rules/no-dupe-keys.md
@@ -1,4 +1,6 @@
-# disallow duplication of field names (no-dupe-keys)
+# disallow duplication of field names (vue/no-dupe-keys)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule prevents to use duplicated names.
 
diff --git a/docs/rules/no-duplicate-attributes.md b/docs/rules/no-duplicate-attributes.md
index 989bbe7a..51a37789 100644
--- a/docs/rules/no-duplicate-attributes.md
+++ b/docs/rules/no-duplicate-attributes.md
@@ -1,4 +1,6 @@
-# disallow duplication of attributes (no-duplicate-attributes)
+# disallow duplication of attributes (vue/no-duplicate-attributes)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 When duplicate arguments exist, only the last one is valid.
 It's possibly mistakes.
diff --git a/docs/rules/no-multi-spaces.md b/docs/rules/no-multi-spaces.md
index 30ba8e14..196bee56 100644
--- a/docs/rules/no-multi-spaces.md
+++ b/docs/rules/no-multi-spaces.md
@@ -1,5 +1,6 @@
-# disallow multiple spaces (no-multi-spaces)
+# disallow multiple spaces (vue/no-multi-spaces)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 The `--fix` option on the command line can automatically fix some of the problems reported by this rule.
diff --git a/docs/rules/no-parsing-error.md b/docs/rules/no-parsing-error.md
index 7fbee81a..c5988b79 100644
--- a/docs/rules/no-parsing-error.md
+++ b/docs/rules/no-parsing-error.md
@@ -1,4 +1,6 @@
-# disallow parsing errors in `<template>` (no-parsing-error)
+# disallow parsing errors in `<template>` (vue/no-parsing-error)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule reports syntax errors in `<template>`. For example:
 
diff --git a/docs/rules/no-reserved-keys.md b/docs/rules/no-reserved-keys.md
index f6aefd7c..80331d4d 100644
--- a/docs/rules/no-reserved-keys.md
+++ b/docs/rules/no-reserved-keys.md
@@ -1,4 +1,6 @@
-# disallow overwriting reserved keys (no-reserved-keys)
+# disallow overwriting reserved keys (vue/no-reserved-keys)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule prevents to use reserved names from to avoid conflicts and unexpected behavior.
 
diff --git a/docs/rules/no-shared-component-data.md b/docs/rules/no-shared-component-data.md
index 1bba0424..346e4832 100644
--- a/docs/rules/no-shared-component-data.md
+++ b/docs/rules/no-shared-component-data.md
@@ -1,5 +1,6 @@
-# enforce component's data property to be a function (no-shared-component-data)
+# enforce component's data property to be a function (vue/no-shared-component-data)
 
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 When using the data property on a component (i.e. anywhere except on `new Vue`), the value must be a function that returns an object.
diff --git a/docs/rules/no-side-effects-in-computed-properties.md b/docs/rules/no-side-effects-in-computed-properties.md
index 954e8d46..36066d82 100644
--- a/docs/rules/no-side-effects-in-computed-properties.md
+++ b/docs/rules/no-side-effects-in-computed-properties.md
@@ -1,4 +1,6 @@
-# disallow side effects in computed properties (no-side-effects-in-computed-properties)
+# disallow side effects in computed properties (vue/no-side-effects-in-computed-properties)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 It is considered a very bad practice to introduce side effects inside computed properties. It makes the code not predictable and hard to understand.
 
diff --git a/docs/rules/no-template-key.md b/docs/rules/no-template-key.md
index 217efbc6..b7da4c4b 100644
--- a/docs/rules/no-template-key.md
+++ b/docs/rules/no-template-key.md
@@ -1,4 +1,6 @@
-# disallow `key` attribute on `<template>` (no-template-key)
+# disallow `key` attribute on `<template>` (vue/no-template-key)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 Vue.js disallows `key` attribute on `<template>` elements.
 
diff --git a/docs/rules/no-textarea-mustache.md b/docs/rules/no-textarea-mustache.md
index d204c1fd..0241138f 100644
--- a/docs/rules/no-textarea-mustache.md
+++ b/docs/rules/no-textarea-mustache.md
@@ -1,4 +1,6 @@
-# disallow mustaches in `<textarea>` (no-textarea-mustache)
+# disallow mustaches in `<textarea>` (vue/no-textarea-mustache)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 > Interpolation on textareas (`<textarea>{{text}}</textarea>`) won't work. Use `v-model` instead.
 >
diff --git a/docs/rules/no-unused-vars.md b/docs/rules/no-unused-vars.md
index 9691ec41..34e48ebb 100644
--- a/docs/rules/no-unused-vars.md
+++ b/docs/rules/no-unused-vars.md
@@ -1,4 +1,6 @@
-# disallow unused variable definitions of v-for directives or scope attributes (no-unused-vars)
+# disallow unused variable definitions of v-for directives or scope attributes (vue/no-unused-vars)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule report variable definitions of v-for directives or scope attributes if those are not used.
 
diff --git a/docs/rules/order-in-components.md b/docs/rules/order-in-components.md
index 674140d7..ba40ca20 100644
--- a/docs/rules/order-in-components.md
+++ b/docs/rules/order-in-components.md
@@ -1,4 +1,6 @@
-# enforce order of properties in components (order-in-components)
+# enforce order of properties in components (vue/order-in-components)
+
+- :gear: This rule is included in `"plugin:vue/recommended"`.
 
 This rule makes sure you keep declared order of properties in components.
 
diff --git a/docs/rules/require-component-is.md b/docs/rules/require-component-is.md
index 0d929676..cf8a9d89 100644
--- a/docs/rules/require-component-is.md
+++ b/docs/rules/require-component-is.md
@@ -1,4 +1,6 @@
-# require `v-bind:is` of `<component>` elements (require-component-is)
+# require `v-bind:is` of `<component>` elements (vue/require-component-is)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 > You can use the same mount point and dynamically switch between multiple components using the reserved `<component>` element and dynamically bind to its `is` attribute:
 >
diff --git a/docs/rules/require-default-prop.md b/docs/rules/require-default-prop.md
index 1071d4f9..bacaae0b 100644
--- a/docs/rules/require-default-prop.md
+++ b/docs/rules/require-default-prop.md
@@ -1,4 +1,6 @@
-# require default value for props (require-default-prop)
+# require default value for props (vue/require-default-prop)
+
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule requires default value to be set for each props that are not marked as `required`.
 
diff --git a/docs/rules/require-prop-types.md b/docs/rules/require-prop-types.md
index a1b396e1..c163a670 100644
--- a/docs/rules/require-prop-types.md
+++ b/docs/rules/require-prop-types.md
@@ -1,4 +1,6 @@
-# require type definitions in props (require-prop-types)
+# require type definitions in props (vue/require-prop-types)
+
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 In committed code, prop definitions should always be as detailed as possible, specifying at least type(s).
 
diff --git a/docs/rules/require-render-return.md b/docs/rules/require-render-return.md
index b4780b17..a28826c2 100644
--- a/docs/rules/require-render-return.md
+++ b/docs/rules/require-render-return.md
@@ -1,4 +1,6 @@
-# enforce render function to always return value (require-render-return)
+# enforce render function to always return value (vue/require-render-return)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule aims to enforce render function to always return value
 
diff --git a/docs/rules/require-v-for-key.md b/docs/rules/require-v-for-key.md
index c48f5ea9..5c54a3d2 100644
--- a/docs/rules/require-v-for-key.md
+++ b/docs/rules/require-v-for-key.md
@@ -1,4 +1,6 @@
-# require `v-bind:key` with `v-for` directives (require-v-for-key)
+# require `v-bind:key` with `v-for` directives (vue/require-v-for-key)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 When `v-for` is written on custom components, it requires `v-bind:key` at the same time.
 On other elements, it's better that `v-bind:key` is written as well.
diff --git a/docs/rules/require-valid-default-prop.md b/docs/rules/require-valid-default-prop.md
index fad89c09..568d65ae 100644
--- a/docs/rules/require-valid-default-prop.md
+++ b/docs/rules/require-valid-default-prop.md
@@ -1,4 +1,6 @@
-# enforce props default values to be valid (require-valid-default-prop)
+# enforce props default values to be valid (vue/require-valid-default-prop)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether the default value of each prop is valid for the given type. It should report an error when default value for type `Array` or `Object` is not returned using function.
 
diff --git a/docs/rules/return-in-computed-property.md b/docs/rules/return-in-computed-property.md
index 87fdb26f..761db13a 100644
--- a/docs/rules/return-in-computed-property.md
+++ b/docs/rules/return-in-computed-property.md
@@ -1,4 +1,6 @@
-# enforce that a return statement is present in computed property (return-in-computed-property)
+# enforce that a return statement is present in computed property (vue/return-in-computed-property)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 ## :book: Rule Details
 
diff --git a/docs/rules/this-in-template.md b/docs/rules/this-in-template.md
index 270f9389..d0603edd 100644
--- a/docs/rules/this-in-template.md
+++ b/docs/rules/this-in-template.md
@@ -1,4 +1,6 @@
-# enforce usage of `this` in template (this-in-template)
+# enforce usage of `this` in template (vue/this-in-template)
+
+- :gear: This rule is included in `"plugin:vue/recommended"`.
 
 ## :book: Rule Details
 
diff --git a/docs/rules/v-bind-style.md b/docs/rules/v-bind-style.md
index 351c7e4b..eb33a8d8 100644
--- a/docs/rules/v-bind-style.md
+++ b/docs/rules/v-bind-style.md
@@ -1,5 +1,6 @@
-# enforce `v-bind` directive style (v-bind-style)
+# enforce `v-bind` directive style (vue/v-bind-style)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 This rule enforces `v-bind` directive style which you should use shorthand or long form.
diff --git a/docs/rules/v-on-style.md b/docs/rules/v-on-style.md
index 4dab8bc4..0adc88e5 100644
--- a/docs/rules/v-on-style.md
+++ b/docs/rules/v-on-style.md
@@ -1,5 +1,6 @@
-# enforce `v-on` directive style (v-on-style)
+# enforce `v-on` directive style (vue/v-on-style)
 
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 - :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
 
 This rule enforces `v-on` directive style which you should use shorthand or long form.
diff --git a/docs/rules/valid-template-root.md b/docs/rules/valid-template-root.md
index 271ea935..e113d524 100644
--- a/docs/rules/valid-template-root.md
+++ b/docs/rules/valid-template-root.md
@@ -1,4 +1,6 @@
-# enforce valid template root (valid-template-root)
+# enforce valid template root (vue/valid-template-root)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every template root is valid.
 
diff --git a/docs/rules/valid-v-bind.md b/docs/rules/valid-v-bind.md
index 0d944504..dfc9091d 100644
--- a/docs/rules/valid-v-bind.md
+++ b/docs/rules/valid-v-bind.md
@@ -1,4 +1,6 @@
-# enforce valid `v-bind` directives (valid-v-bind)
+# enforce valid `v-bind` directives (vue/valid-v-bind)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-bind` directive is valid.
 
diff --git a/docs/rules/valid-v-cloak.md b/docs/rules/valid-v-cloak.md
index 175067f8..4b7b9a4a 100644
--- a/docs/rules/valid-v-cloak.md
+++ b/docs/rules/valid-v-cloak.md
@@ -1,4 +1,6 @@
-# enforce valid `v-cloak` directives (valid-v-cloak)
+# enforce valid `v-cloak` directives (vue/valid-v-cloak)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-cloak` directive is valid.
 
@@ -12,8 +14,6 @@ This rule reports `v-cloak` directives in the following cases:
 
 :-1: Examples of **incorrect** code for this rule:
 
-:-1: Examples of **incorrect** code for this rule:
-
 ```html
 <div v-cloak:aaa/>
 <div v-cloak.bbb/>
diff --git a/docs/rules/valid-v-else-if.md b/docs/rules/valid-v-else-if.md
index a04347a7..a7334008 100644
--- a/docs/rules/valid-v-else-if.md
+++ b/docs/rules/valid-v-else-if.md
@@ -1,4 +1,6 @@
-# enforce valid `v-else-if` directives (valid-v-else-if)
+# enforce valid `v-else-if` directives (vue/valid-v-else-if)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-else-if` directive is valid.
 
diff --git a/docs/rules/valid-v-else.md b/docs/rules/valid-v-else.md
index 25f39f78..5c63b155 100644
--- a/docs/rules/valid-v-else.md
+++ b/docs/rules/valid-v-else.md
@@ -1,4 +1,6 @@
-# enforce valid `v-else` directives (valid-v-else)
+# enforce valid `v-else` directives (vue/valid-v-else)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-else` directive is valid.
 
diff --git a/docs/rules/valid-v-for.md b/docs/rules/valid-v-for.md
index f799c804..13f8e9de 100644
--- a/docs/rules/valid-v-for.md
+++ b/docs/rules/valid-v-for.md
@@ -1,4 +1,6 @@
-# enforce valid `v-for` directives (valid-v-for)
+# enforce valid `v-for` directives (vue/valid-v-for)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-for` directive is valid.
 
diff --git a/docs/rules/valid-v-html.md b/docs/rules/valid-v-html.md
index 3c46bcbe..d562b675 100644
--- a/docs/rules/valid-v-html.md
+++ b/docs/rules/valid-v-html.md
@@ -1,4 +1,6 @@
-# enforce valid `v-html` directives (valid-v-html)
+# enforce valid `v-html` directives (vue/valid-v-html)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-html` directive is valid.
 
diff --git a/docs/rules/valid-v-if.md b/docs/rules/valid-v-if.md
index e57f022d..53c42f42 100644
--- a/docs/rules/valid-v-if.md
+++ b/docs/rules/valid-v-if.md
@@ -1,4 +1,6 @@
-# enforce valid `v-if` directives (valid-v-if)
+# enforce valid `v-if` directives (vue/valid-v-if)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-if` directive is valid.
 
@@ -15,8 +17,6 @@ This rule does not check syntax errors in directives because it's checked by [no
 
 :-1: Examples of **incorrect** code for this rule:
 
-:-1: Examples of **incorrect** code for this rule:
-
 ```html
 <div v-if/>
 <div v-if:aaa="foo"/>
diff --git a/docs/rules/valid-v-model.md b/docs/rules/valid-v-model.md
index fd1ff509..2661c6b3 100644
--- a/docs/rules/valid-v-model.md
+++ b/docs/rules/valid-v-model.md
@@ -1,4 +1,6 @@
-# enforce valid `v-model` directives (valid-v-model)
+# enforce valid `v-model` directives (vue/valid-v-model)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-model` directive is valid.
 
diff --git a/docs/rules/valid-v-on.md b/docs/rules/valid-v-on.md
index 20ab1184..18580ccc 100644
--- a/docs/rules/valid-v-on.md
+++ b/docs/rules/valid-v-on.md
@@ -1,4 +1,6 @@
-# enforce valid `v-on` directives (valid-v-on)
+# enforce valid `v-on` directives (vue/valid-v-on)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-on` directive is valid.
 
@@ -14,8 +16,6 @@ This rule does not check syntax errors in directives because it's checked by [no
 
 :-1: Examples of **incorrect** code for this rule:
 
-:-1: Examples of **incorrect** code for this rule:
-
 ```html
 <div v-on/>
 <div v-on:click/>
diff --git a/docs/rules/valid-v-once.md b/docs/rules/valid-v-once.md
index 168af299..0c3aefb9 100644
--- a/docs/rules/valid-v-once.md
+++ b/docs/rules/valid-v-once.md
@@ -1,4 +1,6 @@
-# enforce valid `v-once` directives (valid-v-once)
+# enforce valid `v-once` directives (vue/valid-v-once)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-once` directive is valid.
 
diff --git a/docs/rules/valid-v-pre.md b/docs/rules/valid-v-pre.md
index 4d177682..4b36030c 100644
--- a/docs/rules/valid-v-pre.md
+++ b/docs/rules/valid-v-pre.md
@@ -1,4 +1,6 @@
-# enforce valid `v-pre` directives (valid-v-pre)
+# enforce valid `v-pre` directives (vue/valid-v-pre)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-pre` directive is valid.
 
diff --git a/docs/rules/valid-v-show.md b/docs/rules/valid-v-show.md
index 7fb00cfd..5742c76b 100644
--- a/docs/rules/valid-v-show.md
+++ b/docs/rules/valid-v-show.md
@@ -1,4 +1,6 @@
-# enforce valid `v-show` directives (valid-v-show)
+# enforce valid `v-show` directives (vue/valid-v-show)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-show` directive is valid.
 
diff --git a/docs/rules/valid-v-text.md b/docs/rules/valid-v-text.md
index 8fbf42a2..df777712 100644
--- a/docs/rules/valid-v-text.md
+++ b/docs/rules/valid-v-text.md
@@ -1,4 +1,6 @@
-# enforce valid `v-text` directives (valid-v-text)
+# enforce valid `v-text` directives (vue/valid-v-text)
+
+- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
 
 This rule checks whether every `v-text` directive is valid.
 
diff --git a/lib/base-rules.js b/lib/base-rules.js
deleted file mode 100644
index 53cde306..00000000
--- a/lib/base-rules.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-* IMPORTANT!
-* This file has been automatically generated,
-* in order to update it's content execute "npm run update"
-*/
-module.exports = {
-  "vue/comment-directive": "error",
-  "vue/jsx-uses-vars": "error"
-}
\ No newline at end of file
diff --git a/lib/config/essential.js b/lib/config/essential.js
deleted file mode 100644
index 47493152..00000000
--- a/lib/config/essential.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = {
-  extends: require.resolve('./base.js'),
-  rules: require('../essential-rules.js')
-}
diff --git a/lib/config/recommended.js b/lib/config/recommended.js
deleted file mode 100644
index a3b7f7f3..00000000
--- a/lib/config/recommended.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = {
-  extends: require.resolve('./base.js'),
-  rules: require('../recommended-rules.js')
-}
diff --git a/lib/config/strongly-recommended.js b/lib/config/strongly-recommended.js
deleted file mode 100644
index af0045aa..00000000
--- a/lib/config/strongly-recommended.js
+++ /dev/null
@@ -1,4 +0,0 @@
-module.exports = {
-  extends: require.resolve('./base.js'),
-  rules: require('../strongly-recommended-rules.js')
-}
diff --git a/lib/config/base.js b/lib/configs/base.js
similarity index 55%
rename from lib/config/base.js
rename to lib/configs/base.js
index 2039b801..54e00275 100644
--- a/lib/config/base.js
+++ b/lib/configs/base.js
@@ -1,25 +1,28 @@
+/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
 module.exports = {
   root: true,
-
   parser: require.resolve('vue-eslint-parser'),
-
   parserOptions: {
-    ecmaVersion: 6,
+    ecmaVersion: 2015,
     sourceType: 'module',
     ecmaFeatures: {
       jsx: true,
       experimentalObjectRestSpread: true
     }
   },
-
   env: {
     browser: true,
     es6: true
   },
-
   plugins: [
     'vue'
   ],
-
-  rules: require('../base-rules.js')
+  rules: {
+    'vue/comment-directive': 'error',
+    'vue/jsx-uses-vars': 'error'
+  }
 }
diff --git a/lib/configs/essential.js b/lib/configs/essential.js
new file mode 100644
index 00000000..5d36fb3a
--- /dev/null
+++ b/lib/configs/essential.js
@@ -0,0 +1,39 @@
+/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
+module.exports = {
+  extends: require.resolve('./base'),
+  rules: {
+    'vue/no-async-in-computed-properties': 'error',
+    'vue/no-dupe-keys': 'error',
+    'vue/no-duplicate-attributes': 'error',
+    'vue/no-parsing-error': 'error',
+    'vue/no-reserved-keys': 'error',
+    'vue/no-shared-component-data': 'error',
+    'vue/no-side-effects-in-computed-properties': 'error',
+    'vue/no-template-key': 'error',
+    'vue/no-textarea-mustache': 'error',
+    'vue/no-unused-vars': 'error',
+    'vue/require-component-is': 'error',
+    'vue/require-render-return': 'error',
+    'vue/require-v-for-key': 'error',
+    'vue/require-valid-default-prop': 'error',
+    'vue/return-in-computed-property': 'error',
+    'vue/valid-template-root': 'error',
+    'vue/valid-v-bind': 'error',
+    'vue/valid-v-cloak': 'error',
+    'vue/valid-v-else-if': 'error',
+    'vue/valid-v-else': 'error',
+    'vue/valid-v-for': 'error',
+    'vue/valid-v-html': 'error',
+    'vue/valid-v-if': 'error',
+    'vue/valid-v-model': 'error',
+    'vue/valid-v-on': 'error',
+    'vue/valid-v-once': 'error',
+    'vue/valid-v-pre': 'error',
+    'vue/valid-v-show': 'error',
+    'vue/valid-v-text': 'error'
+  }
+}
diff --git a/lib/configs/recommended.js b/lib/configs/recommended.js
new file mode 100644
index 00000000..47a0fec9
--- /dev/null
+++ b/lib/configs/recommended.js
@@ -0,0 +1,14 @@
+/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
+module.exports = {
+  extends: require.resolve('./strongly-recommended'),
+  rules: {
+    'vue/html-quotes': 'error',
+    'vue/no-confusing-v-for-v-if': 'error',
+    'vue/order-in-components': 'error',
+    'vue/this-in-template': 'error'
+  }
+}
diff --git a/lib/configs/strongly-recommended.js b/lib/configs/strongly-recommended.js
new file mode 100644
index 00000000..993c78d3
--- /dev/null
+++ b/lib/configs/strongly-recommended.js
@@ -0,0 +1,22 @@
+/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
+module.exports = {
+  extends: require.resolve('./essential'),
+  rules: {
+    'vue/attribute-hyphenation': 'error',
+    'vue/html-end-tags': 'error',
+    'vue/html-indent': 'error',
+    'vue/html-self-closing': 'error',
+    'vue/max-attributes-per-line': 'error',
+    'vue/mustache-interpolation-spacing': 'error',
+    'vue/name-property-casing': 'error',
+    'vue/no-multi-spaces': 'error',
+    'vue/require-default-prop': 'error',
+    'vue/require-prop-types': 'error',
+    'vue/v-bind-style': 'error',
+    'vue/v-on-style': 'error'
+  }
+}
diff --git a/lib/essential-rules.js b/lib/essential-rules.js
deleted file mode 100644
index 0d94c171..00000000
--- a/lib/essential-rules.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-* IMPORTANT!
-* This file has been automatically generated,
-* in order to update it's content execute "npm run update"
-*/
-module.exports = {
-  "vue/comment-directive": "error",
-  "vue/jsx-uses-vars": "error",
-  "vue/no-async-in-computed-properties": "error",
-  "vue/no-dupe-keys": "error",
-  "vue/no-duplicate-attributes": "error",
-  "vue/no-parsing-error": "error",
-  "vue/no-reserved-keys": "error",
-  "vue/no-shared-component-data": "error",
-  "vue/no-side-effects-in-computed-properties": "error",
-  "vue/no-template-key": "error",
-  "vue/no-textarea-mustache": "error",
-  "vue/no-unused-vars": "error",
-  "vue/require-component-is": "error",
-  "vue/require-render-return": "error",
-  "vue/require-v-for-key": "error",
-  "vue/require-valid-default-prop": "error",
-  "vue/return-in-computed-property": "error",
-  "vue/valid-template-root": "error",
-  "vue/valid-v-bind": "error",
-  "vue/valid-v-cloak": "error",
-  "vue/valid-v-else-if": "error",
-  "vue/valid-v-else": "error",
-  "vue/valid-v-for": "error",
-  "vue/valid-v-html": "error",
-  "vue/valid-v-if": "error",
-  "vue/valid-v-model": "error",
-  "vue/valid-v-on": "error",
-  "vue/valid-v-once": "error",
-  "vue/valid-v-pre": "error",
-  "vue/valid-v-show": "error",
-  "vue/valid-v-text": "error"
-}
\ No newline at end of file
diff --git a/lib/index.js b/lib/index.js
index ba9eebe6..dff5dd4c 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,20 +1,69 @@
+/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
 'use strict'
 
-const resolve = require('path').resolve
-const requireAll = require('require-all')
-
-const rules = requireAll({
-  dirname: resolve(__dirname, 'rules'),
-  filter: /^([\w\-]+)\.js$/
-})
-const configs = requireAll({
-  dirname: resolve(__dirname, 'config'),
-  filter: /^([\w\-]+)\.js$/
-})
-const processor = require('./processor')
-
 module.exports = {
-  rules,
-  configs,
-  processors: { '.vue': processor }
+  rules: {
+    'attribute-hyphenation': require('./rules/attribute-hyphenation'),
+    'comment-directive': require('./rules/comment-directive'),
+    'html-closing-bracket-newline': require('./rules/html-closing-bracket-newline'),
+    'html-closing-bracket-spacing': require('./rules/html-closing-bracket-spacing'),
+    'html-end-tags': require('./rules/html-end-tags'),
+    'html-indent': require('./rules/html-indent'),
+    'html-quotes': require('./rules/html-quotes'),
+    'html-self-closing': require('./rules/html-self-closing'),
+    'jsx-uses-vars': require('./rules/jsx-uses-vars'),
+    'max-attributes-per-line': require('./rules/max-attributes-per-line'),
+    'mustache-interpolation-spacing': require('./rules/mustache-interpolation-spacing'),
+    'name-property-casing': require('./rules/name-property-casing'),
+    'no-async-in-computed-properties': require('./rules/no-async-in-computed-properties'),
+    'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
+    'no-dupe-keys': require('./rules/no-dupe-keys'),
+    'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
+    'no-multi-spaces': require('./rules/no-multi-spaces'),
+    'no-parsing-error': require('./rules/no-parsing-error'),
+    'no-reserved-keys': require('./rules/no-reserved-keys'),
+    'no-shared-component-data': require('./rules/no-shared-component-data'),
+    'no-side-effects-in-computed-properties': require('./rules/no-side-effects-in-computed-properties'),
+    'no-template-key': require('./rules/no-template-key'),
+    'no-textarea-mustache': require('./rules/no-textarea-mustache'),
+    'no-unused-vars': require('./rules/no-unused-vars'),
+    'order-in-components': require('./rules/order-in-components'),
+    'require-component-is': require('./rules/require-component-is'),
+    'require-default-prop': require('./rules/require-default-prop'),
+    'require-prop-types': require('./rules/require-prop-types'),
+    'require-render-return': require('./rules/require-render-return'),
+    'require-v-for-key': require('./rules/require-v-for-key'),
+    'require-valid-default-prop': require('./rules/require-valid-default-prop'),
+    'return-in-computed-property': require('./rules/return-in-computed-property'),
+    'this-in-template': require('./rules/this-in-template'),
+    'v-bind-style': require('./rules/v-bind-style'),
+    'v-on-style': require('./rules/v-on-style'),
+    'valid-template-root': require('./rules/valid-template-root'),
+    'valid-v-bind': require('./rules/valid-v-bind'),
+    'valid-v-cloak': require('./rules/valid-v-cloak'),
+    'valid-v-else-if': require('./rules/valid-v-else-if'),
+    'valid-v-else': require('./rules/valid-v-else'),
+    'valid-v-for': require('./rules/valid-v-for'),
+    'valid-v-html': require('./rules/valid-v-html'),
+    'valid-v-if': require('./rules/valid-v-if'),
+    'valid-v-model': require('./rules/valid-v-model'),
+    'valid-v-on': require('./rules/valid-v-on'),
+    'valid-v-once': require('./rules/valid-v-once'),
+    'valid-v-pre': require('./rules/valid-v-pre'),
+    'valid-v-show': require('./rules/valid-v-show'),
+    'valid-v-text': require('./rules/valid-v-text')
+  },
+  configs: {
+    'base': require('./configs/base'),
+    'essential': require('./configs/essential'),
+    'strongly-recommended': require('./configs/strongly-recommended'),
+    'recommended': require('./configs/recommended')
+  },
+  processors: {
+    '.vue': require('./processor')
+  }
 }
diff --git a/lib/recommended-rules.js b/lib/recommended-rules.js
deleted file mode 100644
index 2ce4178c..00000000
--- a/lib/recommended-rules.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-* IMPORTANT!
-* This file has been automatically generated,
-* in order to update it's content execute "npm run update"
-*/
-module.exports = {
-  "vue/attribute-hyphenation": "error",
-  "vue/comment-directive": "error",
-  "vue/html-end-tags": "error",
-  "vue/html-indent": "error",
-  "vue/html-quotes": "error",
-  "vue/html-self-closing": "error",
-  "vue/jsx-uses-vars": "error",
-  "vue/max-attributes-per-line": "error",
-  "vue/mustache-interpolation-spacing": "error",
-  "vue/name-property-casing": "error",
-  "vue/no-async-in-computed-properties": "error",
-  "vue/no-confusing-v-for-v-if": "error",
-  "vue/no-dupe-keys": "error",
-  "vue/no-duplicate-attributes": "error",
-  "vue/no-multi-spaces": "error",
-  "vue/no-parsing-error": "error",
-  "vue/no-reserved-keys": "error",
-  "vue/no-shared-component-data": "error",
-  "vue/no-side-effects-in-computed-properties": "error",
-  "vue/no-template-key": "error",
-  "vue/no-textarea-mustache": "error",
-  "vue/no-unused-vars": "error",
-  "vue/order-in-components": "error",
-  "vue/require-component-is": "error",
-  "vue/require-default-prop": "error",
-  "vue/require-prop-types": "error",
-  "vue/require-render-return": "error",
-  "vue/require-v-for-key": "error",
-  "vue/require-valid-default-prop": "error",
-  "vue/return-in-computed-property": "error",
-  "vue/this-in-template": "error",
-  "vue/v-bind-style": "error",
-  "vue/v-on-style": "error",
-  "vue/valid-template-root": "error",
-  "vue/valid-v-bind": "error",
-  "vue/valid-v-cloak": "error",
-  "vue/valid-v-else-if": "error",
-  "vue/valid-v-else": "error",
-  "vue/valid-v-for": "error",
-  "vue/valid-v-html": "error",
-  "vue/valid-v-if": "error",
-  "vue/valid-v-model": "error",
-  "vue/valid-v-on": "error",
-  "vue/valid-v-once": "error",
-  "vue/valid-v-pre": "error",
-  "vue/valid-v-show": "error",
-  "vue/valid-v-text": "error"
-}
\ No newline at end of file
diff --git a/lib/rules/comment-directive.js b/lib/rules/comment-directive.js
index 4afe8109..1e53749d 100644
--- a/lib/rules/comment-directive.js
+++ b/lib/rules/comment-directive.js
@@ -8,8 +8,8 @@
 // Helpers
 // -----------------------------------------------------------------------------
 
-const COMMENT_DIRECTIVE_B = /^\s*(eslint-(?:en|dis)able)\s*(?:(\S|\S[\s\S]*\S)\s*)?$/
-const COMMENT_DIRECTIVE_L = /^\s*(eslint-disable(?:-next)?-line)\s*(?:(\S|\S[\s\S]*\S)\s*)?$/
+const COMMENT_DIRECTIVE_B = /^\s*(eslint-(?:en|dis)able)(?:\s+(\S|\S[\s\S]*\S))?\s*$/
+const COMMENT_DIRECTIVE_L = /^\s*(eslint-disable(?:-next)?-line)(?:\s+(\S|\S[\s\S]*\S))?\s*$/
 
 /**
  * Parse a given comment.
diff --git a/lib/strongly-recommended-rules.js b/lib/strongly-recommended-rules.js
deleted file mode 100644
index 55a451cf..00000000
--- a/lib/strongly-recommended-rules.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-* IMPORTANT!
-* This file has been automatically generated,
-* in order to update it's content execute "npm run update"
-*/
-module.exports = {
-  "vue/attribute-hyphenation": "error",
-  "vue/comment-directive": "error",
-  "vue/html-end-tags": "error",
-  "vue/html-indent": "error",
-  "vue/html-self-closing": "error",
-  "vue/jsx-uses-vars": "error",
-  "vue/max-attributes-per-line": "error",
-  "vue/mustache-interpolation-spacing": "error",
-  "vue/name-property-casing": "error",
-  "vue/no-async-in-computed-properties": "error",
-  "vue/no-dupe-keys": "error",
-  "vue/no-duplicate-attributes": "error",
-  "vue/no-multi-spaces": "error",
-  "vue/no-parsing-error": "error",
-  "vue/no-reserved-keys": "error",
-  "vue/no-shared-component-data": "error",
-  "vue/no-side-effects-in-computed-properties": "error",
-  "vue/no-template-key": "error",
-  "vue/no-textarea-mustache": "error",
-  "vue/no-unused-vars": "error",
-  "vue/require-component-is": "error",
-  "vue/require-default-prop": "error",
-  "vue/require-prop-types": "error",
-  "vue/require-render-return": "error",
-  "vue/require-v-for-key": "error",
-  "vue/require-valid-default-prop": "error",
-  "vue/return-in-computed-property": "error",
-  "vue/v-bind-style": "error",
-  "vue/v-on-style": "error",
-  "vue/valid-template-root": "error",
-  "vue/valid-v-bind": "error",
-  "vue/valid-v-cloak": "error",
-  "vue/valid-v-else-if": "error",
-  "vue/valid-v-else": "error",
-  "vue/valid-v-for": "error",
-  "vue/valid-v-html": "error",
-  "vue/valid-v-if": "error",
-  "vue/valid-v-model": "error",
-  "vue/valid-v-on": "error",
-  "vue/valid-v-once": "error",
-  "vue/valid-v-pre": "error",
-  "vue/valid-v-show": "error",
-  "vue/valid-v-text": "error"
-}
\ No newline at end of file
diff --git a/package.json b/package.json
index 44ad0143..64052abc 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
     "lint": "eslint . --rulesdir eslint-internal-rules",
     "pretest": "npm run lint",
     "preversion": "npm run update && npm test",
-    "update": "node ./tools/update-rules.js"
+    "update": "node ./tools/update.js"
   },
   "files": [
     "lib"
@@ -43,7 +43,6 @@
     "eslint": "^3.18.0 || ^4.0.0"
   },
   "dependencies": {
-    "require-all": "^2.2.0",
     "vue-eslint-parser": "^2.0.1"
   },
   "devDependencies": {
@@ -54,6 +53,7 @@
     "eslint-plugin-eslint-plugin": "^0.8.0",
     "eslint-plugin-html": "^4.0.1",
     "eslint-plugin-vue-libs": "^2.0.0",
+    "lodash": "^4.17.4",
     "mocha": "^3.2.0",
     "nyc": "^11.1.0"
   }
diff --git a/tools/lib/categories.js b/tools/lib/categories.js
new file mode 100644
index 00000000..4a2a0691
--- /dev/null
+++ b/tools/lib/categories.js
@@ -0,0 +1,35 @@
+/**
+ * @author Toru Nagashima
+ * @copyright 2017 Toru Nagashima. All rights reserved.
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+const groupBy = require('lodash/groupBy')
+const rules = require('./rules')
+
+const categoryTitles = {
+  'base': 'Base Rules (Enabling Correct ESLint Parsing)',
+  'essential': 'Priority A: Essential (Error Prevention)',
+  'strongly-recommended': 'Priority B: Strongly Recommended (Improving Readability)',
+  'recommended': 'Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)',
+  'use-with-caution': 'Priority D: Use with Caution (Potentially Dangerous Patterns)'
+}
+const categoryIds = Object.keys(categoryTitles)
+const categoryRules = groupBy(rules, (rule) => rule.meta.docs.category || 'uncategorized')
+
+// Throw if no title is defined for a category
+for (const categoryId of Object.keys(categoryRules)) {
+  if (categoryId !== 'uncategorized' && !categoryTitles[categoryId]) {
+    throw new Error(`Category "${categoryId}" does not have a title defined.`)
+  }
+}
+
+module.exports =
+  categoryIds
+    .map(categoryId => ({
+      categoryId,
+      title: categoryTitles[categoryId],
+      rules: (categoryRules[categoryId] || []).filter(rule => !rule.meta.deprecated)
+    }))
+    .filter(category => category.rules.length >= 1)
diff --git a/tools/lib/rules.js b/tools/lib/rules.js
new file mode 100644
index 00000000..e41d7ba6
--- /dev/null
+++ b/tools/lib/rules.js
@@ -0,0 +1,20 @@
+/**
+ * @author Toru Nagashima <https://github.com/mysticatea>
+ * See LICENSE file in root directory for full license.
+ */
+
+'use strict'
+
+const fs = require('fs')
+const path = require('path')
+const ROOT = path.resolve(__dirname, '../../lib/rules')
+
+module.exports =
+  fs.readdirSync(ROOT)
+    .filter(file => path.extname(file) === '.js')
+    .map(file => path.basename(file, '.js'))
+    .map(name => ({
+      ruleId: `vue/${name}`,
+      name,
+      meta: require(path.join(ROOT, name)).meta
+    }))
diff --git a/tools/update-docs.js b/tools/update-docs.js
new file mode 100644
index 00000000..c0c3de43
--- /dev/null
+++ b/tools/update-docs.js
@@ -0,0 +1,69 @@
+/**
+ * @author Toru Nagashima
+ * @copyright 2017 Toru Nagashima. All rights reserved.
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+/*
+This script updates the header of `docs/rules/*.md` from rule's meta data.
+For example:
+
+```md
+# rule description (vue/rule-name)
+
+- :gear: This rule is included in `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
+- :warning: This rule was **deprecated**.
+- :wrench: The `--fix` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.
+```
+*/
+
+const fs = require('fs')
+const path = require('path')
+const last = require('lodash/last')
+const rules = require('./lib/rules')
+const categories = require('./lib/categories')
+
+function formatItems (items) {
+  if (items.length <= 2) {
+    return items.join(' and ')
+  }
+  return `all of ${items.slice(0, -1).join(', ')} and ${last(items)}`
+}
+
+const ROOT = path.resolve(__dirname, '../docs/rules')
+for (const rule of rules) {
+  const filePath = path.join(ROOT, `${rule.name}.md`)
+  const categoryIndex = categories.findIndex(category => category.categoryId === rule.meta.docs.category)
+  const title = `# ${rule.meta.docs.description} (${rule.ruleId})`
+  const notes = []
+
+  if (categoryIndex >= 0) {
+    const presets = categories.slice(categoryIndex).map(category => `\`"plugin:vue/${category.categoryId}"\``)
+    notes.push(`- :gear: This rule is included in ${formatItems(presets)}.`)
+  }
+  if (rule.meta.deprecated) {
+    if (rule.meta.docs.replacedBy) {
+      const replacedRules = rule.meta.docs.replacedBy.map(name => `[vue/${name}](${name}.md) rule`)
+      notes.push(`- :warning: This rule was **deprecated** and replaced by ${formatItems(replacedRules)}.`)
+    } else {
+      notes.push(`- :warning: This rule was **deprecated**.`)
+    }
+  }
+  if (rule.meta.fixable) {
+    notes.push(`- :wrench: The \`--fix\` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.`)
+  }
+
+  // Add an empty line after notes.
+  if (notes.length >= 1) {
+    notes.push('', '')
+  }
+
+  fs.writeFileSync(
+    filePath,
+    fs.readFileSync(filePath, 'utf8').replace(
+      /^#[^\n]*\n+(?:- .+\n)*\n*/,
+      `${title}\n\n${notes.join('\n')}`
+    )
+  )
+}
diff --git a/tools/update-lib-configs.js b/tools/update-lib-configs.js
new file mode 100644
index 00000000..2eb90c51
--- /dev/null
+++ b/tools/update-lib-configs.js
@@ -0,0 +1,78 @@
+/**
+ * @author Toru Nagashima
+ * @copyright 2017 Toru Nagashima. All rights reserved.
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+/*
+This script updates `lib/configs/*.js` files from rule's meta data.
+*/
+
+const fs = require('fs')
+const path = require('path')
+const eslint = require('eslint')
+const categories = require('./lib/categories')
+
+function formatRules (rules) {
+  const obj = rules.reduce((setting, rule) => {
+    setting[rule.ruleId] = 'error'
+    return setting
+  }, {})
+  return JSON.stringify(obj, null, 2)
+}
+
+function formatCategory (category, prevCategory) {
+  if (prevCategory == null) {
+    return `/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
+module.exports = {
+  root: true,
+  parser: require.resolve('vue-eslint-parser'),
+  parserOptions: {
+    ecmaVersion: 2015,
+    sourceType: 'module',
+    ecmaFeatures: {
+      jsx: true,
+      experimentalObjectRestSpread: true
+    }
+  },
+  env: {
+    browser: true,
+    es6: true
+  },
+  plugins: [
+    'vue'
+  ],
+  rules: ${formatRules(category.rules)}
+}
+`
+  }
+  return `/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
+module.exports = {
+  extends: require.resolve('./${prevCategory.categoryId}'),
+  rules: ${formatRules(category.rules)}
+}
+`
+}
+
+// Update files.
+const ROOT = path.resolve(__dirname, '../lib/configs/')
+categories.forEach((category, index) => {
+  const filePath = path.join(ROOT, `${category.categoryId}.js`)
+  const content = formatCategory(category, categories[index - 1])
+
+  fs.writeFileSync(filePath, content)
+})
+
+// Format files.
+const linter = new eslint.CLIEngine({ fix: true })
+const report = linter.executeOnFiles([ROOT])
+eslint.CLIEngine.outputFixes(report)
diff --git a/tools/update-lib-index.js b/tools/update-lib-index.js
new file mode 100644
index 00000000..faeb32f3
--- /dev/null
+++ b/tools/update-lib-index.js
@@ -0,0 +1,44 @@
+/**
+ * @author Toru Nagashima
+ * @copyright 2017 Toru Nagashima. All rights reserved.
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+/*
+This script updates `lib/index.js` file from rule's meta data.
+*/
+
+const fs = require('fs')
+const path = require('path')
+const eslint = require('eslint')
+const rules = require('./lib/rules')
+const categories = require('./lib/categories')
+
+// Update files.
+const filePath = path.resolve(__dirname, '../lib/index.js')
+const content = `/*
+ * IMPORTANT!
+ * This file has been automatically generated,
+ * in order to update it's content execute "npm run update"
+ */
+'use strict'
+
+module.exports = {
+  rules: {
+    ${rules.map(rule => `'${rule.name}': require('./rules/${rule.name}')`).join(',\n')}
+  },
+  configs: {
+    ${categories.map(category => `'${category.categoryId}': require('./configs/${category.categoryId}')`).join(',\n')}
+  },
+  processors: {
+    '.vue': require('./processor')
+  }
+}
+`
+fs.writeFileSync(filePath, content)
+
+// Format files.
+const linter = new eslint.CLIEngine({ fix: true })
+const report = linter.executeOnFiles([filePath])
+eslint.CLIEngine.outputFixes(report)
diff --git a/tools/update-readme.js b/tools/update-readme.js
new file mode 100644
index 00000000..c8cf4997
--- /dev/null
+++ b/tools/update-readme.js
@@ -0,0 +1,89 @@
+/**
+ * @author Toru Nagashima
+ * @copyright 2017 Toru Nagashima. All rights reserved.
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+/*
+This script updates the rule tables of `README.md` file from rule's meta data.
+*/
+
+const fs = require('fs')
+const path = require('path')
+const rules = require('./lib/rules')
+const categories = require('./lib/categories')
+
+// -----------------------------------------------------------------------------
+const uncategorizedRules = rules.filter(rule => !rule.meta.docs.category && !rule.meta.deprecated)
+const deprecatedRules = rules.filter(rule => rule.meta.deprecated)
+
+function toRuleRow (rule) {
+  const mark = `${rule.meta.fixable ? ':wrench:' : ''}${rule.meta.deprecated ? ':warning:' : ''}`
+  const link = `[${rule.ruleId}](./docs/rules/${rule.name}.md)`
+  const description = rule.meta.docs.description || '(no description)'
+
+  return `| ${mark} | ${link} | ${description} |`
+}
+
+function toDeprecatedRuleRow (rule) {
+  const link = `[${rule.ruleId}](./docs/rules/${rule.name}.md)`
+  const replacedRules = rule.meta.docs.replacedBy || []
+  const replacedBy = replacedRules
+    .map(name => `[vue/${name}](./docs/rules/${name}.md)`)
+    .join(', ')
+
+  return `| ${link} | ${replacedBy || '(no replacement)'} |`
+}
+
+// -----------------------------------------------------------------------------
+let rulesTableContent = categories.map(category => `
+### ${category.title}
+
+Enforce all the rules in this category, as well as all higher priority rules, with:
+
+\`\`\`json
+{
+  "extends": "plugin:vue/${category.categoryId}"
+}
+\`\`\`
+
+|    | Rule ID | Description |
+|:---|:--------|:------------|
+${category.rules.map(toRuleRow).join('\n')}
+`).join('')
+
+// -----------------------------------------------------------------------------
+if (uncategorizedRules.length >= 1) {
+  rulesTableContent += `
+### Uncategorized
+
+|    | Rule ID | Description |
+|:---|:--------|:------------|
+${uncategorizedRules.map(toRuleRow).join('\n')}
+`
+}
+
+// -----------------------------------------------------------------------------
+if (deprecatedRules.length >= 1) {
+  rulesTableContent += `
+### Deprecated
+
+> - :warning: We're going to remove deprecated rules in the next major release. Please migrate to successor/new rules.
+> - :innocent: We don't fix bugs which are in deprecated rules since we don't have enough resources.
+
+| Rule ID | Replaced by |
+|:--------|:------------|
+${deprecatedRules.map(toDeprecatedRuleRow).join('\n')}
+`
+}
+
+// -----------------------------------------------------------------------------
+const readmeFilePath = path.resolve(__dirname, '../README.md')
+fs.writeFileSync(
+  readmeFilePath,
+  fs.readFileSync(readmeFilePath, 'utf8').replace(
+    /<!--RULES_TABLE_START-->[\s\S]*<!--RULES_TABLE_END-->/,
+    `<!--RULES_TABLE_START-->\n${rulesTableContent}\n<!--RULES_TABLE_END-->`
+  )
+)
diff --git a/tools/update-rules.js b/tools/update-rules.js
deleted file mode 100644
index e2da0121..00000000
--- a/tools/update-rules.js
+++ /dev/null
@@ -1,204 +0,0 @@
-/**
- * @author Toru Nagashima
- * @copyright 2017 Toru Nagashima. All rights reserved.
- * See LICENSE file in root directory for full license.
- */
-'use strict'
-
-// ------------------------------------------------------------------------------
-// Requirements
-// ------------------------------------------------------------------------------
-
-const fs = require('fs')
-const path = require('path')
-
-// ------------------------------------------------------------------------------
-// Main
-// ------------------------------------------------------------------------------
-
-const root = path.resolve(__dirname, '../lib/rules')
-const readmeFile = path.resolve(__dirname, '../README.md')
-const tablePlaceholder = /<!--RULES_TABLE_START-->[\s\S]*<!--RULES_TABLE_END-->/
-const readmeContent = fs.readFileSync(readmeFile, 'utf8')
-
-const PEN = ':wrench:'
-const WARN = ':warning:'
-
-const rules = fs.readdirSync(root)
-  .filter(file => path.extname(file) === '.js')
-  .map(file => path.basename(file, '.js'))
-  .map(fileName => [
-    fileName,
-    require(path.join(root, fileName))
-  ])
-
-// In order of priority
-const categories = [
-  'base',
-  'essential',
-  'strongly-recommended',
-  'recommended'
-// Only include categories with existing rules
-].filter(category =>
-  rules.some(entry =>
-    !entry[1].meta.deprecated &&
-    entry[1].meta.docs.category === category
-  )
-)
-
-// Throw if an invalid category has been used
-for (const entry of rules) {
-  const category = entry[1].meta.docs.category
-  if (!categories.includes(category)) {
-    categories.push('uncategorized')
-    if (category) {
-      throw new Error(`Rule category ${category} from ${entry[0]} is invalid`)
-    }
-  }
-}
-
-const categoryTitles = {
-  'base': 'Base Rules (Enabling Correct ESLint Parsing)',
-  'essential': 'Priority A: Essential (Error Prevention)',
-  'strongly-recommended': 'Priority B: Strongly Recommended (Improving Readability)',
-  'recommended': 'Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)',
-  'use-with-caution': 'Priority D: Use with Caution (Potentially Dangerous Patterns)',
-  'uncategorized': 'Uncategorized'
-}
-
-// Throw if no title is defined for a category
-for (const category of categories) {
-  if (!categoryTitles[category]) {
-    throw new Error(`Category "${category}" does not have a title defined.`)
-  }
-}
-
-const deprecatedRules = rules
-  .filter(entry => entry[1].meta.deprecated)
-
-let rulesTableContent = categories.map(category => `
-### ${categoryTitles[category]}
-${
-  category === 'uncategorized' ? '' : `
-Enforce all the rules in this category, as well as all higher priority rules, with:
-
-\`\`\` json
-"extends": "plugin:vue/${category}"
-\`\`\`
-`
-}
-|    | Rule ID | Description |
-|:---|:--------|:------------|
-${
-  rules
-    .filter(entry =>
-      (
-        category === 'uncategorized' &&
-        !entry[1].meta.docs.category
-      ) ||
-      (
-        entry[1].meta.docs.category === category &&
-        !entry[1].meta.deprecated
-      )
-    )
-    .map(entry => {
-      const name = entry[0]
-      const meta = entry[1].meta
-      const mark = `${meta.fixable ? PEN : ''}${meta.deprecated ? WARN : ''}`
-      const link = `[${name}](./docs/rules/${name}.md)`
-      const description = meta.docs.description || '(no description)'
-      return `| ${mark} | ${link} | ${description} |`
-    })
-    .join('\n')
-}
-`).join('\n')
-
-if (deprecatedRules.length) {
-  rulesTableContent += `
-  ### Deprecated
-
-  > - :warning: We're going to remove deprecated rules in the next major release. Please migrate to successor/new rules.
-  > - :innocent: We don't fix bugs which are in deprecated rules since we don't have enough resources.
-
-  | Rule ID | Replaced by |
-  |:--------|:------------|
-  ${
-  rules
-    .filter(entry => entry[1].meta.deprecated)
-    .map(entry => {
-      const name = entry[0]
-      const meta = entry[1].meta
-      const link = `[${name}](./docs/rules/${name}.md)`
-      const replacedBy = (meta.docs.replacedBy || []).map(id => `[${id}](./docs/rules/${id}.md)`).join(', ') || '(no replacement)'
-      return `| ${link} | ${replacedBy} |`
-    })
-    .join('\n')
-}
-  `
-}
-
-categories.forEach((category, categoryIndex) => {
-  if (category === 'uncategorized') return
-  createRulesFile(category, categories.slice(0, categoryIndex + 1))
-})
-
-function createRulesFile (rulesGroupName, categories) {
-  const enabledRules = rules.filter(entry =>
-    !entry[1].meta.deprecated &&
-    categories.includes(entry[1].meta.docs.category)
-  ).reduce((obj, entry) => {
-    obj[`vue/${entry[0]}`] = 'error'
-    return obj
-  }, {})
-
-  const enabledRulesContent = `/*
-* IMPORTANT!
-* This file has been automatically generated,
-* in order to update it's content execute "npm run update"
-*/
-module.exports = ${JSON.stringify(enabledRules, null, 2)}`
-
-  fs.writeFileSync(
-    readmeFile,
-    readmeContent.replace(
-      tablePlaceholder,
-      `<!--RULES_TABLE_START-->\n${rulesTableContent}\n<!--RULES_TABLE_END-->`
-    )
-  )
-
-  const enabledRulesFile = path.resolve(__dirname, `../lib/${rulesGroupName}-rules.js`)
-
-  fs.writeFileSync(
-    enabledRulesFile,
-    enabledRulesContent
-  )
-}
-
-/*
-  * The pattern to match document header.
-  * The header is one title line and zero or more unordered list items.
-  * E.g.
-  *
-  * # description
-  * - a note. (there are 3 kinds of notes: recommended, deprecated, and autofixable)
-  * - another note.
-  *
-  */
-const headerPattern = /^#[^\n]*\n+(?:- .+\n)*\n*/
-
-// Update the header of rule documents.
-const docsRoot = path.resolve(__dirname, '../docs/rules')
-for (const entry of rules) {
-  const ruleId = entry[0]
-  const meta = entry[1].meta
-  const filePath = path.join(docsRoot, `${ruleId}.md`)
-  const autofix = meta.fixable ? `- ${PEN} The \`--fix\` option on the [command line](http://eslint.org/docs/user-guide/command-line-interface#fix) can automatically fix some of the problems reported by this rule.\n` : ''
-  let deprecated = meta.deprecated ? `- ${WARN} This rule was **deprecated**` : ''
-  deprecated += meta.deprecated && meta.docs.replacedBy ? ` and replaced by ${meta.docs.replacedBy.map(id => `[${id}](${id}.md) rule`).join(', ')}.` : ''
-  const header = `# ${meta.docs.description} (${ruleId})\n\n${deprecated ? deprecated + '\n' : ''}${autofix ? autofix + '\n' : ''}`
-
-  fs.writeFileSync(
-    filePath,
-    fs.readFileSync(filePath, 'utf8').replace(headerPattern, header)
-  )
-}
diff --git a/tools/update.js b/tools/update.js
new file mode 100644
index 00000000..fd968f37
--- /dev/null
+++ b/tools/update.js
@@ -0,0 +1,11 @@
+/**
+ * @author Toru Nagashima
+ * @copyright 2017 Toru Nagashima. All rights reserved.
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+require('./update-lib-configs')
+require('./update-lib-index')
+require('./update-docs')
+require('./update-readme')


Test patch:
diff --git a/tests/lib/rules/comment-directive.js b/tests/lib/rules/comment-directive.js
index 32de76a6..367d29dd 100644
--- a/tests/lib/rules/comment-directive.js
+++ b/tests/lib/rules/comment-directive.js
@@ -191,5 +191,22 @@ describe('comment-directive', () => {
       assert.deepEqual(messages[0].ruleId, 'vue/no-parsing-error')
       assert.deepEqual(messages[1].ruleId, 'vue/no-duplicate-attributes')
     })
+
+    it('should affect only the next line', () => {
+      const code = `
+        <template>
+          <!-- eslint-disable-next-line vue/no-parsing-error, vue/no-duplicate-attributes -->
+          <div id id="a">Hello</div>
+          <div id id="b">Hello</div>
+        </template>
+      `
+      const messages = linter.executeOnText(code, 'test.vue').results[0].messages
+
+      assert.deepEqual(messages.length, 2)
+      assert.deepEqual(messages[0].ruleId, 'vue/no-parsing-error')
+      assert.deepEqual(messages[0].line, 5)
+      assert.deepEqual(messages[1].ruleId, 'vue/no-duplicate-attributes')
+      assert.deepEqual(messages[1].line, 5)
+    })
   })
 })