optimistic-gold
optimistic-gold2mo ago

ESLint issues with auto-generated code

The inferencers seem to generate code that conflict with popular ESLint configs which made us wonder whether we can have some more control over the code that gets generated. Currently there is code generated such as:
<Typography variant="body1">
<strong>{translate("home.fields.paymentTerms")}: </strong>{store?.paymentTerms ?? ""}</Typography>
<Typography variant="body1">
<strong>{translate("home.fields.paymentTerms")}: </strong>{store?.paymentTerms ?? ""}</Typography>
ESLint generally sees this as a problem as we are only allowed to have one expression per line following the jsx-one-expression-per-line rule. We can further customise to make ESLint work with how refine generates code, but it would be nice to also make refine work with our own preferences. The main problem in the generated code is that within the Typography element there are two expressions: 1. <strong>{translate("home.fields.paymentTerms")}: </strong> 2. {store?.paymentTerms ?? ""} Which honestly could be put into a wrapper and this rule could be used without weird overrides. How can we make Refine generate code like this. And what ESLint config and rules are common to use that do not conflict with the code that the inferencers generate? Reference to the eslint docs used: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-one-expression-per-line.md
GitHub
eslint-plugin-react/docs/rules/jsx-one-expression-per-line.md at ma...
React-specific linting rules for ESLint. Contribute to jsx-eslint/eslint-plugin-react development by creating an account on GitHub.
8 Replies
kapa.ai
kapa.ai2mo ago
Hi @haib. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided in the knowledge sources, there are no direct references to customizing the code generation of inferencers in Refine to comply with specific ESLint rules such as jsx-one-expression-per-line. However, there are some insights and related discussions that might help you address this issue. Customizing Generated Code One of the comments from the refine Devtools RFC suggests that users would like more control over the generated code by inferencers, including the ability to make fine tweaks to core properties of hooks and components. This indicates that the need for customization is recognized, but there is no direct solution provided in the knowledge sources. Current State of Inferencer From the closed GitHub issue #4575 (https://github.com/refinedev/refine/issues/4575), we can see an example of the code generated by the inferencer:
import {
useShow,
IResourceComponentsProps,
useTranslate,
} from "@refinedev/core";
import {
Show,
TextFieldComponent as TextField,
MarkdownField,
DateField,
} from "@refinedev/mui";
import { Typography, Stack } from "@mui/material";

export const BlogPostShow: React.FC<IResourceComponentsProps> = () => {
const translate = useTranslate();
const { queryResult } = useShow();
const { data, isLoading } = queryResult;
const record = data?.data;

return (
<Show isLoading={isLoading}>
<Stack>
<Typography variant="body1">
<strong>{translate("home.fields.paymentTerms")}: </strong>
{store?.paymentTerms ?? ""}
</Typography>
</Stack>
</Show>
);
};
import {
useShow,
IResourceComponentsProps,
useTranslate,
} from "@refinedev/core";
import {
Show,
TextFieldComponent as TextField,
MarkdownField,
DateField,
} from "@refinedev/mui";
import { Typography, Stack } from "@mui/material";

export const BlogPostShow: React.FC<IResourceComponentsProps> = () => {
const translate = useTranslate();
const { queryResult } = useShow();
const { data, isLoading } = queryResult;
const record = data?.data;

return (
<Show isLoading={isLoading}>
<Stack>
<Typography variant="body1">
<strong>{translate("home.fields.paymentTerms")}: </strong>
{store?.paymentTerms ?? ""}
</Typography>
</Stack>
</Show>
);
};
ESLint Configuration To address the ESLint issue, you can either: 1. Adjust the ESLint Configuration: Modify your ESLint configuration to allow multiple expressions per line within JSX. 2. Post-process the Generated Code: Create a script to post-process the generated code to wrap expressions as needed. Example ESLint Configuration Adjustment You can disable the jsx-one-expression-per-line rule in your ESLint configuration:
{
"rules": {
"react/jsx-one-expression-per-line": "off"
}
}
{
"rules": {
"react/jsx-one-expression-per-line": "off"
}
}
Example Post-processing Script If you prefer to keep the ESLint rule and adjust the generated code, you can create a script to wrap the expressions:
const fs = require('fs');
const path = require('path');

const filePath = path.join(__dirname, 'path-to-generated-file.tsx');
let fileContent = fs.readFileSync(filePath, 'utf8');

fileContent = fileContent.replace(
/<Typography variant="body1">\s*<strong>{translate\("home\.fields\.paymentTerms"\)}: <\/strong>\s*{store\?\.paymentTerms \?\? ""}\s*<\/Typography>/g,
`<Typography variant="body1">
<span>
<strong>{translate("home.fields.paymentTerms")}: </strong>
{store?.paymentTerms ?? ""}
</span>
</Typography>`
);

fs.writeFileSync(filePath, fileContent, 'utf8');
const fs = require('fs');
const path = require('path');

const filePath = path.join(__dirname, 'path-to-generated-file.tsx');
let fileContent = fs.readFileSync(filePath, 'utf8');

fileContent = fileContent.replace(
/<Typography variant="body1">\s*<strong>{translate\("home\.fields\.paymentTerms"\)}: <\/strong>\s*{store\?\.paymentTerms \?\? ""}\s*<\/Typography>/g,
`<Typography variant="body1">
<span>
<strong>{translate("home.fields.paymentTerms")}: </strong>
{store?.paymentTerms ?? ""}
</span>
</Typography>`
);

fs.writeFileSync(filePath, fileContent, 'utf8');
Conclusion While there is no direct method to customize the inferencer's code generation in Refine as per the knowledge sources, you can either adjust your ESLint configuration or create a post-processing script to format the generated code according to your preferences. For more detailed information, you might want to refer to the Refine documentation (https://refine.dev/docs) or participate in discussions on their [GitHub repository](https://github.com/refinedev/refine ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@525050092005359626> kapa.ai is still learning and improving, please let us know how it did by reacting below
optimistic-gold
optimistic-gold2mo ago
@kapa.ai What ruleset do you guys use then? Do you just not use ESLint? Do you allow multi-line expressions?
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Based on the information from the knowledge sources, it appears that the Refine team does use ESLint, but they have encountered and addressed various issues related to ESLint configurations in their examples and projects. ESLint Configuration in Refine Projects From the GitHub issue #2765 (https://github.com/refinedev/refine/issues/2765), we can see that the Refine team does use ESLint and has specific configurations to handle common issues. Here is an example of an ESLint configuration that they use:
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:prettier/recommended"
],
"plugins": ["react", "prettier"],
"rules": {
"prettier/prettier": "error", // Enforce Prettier formatting
"react/no-deprecated": "warn", // Warn about deprecated lifecycle methods
"react/no-direct-mutation-state": "error" // Prevent direct state mutation
},
"settings": {
"react": {
"version": "detect"
}
}
}
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:prettier/recommended"
],
"plugins": ["react", "prettier"],
"rules": {
"prettier/prettier": "error", // Enforce Prettier formatting
"react/no-deprecated": "warn", // Warn about deprecated lifecycle methods
"react/no-direct-mutation-state": "error" // Prevent direct state mutation
},
"settings": {
"react": {
"version": "detect"
}
}
}
Handling ESLint Warnings and Errors In some cases, the team has opted to disable specific ESLint rules temporarily to address issues. For example, in the same issue #2765 (https://github.com/refinedev/refine/issues/2765), they suggested adding the examples/ directory to the .eslintignore file to ignore ESLint checks in that folder:
examples/
examples/
Multi-line Expressions While there is no explicit mention of allowing or disallowing multi-line expressions, the team has discussed the importance of maintaining code standards and avoiding disabling ESLint entirely. This suggests that they strive to adhere to ESLint rules as much as possible while making necessary adjustments to ensure smooth development. Conclusion The Refine team does use ESLint and has a specific ruleset to enforce best practices and code standards. They handle ESLint warnings and errors by configuring ESLint appropriately and, in some cases, temporarily disabling specific rules. Here is a summary of their approach: - ESLint Configuration: Use a combination of recommended rules and plugins, including Prettier for code formatting. - Handling Issues: Temporarily disable specific rules or ignore certain directories to address issues. - Code Standards: Strive to maintain code standards and avoid disabling ESLint entirely. For more detailed information, you can refer to the Refine documentation (https://refine.dev/docs) or participate in discussions on their GitHub repository (https://github.com/refinedev/refine). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@525050092005359626> kapa.ai is still learning and improving, please let us know how it did by reacting below
optimistic-gold
optimistic-gold2mo ago
@kapa.ai Mark as resolved; Extending your eslint with "prettier/react" makes it auto-format in a different way which seems much more compatible with Refine's set-up. Avoids the initial problem and gives you more control over errors and auto-formatting options.
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Mark as Resolved Extending your ESLint configuration with "plugin:prettier/recommended" makes it auto-format in a different way, which seems much more compatible with Refine's setup. This approach avoids the initial problem and gives you more control over errors and auto-formatting options. Here is an example of an ESLint configuration that includes Prettier and is compatible with Refine:
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:prettier/recommended"
],
"plugins": ["react", "prettier"],
"rules": {
"prettier/prettier": "error", // Enforce Prettier formatting
"react/no-deprecated": "warn", // Warn about deprecated lifecycle methods
"react/no-direct-mutation-state": "error" // Prevent direct state mutation
},
"settings": {
"react": {
"version": "detect"
}
}
}
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:prettier/recommended"
],
"plugins": ["react", "prettier"],
"rules": {
"prettier/prettier": "error", // Enforce Prettier formatting
"react/no-deprecated": "warn", // Warn about deprecated lifecycle methods
"react/no-direct-mutation-state": "error" // Prevent direct state mutation
},
"settings": {
"react": {
"version": "detect"
}
}
}
By using this configuration, you can ensure that your code is formatted consistently and in a way that is compatible with Refine's setup, while also maintaining control over ESLint errors and auto-formatting options. For more detailed information, you can refer to the Refine documentation (https://refine.dev/docs) or participate in discussions on their GitHub repository (https://github.com/refinedev/refine). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@525050092005359626> kapa.ai is still learning and improving, please let us know how it did by reacting below