Skip to content

Commit e825692

Browse files
committed
BREAKING CHANGE: refactor -> import rules show an error and made a custom rule for rn svg to show a warning
1 parent f77ad54 commit e825692

File tree

6 files changed

+109
-16
lines changed

6 files changed

+109
-16
lines changed

packages/eslint-plugin/README.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,18 @@ This plugin exports some custom rules that you can optionally use in your projec
103103
<!-- begin auto-generated rules list -->
104104

105105
💼 Configurations enabled in.\
106-
✅ Set in the `recommended` configuration.\
106+
⚠️ Configurations set to warn in.\
107107
🧪 Set in the `tests` configuration.\
108108
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).
109109

110-
| Name | Description | 💼 | 🔧 |
111-
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- | :--------------------- | :-- |
112-
| [avoid-intl-number-format](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/avoid-intl-number-format.md) | Disallow the use of `Intl.NumberFormat` due to potential performance issues. | ![badge-performance][] | 🔧 |
113-
| [await-user-event](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/await-user-event.md) | Enforces awaiting userEvent calls | 🧪 | 🔧 |
114-
| [no-different-displayname](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/no-different-displayname.md) | Enforce component displayName to match with component name || 🔧 |
115-
| [no-animated-without-native-driver](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/no-animated-without-native-driver.md) | Disallow the use of `Animated` with `useNativeDriver: false` | ![badge-performance][] | 🔧 |
116-
| [prefer-user-event](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/prefer-user-event.md) | Enforces usage of userEvent over fireEvent in tests. | | 🔧 |
117-
| [require-named-effect](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/require-named-effect.md) | Enforces the use of named functions inside a useEffect | | |
118-
| Name                              |
110+
| Name                              | Description | 💼 | ⚠️ | 🔧 |
111+
| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------- | :--------------------- | :--------------------- | :-- |
112+
| [avoid-intl-number-format](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/avoid-intl-number-format.md) | Disallow the use of `Intl.NumberFormat` due to potential performance issues. | ![badge-performance][] | | 🔧 |
113+
| [avoid-react-native-svg](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/avoid-react-native-svg.md) | Disallow importing the `react-native-svg` package. | | ![badge-performance][] | 🔧 |
114+
| [await-user-event](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/await-user-event.md) | Enforces awaiting userEvent calls | 🧪 | | 🔧 |
115+
| [no-animated-without-native-driver](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/no-animated-without-native-driver.md) | Disallow the use of `Animated` with `useNativeDriver: false` | ![badge-performance][] | | 🔧 |
116+
| [prefer-user-event](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/prefer-user-event.md) | Enforces usage of userEvent over fireEvent in tests. | | | 🔧 |
117+
| [require-named-effect](https://github.com/bamlab/react-native-project-config/blob/main/packages/eslint-plugin/docs/rules/require-named-effect.md) | Enforces the use of named functions inside a useEffect | | | |
119118

120119
<!-- end auto-generated rules list -->
121120

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Disallow importing the `react-native-svg` package (`@bam.tech/avoid-react-native-svg`)
2+
3+
⚠️ This rule _warns_ in the `performance` config.
4+
5+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
6+
7+
<!-- end auto-generated rule header -->
8+
9+
Prevents from using "react-native-svg" import to avoid performance issues.
10+
11+
## Rule details
12+
13+
Examples of **incorrect** code for this rule:
14+
15+
```jsx
16+
import Svg from "react-native-svg";
17+
```
18+
19+
```jsx
20+
const Svg = require("react-native-svg");
21+
```

packages/eslint-plugin/lib/configs/performance.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { defineConfig } from "eslint-define-config";
33
export const performanceConfig = defineConfig({
44
rules: {
55
"no-restricted-imports": [
6-
"warn",
6+
"error",
77
{
88
paths: [
99
{
@@ -23,16 +23,12 @@ export const performanceConfig = defineConfig({
2323
message:
2424
"Please use useFocusEffect instead of useIsFocused to avoid excessive rerenders.",
2525
},
26-
{
27-
name: "react-native-svg",
28-
message:
29-
"Usage of react-native-svg is discouraged. Consider alternatives if applicable.",
30-
},
3126
],
3227
},
3328
],
3429
"@bam.tech/no-animated-without-native-driver": "error",
3530
"@bam.tech/avoid-intl-number-format": "error",
31+
"@bam.tech/avoid-react-native-svg": "warn",
3632
},
3733
overrides: [
3834
{
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import type { Rule } from "eslint";
2+
3+
// Custom Rule: No react-native-svg Import
4+
export const avoidReactNativeSvgImportRule: Rule.RuleModule = {
5+
meta: {
6+
type: "problem",
7+
docs: {
8+
description: "Disallow importing the `react-native-svg` package.",
9+
category: "Possible Errors",
10+
recommended: true,
11+
url: "https://github.com/bamlab/react-native-project-config/tree/main/packages/eslint-plugin/docs/rules/no-react-native-svg-import.md",
12+
},
13+
messages: {
14+
noReactNativeSvgImport:
15+
"Do not import `react-native-svg`. Consider using an alternative method for SVG handling or ensure it's necessary for your use case.",
16+
},
17+
schema: [],
18+
fixable: "code",
19+
},
20+
21+
create(context) {
22+
return {
23+
ImportDeclaration(node) {
24+
if (node.source.value === "react-native-svg") {
25+
context.report({
26+
node,
27+
messageId: "noReactNativeSvgImport",
28+
});
29+
}
30+
},
31+
CallExpression(node) {
32+
if (
33+
node.callee.type === "Identifier" &&
34+
node.callee.name === "require" &&
35+
node.arguments.length > 0 &&
36+
node.arguments[0].type === "Literal" &&
37+
node.arguments[0].value === "react-native-svg"
38+
) {
39+
context.report({
40+
node,
41+
messageId: "noReactNativeSvgImport",
42+
});
43+
}
44+
},
45+
};
46+
},
47+
};

packages/eslint-plugin/lib/rules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { avoidIntlNumberFormatRule } from "./avoid-intl-number-format";
2+
import { avoidReactNativeSvgImportRule } from "./avoid-react-native-svg";
23
import { awaitUserEventRule } from "./await-user-event";
34
import { noDifferentDisplaynameRule } from "./no-different-displayname";
45
import { noAnimatedWithoutNativeDriverRule } from "./no-animated-without-native-driver";
@@ -12,4 +13,5 @@ export default {
1213
"no-different-displayname": noDifferentDisplaynameRule,
1314
"no-animated-without-native-driver": noAnimatedWithoutNativeDriverRule,
1415
"avoid-intl-number-format": avoidIntlNumberFormatRule,
16+
"avoid-react-native-svg": avoidReactNativeSvgImportRule,
1517
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Save without formatting: [⌘ + K] > [S]
2+
3+
// This should trigger an error breaking eslint-plugin-bam-custom-rules:
4+
// bam-custom-rules/avoid-react-native-svg
5+
6+
import { avoidReactNativeSvgImportRule } from "../../../lib/rules/avoid-react-native-svg";
7+
import { RuleTester } from "eslint";
8+
9+
const ruleTester = new RuleTester({
10+
parser: require.resolve("@typescript-eslint/parser"),
11+
});
12+
13+
const valid = [``];
14+
15+
const invalid = [
16+
`import Svg from 'react-native-svg';`,
17+
`const Svg = require('react-native-svg');`,
18+
];
19+
20+
ruleTester.run("avoid-react-native-svg", avoidReactNativeSvgImportRule, {
21+
valid,
22+
invalid: invalid.map((code) => ({
23+
code,
24+
errors: [
25+
"Do not import `react-native-svg`. Consider using an alternative method for SVG handling or ensure it's necessary for your use case.",
26+
],
27+
})),
28+
});

0 commit comments

Comments
 (0)