@eventra_dev/cli-plugin-vue
| Install | |
|---|---|
npm install @eventra_dev/cli-plugin-vue |
|
| Latest Version: | 1.1.1 |
| License: | MIT |
| Last Updated: | Oct 17, 2026 |
| Links: | GitHub · npm |
Eventra CLI Plugin — Vue
Official Eventra CLI plugin — extracts track() calls from Vue Single-File Components (.vue), so eventra sync/check/watch understand Vue and Nuxt code the same way they already understand plain TypeScript.
Overview
The CLI core is framework-agnostic and only walks .ts/.tsx/.js/.jsx. This plugin teaches it .vue: it parses each SFC with the real Vue compiler (@vue/compiler-sfc) — not a regex — and hands the CLI a single virtual TypeScript module per file, so every existing detection rule (direct SDK calls, function wrappers, cross-file propagation, dynamic-name reporting) applies to Vue code without any Vue-specific case in the core engine.
Vue and Nuxt .vue files are handled the same way — Nuxt pages/layouts/components are ordinary Vue SFCs. See Nuxt below for auto-import composables.
Installation
npm install -D @eventra_dev/cli-plugin-vue @eventra_dev/eventra-cli
# or
pnpm add -D @eventra_dev/cli-plugin-vue @eventra_dev/eventra-cli
Enable it in eventra.json:
{
"plugins": ["@eventra_dev/cli-plugin-vue"],
"sync": {
"include": ["**/*.{ts,tsx,js,jsx}"],
"exclude": ["node_modules", "dist", ".next", ".git"]
}
}
sync.include does not need **/*.vue added manually — the plugin registers it via includeGlobs.
What gets detected
<script> / <script setup>
Handled exactly like a regular .ts file — direct SDK calls, function wrappers, variables, ternaries, cross-file propagation all apply:
<script setup lang="ts">
import { Eventra } from "@eventra_dev/eventra-sdk";
const tracker = new Eventra({ apiKey: "YOUR_PROJECT_API_KEY" });
tracker.track("checkout.started");
</script>
<script> + <script setup> in the same file are merged in source order. defineProps/defineEmits/defineExpose/defineOptions/withDefaults pass through untouched.
<template> — literal event attributes
<template>
<Button event="checkout.cta" />
</template>
<template> — dynamic event attributes
<template>
<Button :event="computedEventName" />
</template>
The expression is copied as-is into the same module scope as the script. If it resolves to a real script-level constant, the event name is detected normally; otherwise it's reported as a dynamic occurrence (same mechanism as tracker.track(someVariable) in plain TypeScript) instead of being silently dropped.
External blocks
<script src="./logic.ts"> and <template src="./view.html"> are resolved and read from disk.
<template> - calls in handlers and expressions
Tracking calls written in the template itself are read, not only event attributes:
<template>
<button @click="() => { open(); trackEvent('plan:cogm_open', { id }) }">Open</button>
<p>{{ trackEvent('panel:viewed') }}</p>
</template>
Read: @click / v-on handlers (one or several statements, multi-line arrow functions), {{ }} interpolations the source of v-for (item in items()), dynamic arguments (:[name()], @[event()]) and the expressions of v-bind, v-if, v-else-if, v-show, v-model, v-html and v-text. They are placed in the same module as the script, so a function imported or defined there resolves normally; an argument that comes from a v-for variable is reported as a dynamic occurrence. The loop variables of v-for and v-slot parameters are not code and are skipped; the value of a custom directive (v-focus="x") is left alone.
Nuxt
Nuxt pages, layouts, and components are ordinary .vue SFCs — parsed identically, no extra configuration needed.
Composables auto-imported without an explicit import statement (Nuxt's own composables, or your own from composables//utils/) are intended to resolve once the project has run nuxt prepare/nuxt dev (so .nuxt/ exists and is wired into tsconfig.json - the CLI analyzes the project's real tsconfig.json, so Nuxt's generated ambient types are visible to it like any other TypeScript project). The host CLI's resolver understands the declare const x: typeof import("./module")["name"] shape Nuxt/unplugin-auto-import generate for these bindings (covered by a unit test with a hand-written fixture of that ambient shape, and verified manually end to end on a real Nuxt 3 project: after nuxt prepare, calls to an auto-imported composable that wraps track() were detected with no explicit import; without .nuxt/ the same project yields no events). The end-to-end check is manual, not part of the automated test suite.
Configuration
No plugin-specific config — it activates purely by being listed in eventra.json's plugins array (see Installation).
Plugin contract
export interface CliPluginVue {
readonly id: string;
readonly version: string;
readonly includeGlobs: readonly string[];
readonly staticSinks?: readonly CliPluginStaticCalleeSink[];
match(path: string): boolean;
transform(input: { path: string; source: string }): Promise<{
modules: Array<{ path: string; content: string }>;
}>;
}
No dependency on @eventra_dev/eventra-cli - the CLI adapts this shape internally. .vue → one virtual .vue.ts module (compiled script content, then a function wrapping synthetic calls for every template event="..." binding and the handlers, interpolations and directive expressions copied from the template, under a // --- vue template (auto-generated) --- comment the CLI uses to tell generated code from your own lines). staticSinks describes those synthetic calls; the CLI builds its own sink detector from them. See @eventra_dev/eventra-cli's plugin docs for the full external-plugin contract.
Requirements
- Node.js 18+
@eventra_dev/eventra-clias the host CLI
Test Coverage
100% statement/branch/function/line coverage (v8 provider, pnpm test:coverage), enforced via a coverage.thresholds block in vitest.config.ts.
51 unit tests (vitest), covering:
| Area | Covers |
|---|---|
| SFC parsing | Script + script-setup merge order, comment safety, src= external files |
| Template — literal | Nested elements, v-if/v-for, slots, multiple template roots |
| Template — dynamic | Raw expression passthrough, resolution through the merged script scope |
| Script-setup macros | All five compiler macros (defineProps/defineEmits/defineExpose/defineOptions/withDefaults) pass through without special-casing |
| Virtual module output | Single combined .vue.ts, export stub when script/template are empty |
| Plugin contract | match(), includeGlobs, staticSinks, transform() |
The Nuxt ambient auto-import shape (declare const x: typeof import(...)) is covered by a unit test in the host CLI that hand-writes that shape. A real nuxt prepare project was also checked end to end by hand, but that check is not part of the automated suite (see the Nuxt section above).
Run locally:
pnpm --filter @eventra_dev/cli-plugin-vue test
pnpm --filter @eventra_dev/cli-plugin-vue test:coverage
License
Related Packages
Dedicated Piwik PRO library that helps with implementing Piwik PRO Tag Manager a...
Version History
| Version | Released | License |
|---|---|---|
| 1.1.1 | MIT | |
| 1.1.0 | MIT | |
| 1.0.7 | MIT | |
| 1.0.6 | MIT | |
| 1.0.5 | MIT | |
| 1.0.4 | MIT | |
| 1.0.3 | MIT | |
| 1.0.2 | MIT | |
| 1.0.1 | MIT | |
| 1.0.0 | MIT | |
| 0.2.1 | MIT |