oxc-project/oxc · error · OxcDiagnostic
'{name}' is a compiler macro and can't be imported outside o
Error message
'{name}' is a compiler macro and can't be imported outside of `<script setup>`. What it means
The second diagnostic of vue/no-import-compiler-macros: "'{name}' is a compiler macro and can't be imported outside of `<script setup>`." Compiler macros like `defineProps` only exist inside `<script setup>` blocks, where the SFC compiler transforms them. Importing them anywhere else (plain `<script>`, a .js module, a composable) produces code that calls a function which is not actually exported by 'vue' at that position, breaking the build at runtime or compile time.
Source
Thrown at crates/oxc_linter/src/rules/vue/no_import_compiler_macros.rs:18
use oxc_ast::{
AstKind,
ast::{ImportDeclarationSpecifier, ModuleExportName},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, frameworks::FrameworkOptions, rule::Rule};
fn no_import_compiler_macros_diagnostic(span: Span, name: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("'{name}' is a compiler macro and doesn't need to be imported."))
.with_help("Remove the import statement for this macro.")
.with_label(span)
}
fn invalid_import_compiler_macros_diagnostic(span: Span, name: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"'{name}' is a compiler macro and can't be imported outside of `<script setup>`."
))
.with_help("Remove the import statement for this macro.")
.with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoImportCompilerMacros;
declare_oxc_lint!(
/// ### What it does
///
/// Disallow importing Vue compiler macros.
///
/// ### Why is this bad?
///
/// Compiler Macros like:
/// - `defineProps`View on GitHub (pinned to e1e7af627c)
Solutions
- Remove the macro import — the code cannot use compiler macros outside `<script setup>`.
- Move the code that calls the macro (defineProps/defineEmits/...) back into the component's `<script setup>` block.
- Replace macro usage with runtime equivalents in plain modules, e.g. `defineComponent({ props: {...} })` or `vue`'s runtime `defineComponent` API.
- Re-run oxlint to confirm no remaining out-of-scope macro imports.
Example fix
// before (composables/useThing.ts)
import { defineProps } from 'vue'; // can't be imported outside of `<script setup>`
export function useThing(props) { ... }
// after (composables/useThing.ts)
export function useThing(props) { ... }
// and in the component:
<script setup>
const props = defineProps<{ id: string }>();
useThing(props);
</script> Defensive patterns
Strategy: validation
Prevention
- Keep all compiler-macro usage inside `<script setup>` blocks only.
- In plain modules use runtime APIs (defineComponent with props/emits options) instead of macros.
- When extracting logic from a component into a helper, pass props/emits in as arguments rather than re-declaring macros.
When it happens
Trigger: An import declaration resolving a compiler macro name in any context other than `<script setup>` — e.g. `import { defineProps } from 'vue'` in a plain .ts composable, in a `<script>` block without `setup`, or in a helper module that calls the macro.
Common situations: Extracting part of a component's prop logic into a helper file; mixing `<script>` and `<script setup>` and importing the macro in the wrong block; copy-pasting script-setup code into a plain module.
Related errors
- '{name}' is a compiler macro and doesn't need to be imported
- Could not find the reuseWorker option in ${path}
- [HIRBuilder] expected block {:?} to exist
- Inline helpers are not supported yet
- TS5042
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/1989232e17efa9f9.
Report an issue: GitHub.