diff --git a/lib/index.js b/lib/index.js
index 6c737fa..d74edb4 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -13,6 +13,7 @@ module.exports = {
"no-duplicate-attributes": require("./rules/no-duplicate-attributes"),
"no-index-in-wx-key": require("./rules/no-index-in-wx-key"),
"no-dynamic-wx-key": require("./rules/no-dynamic-wx-key"),
+ "no-inconsistent-tagname": require("./rules/no-inconsistent-tagname"),
"no-inline-wxs": require("./rules/no-inline-wxs"),
"no-unexpected-string-bool": require("./rules/no-unexpected-string-bool"),
"no-unnecessary-block": require("./rules/no-unnecessary-block"),
diff --git a/lib/rules/no-inconsistent-tagname.js b/lib/rules/no-inconsistent-tagname.js
new file mode 100644
index 0000000..5423430
--- /dev/null
+++ b/lib/rules/no-inconsistent-tagname.js
@@ -0,0 +1,39 @@
+module.exports = {
+ /** @type {import('eslint').Rule.RuleMetaData} */
+ meta: {
+ type: "problem",
+ docs: {
+ description: "wxml tag's startTag name and endTag name must be equal",
+ categories: [],
+ url: "https://eslint-plugin-wxml.js.org/rules/no-inconsistent-tagname.html",
+ },
+ fixable: null,
+ messages: {
+ tagInconsistent:
+ "startTag's name '{{startTagName}}' and endTag's name '{{endTagName}}' not equal",
+ },
+ schema: [],
+ },
+
+ /** @param {import('eslint').Rule.RuleContext} context */
+ create(context) {
+ return {
+ WXElement(node) {
+ if (
+ node.startTag &&
+ node.endTag &&
+ node.startTag.name !== node.endTag.name
+ ) {
+ context.report({
+ node,
+ messageId: "tagInconsistent",
+ data: {
+ startTagName: node.startTag.name,
+ endTagName: node.endTag.name,
+ },
+ });
+ }
+ },
+ };
+ },
+};
diff --git a/tests/rules/no-inconsistent-tagname.js b/tests/rules/no-inconsistent-tagname.js
new file mode 100644
index 0000000..d3d7cdb
--- /dev/null
+++ b/tests/rules/no-inconsistent-tagname.js
@@ -0,0 +1,44 @@
+const RuleTester = require("eslint").RuleTester;
+const rule = require("../../lib/rules/no-inconsistent-tagname");
+
+const tester = new RuleTester({
+ parser: require.resolve("@wxml/parser"),
+});
+
+tester.run("no-inconsistent-tagname", rule, {
+ valid: [
+ {
+ filename: "test.wxml",
+ code: ``,
+ },
+ {
+ filename: "test.wxml",
+ code: ``,
+ },
+ {
+ filename: "test.wxml",
+ code: ``,
+ },
+ {
+ filename: "wxs.wxml",
+ code: ``,
+ },
+ ],
+ invalid: [
+ {
+ filename: "test.wxml",
+ code: ``,
+ errors: [`startTag's name 'view' and endTag's name 'viw' not equal`],
+ },
+ {
+ filename: "test.wxml",
+ code: `>`,
+ errors: [`startTag's name 'view' and endTag's name '' not equal`],
+ },
+ {
+ filename: "test.wxml",
+ code: ` >`,
+ errors: [`startTag's name 'view' and endTag's name '' not equal`],
+ },
+ ],
+});
diff --git a/website/docs/rules/README.md b/website/docs/rules/README.md
index 7e5532e..de01fa6 100644
--- a/website/docs/rules/README.md
+++ b/website/docs/rules/README.md
@@ -26,6 +26,7 @@ sidebarDepth: 0
| [wxml/no-dot-this-in-wx-key](./no-dot-this-in-wx-key.md) | disable using [`*this`](https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/list.html) as `wx:key`'s value | :star: | |
| [wxml/no-duplicate-attributes](./no-duplicate-attributes.md) | not allow exist duplicate attributes in a single tag | :star: :star: | |
| [wxml/no-dynamic-wx-key](./no-dynamic-wx-key.md) | enforce using static `wx:key` | :star: | |
+| [wxml/no-inconsistent-tagname](./no-inconsistent-tagname.md) | Found startTag name and endTag name not equal at development stage | :star: :star: :star: | |
| [wxml/no-index-in-wx-key](./no-index-in-wx-key.md) | disable using [`index`](https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/list.html) as `wx:key`'s value | :star: | |
| [wxml/no-inline-wxs](./no-inline-wxs.md) | force using separate `.wxs` file | :star: | |
| [wxml/no-unexpected-string-bool](./no-unexpected-string-bool.md) | not allow using `"true"` or `"false"` as attribute's boolean value, [official documentation](https://developers.weixin.qq.com/miniprogram/dev/reference/wxml/data.html) | :star: :star: :star: | |
diff --git a/website/docs/rules/no-inconsistent-tagname.md b/website/docs/rules/no-inconsistent-tagname.md
new file mode 100644
index 0000000..ef800a2
--- /dev/null
+++ b/website/docs/rules/no-inconsistent-tagname.md
@@ -0,0 +1,57 @@
+---
+sidebarDepth: 0
+title: wxml/no-inconsistent-tagname
+---
+
+# wxml/no-inconsistent-tagname
+
+## Motivation
+
+Found startTag name and endTag name not equal at development stage.
+
+
+
+```wxml
+
+
+ {{item.name}}
+
+
+ {{"tag name must be equal"}}
+
+
+
+
+ {{item.name}}
+
+```
+
+
+::: tip 💡 tips
+
+You can edit code via online editor, it's online REPL, try to fix eslint problem !
+
+:::
+
+## Config
+
+No special options, normal config is ok
+
+```json
+{ "wxml/no-inconsistent-tagname": "error" }
+```
+
+## Version
+
+This rule was introduced in eslint-plugin-wxml `v0.7.2`
+
+## Implementation
+
+- [Rule Source Code](https://github.com/wxmlfile/eslint-plugin-wxml/tree/main/lib/rules/no-inconsistent-tagname.js)
+- [Test Source Code](https://github.com/wxmlfile/eslint-plugin-wxml/tree/main/tests/rules/no-inconsistent-tagname.js)