diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9f5c06affe..3359afacd0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,12 +7,14 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
### Fixed
* [`no-unknown-property`]: add `viewBox` on `marker` ([#3416][] @ljharb)
+* [`no-unknown-property`]: add `noModule` on `script` ([#3414][] @ljharb)
### Changed
* [Meta] npmignore markdownlint config ([#3413][] @jorrit)
[#3416]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3416
+[#3414]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3414
[#3413]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3413
## [7.31.7] - 2022.09.05
diff --git a/lib/rules/no-unknown-property.js b/lib/rules/no-unknown-property.js
index 695ae3b64a..2f1a4fc6fd 100644
--- a/lib/rules/no-unknown-property.js
+++ b/lib/rules/no-unknown-property.js
@@ -21,9 +21,10 @@ const DEFAULTS = {
const DOM_ATTRIBUTE_NAMES = {
'accept-charset': 'acceptCharset',
class: 'className',
- for: 'htmlFor',
'http-equiv': 'httpEquiv',
crossorigin: 'crossOrigin',
+ for: 'htmlFor',
+ nomodule: 'noModule',
};
const ATTRIBUTE_TAGS_MAP = {
@@ -64,6 +65,7 @@ const ATTRIBUTE_TAGS_MAP = {
viewBox: ['svg', 'marker'],
as: ['link'],
valign: ['tr', 'td', 'th', 'thead', 'tbody', 'tfoot', 'colgroup', 'col'], // deprecated, but known
+ noModule: ['script'],
// Media events allowed only on audio and video tags, see https://github.com/facebook/react/blob/256aefbea1449869620fb26f6ec695536ab453f5/CHANGELOG.md#notable-enhancements
onAbort: ['audio', 'video'],
onCanPlay: ['audio', 'video'],
diff --git a/tests/lib/rules/no-unknown-property.js b/tests/lib/rules/no-unknown-property.js
index 5e9ceba2fa..d58c6e21c1 100644
--- a/tests/lib/rules/no-unknown-property.js
+++ b/tests/lib/rules/no-unknown-property.js
@@ -110,7 +110,7 @@ ruleTester.run('no-unknown-property', rule, {
{ code: ';' },
{ code: ';' },
// Attributes on allowed elements should work
- { code: '' },
+ { code: '' },
{ code: '' },
{ code: '' },
{ code: '