{"record":{"id":"7e5ad570054ae34e","repo":"oxc-project/oxc","slug":"script-setup-cannot-contain-es-module-exports","errorCode":null,"errorMessage":"<script setup>` cannot contain ES module exports.","messagePattern":"<script setup>` cannot contain ES module exports\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/vue/no_export_in_script_setup.rs","lineNumber":12,"sourceCode":"use oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\n\nuse crate::{\n    context::{ContextHost, LintContext},\n    frameworks::FrameworkOptions,\n    rule::Rule,\n};\n\nfn no_export_in_script_setup_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"<script setup>` cannot contain ES module exports.\").with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoExportInScriptSetup;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow `export` in `<script setup>`\n    ///\n    /// ### Why is this bad?\n    ///\n    /// The previous version of `<script setup>` RFC used `export` to define variables used in templates,\n    /// but the new `<script setup>` RFC has been updated to define without using `export`.\n    /// See [Vue RFCs - 0040-script-setup](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0040-script-setup.md) for more details.\n    ///\n    /// ### Examples\n    ///","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/vue/no_export_in_script_setup.rs#L1-L30","documentation":"The vue/no-export-in-script-setup rule disallows ES module export statements inside a `<script setup>` block. `<script setup>` is compiled by the Vue SFC compiler into the body of the component's `setup()` function, so `export` / `export default` syntax has no valid target there and breaks compilation of the component. Everything declared in `<script setup>` is already implicitly exposed to the template.","triggerScenarios":"Writing any `export`, `export default`, or re-export statement inside a `<script setup>` block in a .vue file that oxlint scans, e.g. `export const foo = 1` inside `<script setup>`. Migrating a plain module into `<script setup>` and leaving its exports behind.","commonSituations":"Converting a normal `<script>` block to `<script setup>` without stripping exports; trying to share helpers from a component file by exporting them; copy-pasting composable code that ends with `export` into the block.","solutions":["Remove the `export` keyword — top-level bindings in `<script setup>` are already usable in the template.","Move the exported helper/constant into a separate .js/.ts module and import it inside `<script setup>`.","If you need a normal `<script>` block alongside (e.g. for named exports or run-once logic), split the file into both `<script>` and `<script setup>` blocks.","Re-run oxlint to verify the diagnostic cleared."],"exampleFix":"// before\n<script setup>\nexport const MAX = 10; // cannot contain ES module exports\nconst count = ref(0);\n</script>\n\n// after\n<script setup>\nimport { MAX } from './constants';\nconst count = ref(0);\n</script>","handlingStrategy":"validation","validationCode":"# catch exports in <script setup> before the SFC compiler does\nnpx oxlint src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep `<script setup>` free of any `export` keyword by convention.","Put shared helpers in sibling .ts modules and import them.","Add the rule to your oxlint config's Vue preset so CI catches regressions.","Watch for IDE auto-fixes that add exports while refactoring blocks."],"tags":["vue","script-setup","lint","module-syntax","sfc"],"backgroundTag":"invalid-module-syntax","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}