eslint rule to define eslint custom rules for jimdo
npm install eslint-plugin-jimdo-custom-rulesCustom ESLint rules for Jimdo projects.
Install the ESLint plugin by running:
``shell`
npm install --save-dev eslint-plugin-jimdo-custom-rules
Some projects have files that aren't meant to be executed in the same environment. For instance, think about a web application with distinct code for the server and the client. In such cases, importing server-only files in client code can lead to issues.
This ESLint rule allows you to specify paths that should be restricted from imports in certain areas of your project. By defining these restricted zones, you can ensure that files intended for a specific environment (e.g., server or client) are not inadvertently imported into the wrong context.
#### Parameters for the rule
0 - error level, [error | warning]
1 - rules for a folder
#### Configuration
Add the plugin to your ESLint configuration file, for example, .eslintrc.js.@apps/wizard
e.g. disallow imports containing in folder workspace/apps/cms
`javascript`
module.exports = {
plugins: ['jimdo-custom-rules'],
rules: {
'jimdo-custom-rules/disallow-imports-in-folder': ['error', {
folderRules: [
// Define your restricted folders here
folder: 'workspace/apps/cms',
disallowedImports: [
'@apps/wizard',
...
],
],
}],
},
};
An enhanced version of React's exhaustive-deps rule that prevents infinite render loops by detecting and excluding functions that are redeclared on each render from dependency array warnings.
#### Why this rule?
The standard react-hooks/exhaustive-deps rule is helpful for ensuring all dependencies are included in React Hook dependency arrays. However, it can sometimes suggest including functions that get redeclared on each render (like inline functions or non-memoized function declarations inside components). Including such functions in dependency arrays causes infinite render loops.
This rule extends the behavior of exhaustive-deps to:
- Detect functions declared inline within components (arrow functions, function expressions)
- Detect function declarations within component bodies
- Exclude these "unsafe" functions from dependency warnings
- Still warn about other missing dependencies as usual
#### What it detects
The rule identifies these patterns as unsafe for dependency arrays:
1. Inline arrow functions and function expressions:
`tsx
function MyComponent() {
const handleClick = () => { // ❌ Unsafe - redeclared each render
console.log('clicked');
};
useEffect(() => {
handleClick();
}, [handleClick]); // This would cause infinite renders
}
`
2. Function declarations inside components:
`tsx
function MyComponent() {
function handleClick() { // ❌ Unsafe - redeclared each render
console.log('clicked');
}
useEffect(() => {
handleClick();
}, [handleClick]); // This would cause infinite renders
}
`
3. Functions wrapped in useCallback/useMemo are safe:
`tsx
function MyComponent() {
const handleClick = useCallback(() => { // ✅ Safe - memoized
console.log('clicked');
}, []);
useEffect(() => {
handleClick();
}, [handleClick]); // This is safe and won't be flagged
}
`
#### Usage
This rule is automatically enabled when you use @jimdo/eslint-config-jimdo. It replaces the standard react-hooks/exhaustive-deps rule with this safer version.
The rule works with all React Hooks that accept dependency arrays:
- useEffectuseLayoutEffect
- useCallback
- useMemo
- useImperativeHandle
-
#### Examples
Problem:
`tsx/api/data/${id}
function MyComponent({ id }) {
// This function is redeclared on every render
const fetchData = () => {
fetch().then(/.../);
};
useEffect(() => {
fetchData();
}, [fetchData]); // ❌ Would cause infinite renders!
}
`
Solution 1 - Use useCallback:
`tsx/api/data/${id}
function MyComponent({ id }) {
const fetchData = useCallback(() => {
fetch().then(/.../);
}, [id]); // ✅ Memoized with proper dependencies
useEffect(() => {
fetchData();
}, [fetchData]); // ✅ Safe to include
}
`
Solution 2 - Move function outside component:
`tsx/api/data/${id}
const fetchData = (id) => {
fetch().then(/.../);
};
function MyComponent({ id }) {
useEffect(() => {
fetchData(id);
}, [id]); // ✅ Safe - fetchData is stable
}
`
Solution 3 - Inline the function:
`tsx/api/data/${id}
function MyComponent({ id }) {
useEffect(() => {
fetch().then(/.../);`
}, [id]); // ✅ Safe - no function in deps
}
An enhanced accessibility rule that extends jsx-a11y's no-static-element-interactions and click-events-have-key-events rules to support polymorphic components using the component prop pattern.
#### Why this rule?
Jimdo design system often use polymorphic components where a single component (like Box) can render as different HTML elements via a component prop:
`tsx`
The standard jsx-a11y rules don't understand this pattern and would incorrectly flag these as accessibility violations. This rule properly resolves the component prop (including imported components) and only reports errors when non-interactive elements have interaction handlers without proper keyboard accessibility.
#### How it works
The rule:
1. Wraps the upstream jsx-a11y/no-static-element-interactions and jsx-a11y/click-events-have-key-events rulescomponent
2. Resolves the prop to determine the actual HTML element being renderedButton
3. Uses the jsx-a11y settings to map component names (like ) to their native element types
4. Only reports violations for definitively non-interactive elements with interaction handlers
#### Usage
This rule is automatically enabled when you use @jimdo/eslint-config-jimdo. The standard jsx-a11y rules are disabled in favor of this polymorphic-aware version.
#### Examples
Valid - Interactive elements with onClick:
`tsx
// Native interactive element
// Mapped to interactive element
// Non-interactive without handlers
`
Invalid - Non-interactive elements with onClick:
`tsx
// Native non-interactive element
// Error: Static elements should not have mouse or keyboard event handlers
// Error: Elements with onClick handlers must have a keyboard event handler
// Mapped to non-interactive element
// Error: Static elements should not have mouse or keyboard event handlers
// Error: Elements with onClick handlers must have a keyboard event handler
`
Fixes:
`tsx
// Option 1: Use an interactive component
// Option 2: Add keyboard handler and role
onClick={handleClick}
onKeyDown={handleKeyDown}
role="button"
tabIndex={0}
>
Click
// Option 3: Don't use interaction handlers on non-interactive elements
`
Prevents redundant aria-hidden attribute on Icon component since it's already included in the component implementation.
#### Why this rule?
The Jimdo design system's Icon component automatically applies aria-hidden={true} in its implementation. Adding it manually creates redundancy and may cause confusion.
#### What it checks
The rule flags any Icon component that has an explicit aria-hidden attribute:
`tsx`
// ❌ Invalid - aria-hidden is redundant
`tsx`
// ✅ Valid - no aria-hidden needed
#### Auto-fix
This rule includes an auto-fix that removes the redundant aria-hidden attribute:
`bash`
eslint --fix
#### Usage
This rule is automatically enabled when you use @jimdo/eslint-config-jimdo`.