@adonisjs/eslint-plugin
v2.2.0
Published
ESLint plugin to enforce AdonisJS app specific linting rules
Readme
@adonisjs/eslint-plugin
Compatible with ESLint>=9.0 and TypeScript >=5.4
Installation
The package comes pre-configured with the @adonisjs/eslint-config preset and hence manual installation is not required.
However, you can install and configure it as follows.
npm i -D @adonisjs/eslint-plugin@beta
# Install peer dependencies
npm i -D eslint@9 typescript typescript-eslintUsage
After installation, you can register the following as follows. Make sure to also setup the typescript-eslint parser in order for the rules to work.
// eslint.config.js
import adonisJSPlugin from '@adonisjs/eslint-plugin'
export default [
{
plugins: {
'@adonisjs': adonisJSPlugin,
},
rules: {
'@adonisjs/prefer-lazy-controller-import': 'error',
'@adonisjs/prefer-lazy-listener-import': 'error',
},
},
]prefer-lazy-controller-import
[!IMPORTANT] The HMR mode of AdonisJS only works with Lazy loaded controllers
The @adonisjs/prefer-lazy-controller-import rule complains when you import a controller using the import expression and assign it to a route. For example:
import router from '@adonisjs/core/services/router'
// ❌ Error: Replace standard import with lazy controller import
import UsersController from '#controllers/user_controller'
router.get('users', [UsersController, 'index'])The rule is auto fixable, therefore you can apply the fix depending upon the shortcuts provided by your code editor.
import router from '@adonisjs/core/services/router'
// ✅ Fixed
const UsersController = () => import('#controllers/user_controller')
router.get('users', [UsersController, 'index'])prefer-lazy-listener-import
[!IMPORTANT] The HMR mode of AdonisJS only works with Lazy loaded event listeners
The @adonisjs/prefer-lazy-listener-import rule complains when you import an event listener using the import expression and assign it to an event. For example:
import emitter from '@adonisjs/core/services/emitter'
// ❌ Error: Replace standard import with lazy controller import
import SendVerificationEmail from '#listeners/send_verification_email'
emitter.on('user:created', [SendVerificationEmail, 'handle'])The rule is auto fixable, therefore you can apply the fix depending upon the shortcuts provided by your code editor.
import emitter from '@adonisjs/core/services/emitter'
// ✅ Fixed
const SendVerificationEmail = () => import('#listeners/send_verification_email')
emitter.on('user:created', [SendVerificationEmail, 'handle'])prefer-adonisjs-inertia-link
[!NOTE] This rule is for AdonisJS 7+ projects using
@adonisjs/inertiav4+.
The @adonisjs/prefer-adonisjs-inertia-link rule warns when you import the Link component from @inertiajs/react or @inertiajs/vue3 instead of using the typesafe version from @adonisjs/inertia.
// ❌ Warning: Prefer importing Link from @adonisjs/inertia/react for typesafe routing
import { Link } from '@inertiajs/react'// ✅ Correct
import { Link } from '@adonisjs/inertia/react'prefer-adonisjs-inertia-form
[!NOTE] This rule is for AdonisJS 7+ projects using
@adonisjs/inertiav4+. You must enable it manually.
The @adonisjs/prefer-adonisjs-inertia-form rule warns when you import the Form component from @inertiajs/react or @inertiajs/vue3 instead of using the typesafe version from @adonisjs/inertia.
// ❌ Warning: Prefer importing Form from @adonisjs/inertia/react for typesafe routing
import { Form } from '@inertiajs/react'// ✅ Correct
import { Form } from '@adonisjs/inertia/react'no-backend-import-in-frontend
The @adonisjs/no-backend-import-in-frontend rule prevents importing backend code in your frontend files located in the inertia/ directory.
The rule detects both:
- Subpath imports (
#models/user) - automatically reads yourpackage.jsonimports field - Relative imports (
../../app/models/user) - checks if the resolved path is outsideinertia/
// inertia/pages/users.tsx
// ❌ Error: Importing backend code in frontend files is not allowed
import User from '#models/user'
import { UserService } from '../../app/services/user_service'// inertia/pages/users.tsx
// ✅ Correct - type-only imports are allowed
import type { User } from '#models/user'
import type { UserService } from '../../app/services/user_service'
// ✅ Correct - imports pointing to inertia/ are allowed
import { Button } from '#components/button' // if #components/* -> ./inertia/components/*
import { utils } from '../utils'Sharing code between frontend and backend
If you have shared code (e.g., enums, constants, utility types) in your backend that you want to import in your frontend, you can use the allowed option to whitelist specific paths:
// eslint.config.js
export default [
{
rules: {
'@adonisjs/no-backend-import-in-frontend': [
'error',
{
allowed: [
'#shared/*', // allows #shared/enums, #shared/constants, etc.
'#shared/**', // allows #shared/utils/helpers (deep nested)
'#enums', // exact match
],
},
],
},
},
]The allowed option uses micromatch for glob pattern matching.
// inertia/pages/users.tsx
// ✅ Correct - #shared/* is in the allowed list
import { UserStatus } from '#shared/enums'