{"record":{"id":"8dcfd933ff7c350d","repo":"oxc-project/oxc","slug":"unexpected-access-to-exports","errorCode":null,"errorMessage":"Unexpected access to `exports`.","messagePattern":"Unexpected access to `exports`\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"info","filePath":"crates/oxc_linter/src/rules/node/exports_style.rs","lineNumber":21,"sourceCode":"    ast::{AssignmentExpression, Expression},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::{NodeId, ReferenceId};\nuse oxc_span::{GetSpan, Span};\nuse schemars::JsonSchema;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    ast_util::iter_outer_expressions,\n    config::GlobalValue,\n    context::LintContext,\n    rule::{Rule, TupleRuleConfig},\n    utils::{is_global_exports_assignment_target, is_global_module_exports},\n};\n\nfn unexpected_exports_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected access to `exports`.\")\n        .with_help(\"Use `module.exports` instead.\")\n        .with_label(span)\n}\n\nfn unexpected_module_exports_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected access to `module.exports`.\")\n        .with_help(\"Use `exports` instead.\")\n        .with_label(span)\n}\n\nfn unexpected_assignment_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Unexpected assignment to `exports`.\")\n        .with_help(\"Do not modify `exports` itself.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]\n#[serde(rename_all = \"kebab-case\")]","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/node/exports_style.rs#L3-L39","documentation":"Diagnostic from oxlint rule node/exports-style (style category). The rule enforces one CommonJS export idiom per codebase; in the default 'module.exports' mode, any access to the bare global `exports` identifier is flagged with the suggestion to use module.exports. This is purely stylistic — `exports.foo = 1` and `module.exports.foo = 1` behave identically as long as `exports` itself is never reassigned — but mixing the two forms across a module or team hurts grep-ability.","triggerScenarios":"The rule is enabled in its default mode (config \"node/exports-style\": \"error\" with no option, or \"module.exports\") and the source contains an identifier reference that resolves to the module-scope global `exports` (detected via the shared is_global_module_exports util) — e.g. exports.foo = 42; or const e = exports;. A local variable shadowing the name `exports` does not trigger the util.","commonSituations":"Teams adopting a shared oxlint config that standardizes on module.exports; files copied in from a project that used the exports style; refactors that introduce a stray exports.x next to existing module.exports assignments.","solutions":["Rewrite the access: 'exports.foo = 42' becomes 'module.exports.foo = 42'","If the file or subdirectory deliberately uses the exports style, switch the rule mode: \"node/exports-style\": [\"error\", \"exports\"] (that flips the rule to flag module.exports instead)","Scope the rule per directory via overrides so legacy exports-style folders are exempt"],"exampleFix":"// before (mode: module.exports)\nexports.hello = function () {};\n\n// after\nmodule.exports.hello = function () {};","handlingStrategy":"validation","validationCode":"// .oxlintrc.json — pick ONE mode and apply it repo-wide\n\"rules\": { \"node/exports-style\": [\"error\", \"module.exports\"] }\n\nnpx oxlint -c .oxlintrc.json --deny-warning .","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Decide the project's CommonJS export idiom once in the team style guide and encode it as the rule's mode","Use overrides for vendored/legacy directories so mixed-style code doesn't erode the standard","Codemod before enforcing: flip stray exports.x to module.exports.x in one commit, then turn the rule on"],"tags":["node","commonjs","exports","style","oxlint"],"backgroundTag":"commonjs-exports-style","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}