From b635488a6cb36462d2b24d44c05e406893fe1884 Mon Sep 17 00:00:00 2001
From: oxc-bot <176400334+oxc-bot@users.noreply.github.com>
Date: Sun, 3 Nov 2024 03:26:14 +0000
Subject: [PATCH] Release 0.11.0
---
.../guide/usage/linter/generated-rules.md | 16 +-
.../rules/eslint/prefer-object-has-own.md | 54 +++++
.../usage/linter/rules/import/no-commonjs.md | 86 ++++++++
.../usage/linter/rules/oxc/no-map-spread.md | 203 ++++++++++++++++++
.../linter/rules/react/style-prop-object.md | 50 +++++
.../linter/rules/unicorn/no-useless-spread.md | 2 +-
6 files changed, 404 insertions(+), 7 deletions(-)
create mode 100644 src/docs/guide/usage/linter/rules/eslint/prefer-object-has-own.md
create mode 100644 src/docs/guide/usage/linter/rules/import/no-commonjs.md
create mode 100644 src/docs/guide/usage/linter/rules/oxc/no-map-spread.md
create mode 100644 src/docs/guide/usage/linter/rules/react/style-prop-object.md
diff --git a/src/docs/guide/usage/linter/generated-rules.md b/src/docs/guide/usage/linter/generated-rules.md
index d63eb57a9ae..24a79e794ee 100644
--- a/src/docs/guide/usage/linter/generated-rules.md
+++ b/src/docs/guide/usage/linter/generated-rules.md
@@ -2,7 +2,7 @@
The progress of all rule implementations is tracked [here](https://github.com/oxc-project/oxc/issues/481).
-- Total number of rules: 441
+- Total number of rules: 445
- Rules turned on by default: 97
## Correctness (172):
@@ -177,7 +177,7 @@ Code that is outright wrong or useless.
| [no-unnecessary-await](/docs/guide/usage/linter/rules/unicorn/no-unnecessary-await.html) | unicorn | ✅ | 🛠️ |
| [no-useless-fallback-in-spread](/docs/guide/usage/linter/rules/unicorn/no-useless-fallback-in-spread.html) | unicorn | ✅ | 🛠️ |
| [no-useless-length-check](/docs/guide/usage/linter/rules/unicorn/no-useless-length-check.html) | unicorn | ✅ | 🚧 |
-| [no-useless-spread](/docs/guide/usage/linter/rules/unicorn/no-useless-spread.html) | unicorn | ✅ | 🛠️ |
+| [no-useless-spread](/docs/guide/usage/linter/rules/unicorn/no-useless-spread.html) | unicorn | ✅ | ⚠️🛠️️ |
| [prefer-set-size](/docs/guide/usage/linter/rules/unicorn/prefer-set-size.html) | unicorn | ✅ | 🛠️ |
| [prefer-string-starts-ends-with](/docs/guide/usage/linter/rules/unicorn/prefer-string-starts-ends-with.html) | unicorn | ✅ | 🛠️ |
| [no-conditional-tests](/docs/guide/usage/linter/rules/vitest/no-conditional-tests.html) | vitest | | |
@@ -195,7 +195,7 @@ Code that can be written to run faster.
| [jsx-no-new-function-as-prop](/docs/guide/usage/linter/rules/react_perf/jsx-no-new-function-as-prop.html) | react_perf | | |
| [jsx-no-new-object-as-prop](/docs/guide/usage/linter/rules/react_perf/jsx-no-new-object-as-prop.html) | react_perf | | |
-## Restriction (57):
+## Restriction (58):
Lints which prevent the use of language and library features. Must not be enabled as a whole, should be considered on a case-by-case basis before enabling.
| Rule name | Source | Default | Fixable? |
@@ -219,6 +219,7 @@ Lints which prevent the use of language and library features. Must not be enable
| [no-void](/docs/guide/usage/linter/rules/eslint/no-void.html) | eslint | | 🚧 |
| [unicode-bom](/docs/guide/usage/linter/rules/eslint/unicode-bom.html) | eslint | | 🛠️ |
| [no-amd](/docs/guide/usage/linter/rules/import/no-amd.html) | import | | |
+| [no-commonjs](/docs/guide/usage/linter/rules/import/no-commonjs.html) | import | | |
| [no-cycle](/docs/guide/usage/linter/rules/import/no-cycle.html) | import | | |
| [no-default-export](/docs/guide/usage/linter/rules/import/no-default-export.html) | import | | |
| [no-dynamic-require](/docs/guide/usage/linter/rules/import/no-dynamic-require.html) | import | | |
@@ -258,7 +259,7 @@ Lints which prevent the use of language and library features. Must not be enable
| [prefer-node-protocol](/docs/guide/usage/linter/rules/unicorn/prefer-node-protocol.html) | unicorn | | 🛠️ |
| [prefer-number-properties](/docs/guide/usage/linter/rules/unicorn/prefer-number-properties.html) | unicorn | | 🚧 |
-## Suspicious (21):
+## Suspicious (22):
code that is most likely wrong or useless.
| Rule name | Source | Default | Fixable? |
@@ -279,6 +280,7 @@ code that is most likely wrong or useless.
| [iframe-missing-sandbox](/docs/guide/usage/linter/rules/react/iframe-missing-sandbox.html) | react | | 🚧 |
| [jsx-no-comment-textnodes](/docs/guide/usage/linter/rules/react/jsx-no-comment-textnodes.html) | react | | |
| [react-in-jsx-scope](/docs/guide/usage/linter/rules/react/react-in-jsx-scope.html) | react | | |
+| [style-prop-object](/docs/guide/usage/linter/rules/react/style-prop-object.html) | react | | |
| [no-confusing-non-null-assertion](/docs/guide/usage/linter/rules/typescript/no-confusing-non-null-assertion.html) | typescript | | 🚧 |
| [no-extraneous-class](/docs/guide/usage/linter/rules/typescript/no-extraneous-class.html) | typescript | | |
| [no-unnecessary-type-constraint](/docs/guide/usage/linter/rules/typescript/no-unnecessary-type-constraint.html) | typescript | | |
@@ -363,7 +365,7 @@ Lints which are rather strict or have occasional false positives.
| [prefer-type-error](/docs/guide/usage/linter/rules/unicorn/prefer-type-error.html) | unicorn | | 🛠️ |
| [require-number-to-fixed-digits-argument](/docs/guide/usage/linter/rules/unicorn/require-number-to-fixed-digits-argument.html) | unicorn | | 🛠️ |
-## Style (103):
+## Style (104):
Code that should be written in a more idiomatic way.
| Rule name | Source | Default | Fixable? |
@@ -384,6 +386,7 @@ Code that should be written in a more idiomatic way.
| [no-ternary](/docs/guide/usage/linter/rules/eslint/no-ternary.html) | eslint | | |
| [prefer-exponentiation-operator](/docs/guide/usage/linter/rules/eslint/prefer-exponentiation-operator.html) | eslint | | |
| [prefer-numeric-literals](/docs/guide/usage/linter/rules/eslint/prefer-numeric-literals.html) | eslint | | 🛠️ |
+| [prefer-object-has-own](/docs/guide/usage/linter/rules/eslint/prefer-object-has-own.html) | eslint | | 🛠️ |
| [sort-imports](/docs/guide/usage/linter/rules/eslint/sort-imports.html) | eslint | | 🛠️ |
| [sort-keys](/docs/guide/usage/linter/rules/eslint/sort-keys.html) | eslint | | 🚧 |
| [consistent-test-it](/docs/guide/usage/linter/rules/jest/consistent-test-it.html) | jest | | 🛠️ |
@@ -472,7 +475,7 @@ Code that should be written in a more idiomatic way.
| [prefer-to-be-object](/docs/guide/usage/linter/rules/vitest/prefer-to-be-object.html) | vitest | | 🛠️ |
| [prefer-to-be-truthy](/docs/guide/usage/linter/rules/vitest/prefer-to-be-truthy.html) | vitest | | 🛠️ |
-## Nursery (10):
+## Nursery (11):
New lints that are still under development.
| Rule name | Source | Default | Fixable? |
@@ -482,6 +485,7 @@ New lints that are still under development.
| [no-undef](/docs/guide/usage/linter/rules/eslint/no-undef.html) | eslint | | |
| [no-unreachable](/docs/guide/usage/linter/rules/eslint/no-unreachable.html) | eslint | | |
| [export](/docs/guide/usage/linter/rules/import/export.html) | import | | |
+| [no-map-spread](/docs/guide/usage/linter/rules/oxc/no-map-spread.html) | oxc | | 🛠️💡 |
| [no-return-in-finally](/docs/guide/usage/linter/rules/promise/no-return-in-finally.html) | promise | | |
| [require-render-return](/docs/guide/usage/linter/rules/react/require-render-return.html) | react | | |
| [rules-of-hooks](/docs/guide/usage/linter/rules/react/rules-of-hooks.html) | react | | |
diff --git a/src/docs/guide/usage/linter/rules/eslint/prefer-object-has-own.md b/src/docs/guide/usage/linter/rules/eslint/prefer-object-has-own.md
new file mode 100644
index 00000000000..bb0ed049b50
--- /dev/null
+++ b/src/docs/guide/usage/linter/rules/eslint/prefer-object-has-own.md
@@ -0,0 +1,54 @@
+
+
+# eslint/prefer-object-has-own
+
+
+
+### What it does
+
+Disallow use of `Object.prototype.hasOwnProperty.call()` and prefer use of `Object.hasOwn()`
+
+### Why is this bad?
+
+It is very common to write code like:
+
+```javascript
+if (Object.prototype.hasOwnProperty.call(object, "foo")) {
+ console.log("has property foo");
+}
+```
+
+This is a common practice because methods on Object.prototype can sometimes be unavailable or redefined (see the no-prototype-builtins rule).
+Introduced in ES2022, Object.hasOwn() is a shorter alternative to Object.prototype.hasOwnProperty.call():
+
+```javascript
+if (Object.hasOwn(object, "foo")) {
+ console.log("has property foo");
+}
+```
+
+### Examples
+
+Examples of **incorrect** code for this rule:
+
+```js
+Object.prototype.hasOwnProperty.call(obj, "a");
+Object.hasOwnProperty.call(obj, "a");
+({}).hasOwnProperty.call(obj, "a");
+const hasProperty = Object.prototype.hasOwnProperty.call(object, property);
+```
+
+Examples of **correct** code for this rule:
+
+```js
+Object.hasOwn(obj, "a");
+const hasProperty = Object.hasOwn(object, property);
+```
+
+## References
+
+- [Rule Source](https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/rules/eslint/prefer_object_has_own.rs)
diff --git a/src/docs/guide/usage/linter/rules/import/no-commonjs.md b/src/docs/guide/usage/linter/rules/import/no-commonjs.md
new file mode 100644
index 00000000000..67d39cc25cc
--- /dev/null
+++ b/src/docs/guide/usage/linter/rules/import/no-commonjs.md
@@ -0,0 +1,86 @@
+
+
+# import/no-commonjs
+
+
+
+
+### What it does
+
+Forbids the use of CommonJS `require` calls. Also forbids `module.exports` and `exports.*`.
+
+### Why is this bad?
+
+ESM modules or Typescript uses `import` and `export` syntax instead of CommonJS syntax.
+This rule enforces the use of more modern module systems to improve maintainability and consistency across the codebase.
+
+### Examples
+
+Examples of **incorrect** code for this rule:
+
+```js
+var mod = require("fs");
+
+var exports = (module.exports = {});
+
+exports.sayHello = function () {
+ return "Hello";
+};
+
+module.exports = "Hola";
+```
+
+Examples of **correct** code for this rule:
+
+```js
+var a = b && require("c");
+
+if (typeof window !== "undefined") {
+ require("somelib");
+}
+
+var fs = null;
+try {
+ fs = require("fs");
+} catch (error) {}
+```
+
+### Allow require
+
+If `allowRequire` option is set to `true`, `require` calls are valid:
+
+```js
+var mod = require("./mod");
+```
+
+but `module.exports` is reported as usual.
+
+### Allow conditional require
+
+By default, conditional requires are allowed, If the `allowConditionalRequire` option is set to `false`, they will be reported.
+
+### Allow primitive modules
+
+If `allowPrimitiveModules` option is set to true, the following is valid:
+
+```js
+module.exports = "foo";
+module.exports = function rule(context) {
+ return {
+ /* ... */
+ };
+};
+```
+
+but this is still reported:
+
+```js
+module.exports = { x: "y" };
+exports.z = function bark() {
+ /* ... */
+};
+```
+
+## References
+
+- [Rule Source](https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/rules/import/no_commonjs.rs)
diff --git a/src/docs/guide/usage/linter/rules/oxc/no-map-spread.md b/src/docs/guide/usage/linter/rules/oxc/no-map-spread.md
new file mode 100644
index 00000000000..da55f3fbcbf
--- /dev/null
+++ b/src/docs/guide/usage/linter/rules/oxc/no-map-spread.md
@@ -0,0 +1,203 @@
+
+
+# oxc/no-map-spread
+
+
+
+### What it does
+
+Disallow the use of object or array spreads in
+[`Array.prototype.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
+and
+[`Array.prototype.flatMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)
+to add properties/elements to array items.
+
+This rule only seeks to report cases where the spread operator is used
+to merge objects or arrays, not where it is used to copy them.
+
+### Why is this bad?
+
+Spreading is commonly used to add properties to objects in an array or
+to combine several objects together. Unfortunately, spreads incur a
+re-allocation for a new object, plus `O(n)` memory copies.
+
+```ts
+// each object in scores gets shallow-copied. Since `scores` is never
+// reused, spreading is inefficient.
+function getDisplayData() {
+ const scores: Array<{ username: string; score: number }> = getScores();
+ const displayData = scores.map((score) => ({ ...score, rank: getRank(score) }));
+ return displayData;
+}
+```
+
+Unless you expect objects in the mapped array to be mutated later, it is
+better to use [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign).
+
+```ts
+// `score` is mutated in place and is more performant.
+function getDisplayData() {
+ const scores: Array<{ username: string; score: number }> = getScores();
+ const displayData = scores.map((score) => Object.assign(score, { rank: getRank(score) }));
+ return displayData;
+}
+```
+
+### Protecting from Mutations
+
+There are valid use cases for spreading objects in `map` calls,
+specifically when you want consumers of returned arrays to be able to
+mutate them without affecting the original data. This rule makes a
+best-effort attempt to avoid reporting on these cases.
+
+Spreads on class instance properties are completely ignored:
+
+```ts
+class AuthorsDb {
+ #authors = [];
+ public getAuthorsWithBooks() {
+ return this.#authors.map((author) => ({
+ // protects against mutations, giving the callee their own
+ // deep(ish) copy of the author object.
+ ...author,
+ books: getBooks(author),
+ }));
+ }
+}
+```
+
+Spreads on arrays that are re-read after the `map` call are also ignored
+by default. Configure this behavior with the `ignoreRereads` option.
+
+```
+/* "oxc/no-map-spread": ["error", { "ignoreRereads": true }] */
+const scores = getScores();
+const displayData = scores.map(score => ({ ...score, rank: getRank(score) }));
+console.log(scores); // scores is re-read after the map call
+```
+
+#### Arrays
+
+In the case of array spreads,
+[`Array.prototype.concat`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat)
+or
+[`Array.prototype.push`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push)
+should be used wherever possible. These have slignly different semantics
+than array spreads, since spreading works on iterables while `concat`
+and `push` work only on arrays.
+
+```ts
+let arr = [1, 2, 3];
+let set = new Set([4]);
+
+let a = [...arr, ...set]; // [1, 2, 3, 4]
+let b = arr.concat(set); // [1, 2, 3, Set(1)]
+
+// Alternative that is more performant than spreading but still has the
+// same semantics. Unfortunately, it is more verbose.
+let c = arr.concat(Array.from(set)); // [1, 2, 3, 4]
+
+// You could also use `Symbol.isConcatSpreadable`
+set[Symbol.isConcatSpreadable] = true;
+let d = arr.concat(set); // [1, 2, 3, 4]
+```
+
+### Automatic Fixing
+
+This rule can automatically fix violations caused by object spreads, but
+does not fix arrays. Object spreads will get replaced with
+[`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign). Array fixing may be added in the future.
+
+Object expressions with a single element (the spread) are not fixed.
+
+```js
+arr.map((x) => ({ ...x })); // not fixed
+```
+
+A `fix` is available (using `--fix`) for objects with "normal" elements before the
+spread. Since `Object.apply` mutates the first argument, and a new
+object will be created with those elements, the spread identifier will
+not be mutated. In effect, the spread semantics are preserved
+
+```js
+// before
+arr.map(({ x, y }) => ({ x, ...y }));
+
+// after
+arr.map(({ x, y }) => Object.assign({ x }, y));
+```
+
+A suggestion (using `--fix-suggestions`) is provided when a spread is
+the first property in an object. This fix mutates the spread identifier,
+meaning it could have unintended side effects.
+
+```js
+// before
+arr.map(({ x, y }) => ({ ...x, y }));
+arr.map(({ x, y }) => ({ ...x, y }));
+
+// after
+arr.map(({ x, y }) => Object.assign(x, { y }));
+arr.map(({ x, y }) => Object.assign(x, y));
+```
+
+### Examples
+
+Examples of **incorrect** code for this rule:
+
+```js
+const arr = [{ a: 1 }, { a: 2 }, { a: 3 }];
+const arr2 = arr.map((obj) => ({ ...obj, b: obj.a * 2 }));
+```
+
+Examples of **correct** code for this rule:
+
+```ts
+const arr = [{ a: 1 }, { a: 2 }, { a: 3 }];
+arr.map((obj) => Object.assign(obj, { b: obj.a * 2 }));
+
+// instance properties are ignored
+class UsersDb {
+ #users = [];
+ public get users() {
+ // clone users, providing caller with their own deep(ish) copy.
+ return this.#users.map((user) => ({ ...user }));
+ }
+}
+```
+
+```tsx
+function UsersTable({ users }) {
+ const usersWithRoles = users.map((user) => ({ ...user, role: getRole(user) }));
+
+ return (
+
+ {usersWithRoles.map((user) => (
+
+ | {user.name} |
+ {user.role} |
+
+ ))}
+
+
+ {/* re-read of users */}
+ | Total users: {users.length} |
+
+
+
+ );
+}
+```
+
+### References
+
+- [ECMA262 - Object spread evaluation semantics](https://262.ecma-international.org/15.0/index.html#sec-runtime-semantics-propertydefinitionevaluation)
+- [JSPerf - `concat` vs array spread performance](https://jsperf.app/pihevu)
+
+## References
+
+- [Rule Source](https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/rules/oxc/no_map_spread.rs)
diff --git a/src/docs/guide/usage/linter/rules/react/style-prop-object.md b/src/docs/guide/usage/linter/rules/react/style-prop-object.md
new file mode 100644
index 00000000000..d7f2f83d2bb
--- /dev/null
+++ b/src/docs/guide/usage/linter/rules/react/style-prop-object.md
@@ -0,0 +1,50 @@
+
+
+# react/style-prop-object
+
+
+
+
+### What it does
+
+Require that the value of the prop `style` be an object or a variable that is an object.
+
+### Why is this bad?
+
+The `style` prop expects an object mapping from style properties to values when using JSX.
+
+### Examples
+
+Examples of **incorrect** code for this rule:
+
+```jsx
+
+
+
+const styles = true;
+
+
+React.createElement("div", { style: "color: 'red'" });
+React.createElement("div", { style: true });
+React.createElement("Hello", { style: true });
+const styles = true;
+React.createElement("div", { style: styles });
+```
+
+Examples of **correct** code for this rule:
+
+```jsx
+
+
+const styles = { color: "red" };
+
+
+React.createElement("div", { style: { color: 'red' }});
+React.createElement("Hello", { style: { color: 'red' }});
+const styles = { height: '100px' };
+React.createElement("div", { style: styles });
+```
+
+## References
+
+- [Rule Source](https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/rules/react/style_prop_object.rs)
diff --git a/src/docs/guide/usage/linter/rules/unicorn/no-useless-spread.md b/src/docs/guide/usage/linter/rules/unicorn/no-useless-spread.md
index 08286837d64..a16e0423c52 100644
--- a/src/docs/guide/usage/linter/rules/unicorn/no-useless-spread.md
+++ b/src/docs/guide/usage/linter/rules/unicorn/no-useless-spread.md
@@ -7,7 +7,7 @@
✅ This rule is turned on by default.
-🛠️ An auto-fix is available for this rule for some violations.
+⚠️🛠️️ A dangerous auto-fix is available for this rule.