These rules perform static analysis to validate import/export syntax and ensure modules can be resolved correctly. They prevent runtime errors by catching typos in module references and validating that imported names exist in their source modules.
Ensures imports point to files/modules that can be resolved.
const noUnresolved: RuleModule<'unresolved' | 'casingMismatch', [
{
commonjs?: boolean;
amd?: boolean;
esmodule?: boolean;
ignore?: string[];
caseSensitive?: boolean;
caseSensitiveStrict?: boolean;
}?
]>;Options:
commonjs (boolean): Check CommonJS modules (default: true)amd (boolean): Check AMD modules (default: true)esmodule (boolean): Check ES modules (default: true)ignore (string[]): Patterns to ignorecaseSensitive (boolean): Enforce case sensitivity (default: true)Example:
// ✗ BAD - module doesn't exist
import foo from './nonexistent-module';
// ✓ GOOD - module exists
import foo from './existing-module';Ensures named imports correspond to a named export in the remote file.
const named: RuleModule<'notFound' | 'notFoundDeep', [
{
commonjs?: boolean;
}?
]>;Options:
commonjs (boolean): Check CommonJS exports (default: true)Example:
// In utils.js: export { helper };
// ✗ BAD - 'nonexistent' is not exported from utils.js
import { helper, nonexistent } from './utils';
// ✓ GOOD - 'helper' is exported from utils.js
import { helper } from './utils';Ensures a default export is present, given a default import.
const defaultRule: RuleModule<'noDefaultExport', []>;Example:
// In utils.js: export { helper }; (no default export)
// ✗ BAD - no default export in utils.js
import utils from './utils';
// ✓ GOOD - using named import
import { helper } from './utils';Ensures imported namespaces contain dereferenced properties as they are dereferenced.
const namespace: RuleModule<'computedReference' | 'topLevelNames', [
{
allowComputed?: boolean;
}?
]>;Options:
allowComputed (boolean): Allow computed property access (default: false)Example:
// In utils.js: export { helper };
// ✗ BAD - 'nonexistent' is not exported from utils.js
import * as utils from './utils';
utils.nonexistent();
// ✓ GOOD - 'helper' is exported from utils.js
import * as utils from './utils';
utils.helper();Forbids any invalid exports, i.e. re-export of the same name.
const exportRule: RuleModule<'duplicateExport' | 'multipleDefaults', []>;Example:
// ✗ BAD - duplicate export
export const foo = 1;
export const foo = 2;
// ✗ BAD - multiple default exports
export default function a() {}
export default function b() {}
// ✓ GOOD - unique exports
export const foo = 1;
export const bar = 2;
export default function main() {}Forbids use of exported name as identifier of default export.
const noNamedAsDefault: RuleModule<'default', []>;Example:
// In foo.js: export default 'foo'; export const foo = 'bar';
// ✗ BAD - 'foo' is also a named export
import foo from './foo';
// ✓ GOOD - use different name for default import
import fooDefault from './foo';
import { foo } from './foo'; // or use named importForbids use of exported name as property of default export.
const noNamedAsDefaultMember: RuleModule<'useMember', []>;Example:
// In foo.js: export default { bar: 'baz' }; export const bar = 'qux';
// ✗ BAD - 'bar' is also a named export
import foo from './foo';
const bar = foo.bar;
// ✓ GOOD - use named import directly
import { bar } from './foo';Forbids repeated import of the same module in multiple places.
const noDuplicates: RuleModule<'duplicate', [
{
considerQueryString?: boolean;
'prefer-inline'?: boolean;
}?
]>;Options:
considerQueryString (boolean): Consider query strings in module paths (default: false)prefer-inline (boolean): Prefer inline type imports (default: false)Example:
// ✗ BAD - duplicate imports
import { merge } from 'lodash';
import { find } from 'lodash';
// ✓ GOOD - single import statement
import { merge, find } from 'lodash';Forbids empty named import blocks.
const noEmptyNamedBlocks: RuleModule<'emptyNamed', []>;Example:
// ✗ BAD - empty named import
import { } from 'module';
// ✗ BAD - empty destructuring with default
import foo, { } from 'module';
// ✓ GOOD - non-empty named import
import { something } from 'module';
// ✓ GOOD - side-effect import
import 'module';Forbids the use of mutable exports with var or let.
const noMutableExports: RuleModule<'mutatingExport', []>;Example:
// ✗ BAD - mutable exports
export var config = { debug: true };
export let state = 'initial';
// ✓ GOOD - immutable exports
export const config = { debug: true };
export const initialState = 'initial';
// ✓ GOOD - mutable local, immutable export
let state = 'initial';
export function getState() { return state; }
export function setState(newState) { state = newState; }Reports modules without exports, or exports without matching import in another module.
const noUnusedModules: RuleModule<'unused' | 'notFound', [
{
src?: string[];
ignoreExports?: string[];
missingExports?: boolean;
unusedExports?: boolean;
}?
]>;Options:
src (string[]): Source directories to analyze (default: ['.'])ignoreExports (string[]): Export patterns to ignoremissingExports (boolean): Report modules with no exports (default: true)unusedExports (boolean): Report unused exports (default: true)Example:
// In unused.js - has exports but never imported
export const unusedFunction = () => {}; // ✗ BAD - unused export
// In empty.js - no exports
const localOnly = 'test'; // ✗ BAD - file has no exports
// ✓ GOOD - exported and used elsewhere
export const usedFunction = () => {};Reports imported names marked with @deprecated documentation tag.
const noDeprecated: RuleModule<'deprecated', []>;Example:
// In api.js
/**
* @deprecated Use newMethod instead
*/
export const oldMethod = () => {};
export const newMethod = () => {};
// In consumer.js
// ✗ BAD - using deprecated import
import { oldMethod } from './api';
// ✓ GOOD - using non-deprecated import
import { newMethod } from './api';interface ValidationError {
message: string;
line: number;
column: number;
ruleId: string;
severity: 'error' | 'warn';
}
type RuleModule<T extends string = string, O extends readonly unknown[] = readonly unknown[]> = {
meta: {
type: 'problem' | 'suggestion' | 'layout';
docs: {
description: string;
category: string;
recommended: boolean;
url: string;
};
fixable?: 'code' | 'whitespace';
schema: JSONSchema4 | JSONSchema4[];
messages: Record<T, string>;
};
create(context: RuleContext<T, O>): Record<string, (node: any) => void>;
};