Vue SFC Parser
vue-sfc-parser is a utility library for parsing Vue.js Single File Components (SFCs) specifically designed for static analysis workflows. It provides a structured representation of an SFC, similar to `vue-template-compiler`'s `parseComponent` function, but enhances it with additional helper methods on `SFCBlock` objects, such as `calcGlobalOffset` and `calcGlobalRange`, to facilitate mapping block-specific positions back to the overall file position. Currently at version 0.1.2, the library also includes a `createDiffWatcher` API for efficiently detecting changes within individual SFC blocks, enabling sophisticated hot-reloading or analysis tools. Its release cadence is ad-hoc, reflecting its early development stage. A key differentiator is its focus on providing precise positional data and change detection, which is crucial for linters, language servers, and build tools that operate on Vue SFCs.
Common errors
-
TypeError: parseComponent is not a function
cause Attempting to use `parseComponent` in a CommonJS context when expecting a named export, or an incorrect named import in an ESM context.fixEnsure you are using `import { parseComponent } from 'vue-sfc-parser';` for ESM, or if strictly CommonJS, verify the export structure. If using TypeScript, check `tsconfig.json` for module resolution settings. -
TS2531: Object is possibly 'null'.
cause Trying to access a property (e.g., `content`) or method (e.g., `calcGlobalOffset`) on an `SFCBlock` (like `sfcDescriptor.script`) without first verifying that the block is not `null`.fixAdd a null check before accessing the block: `if (sfcDescriptor.script) { console.log(sfcDescriptor.script.content); }` or use optional chaining: `sfcDescriptor.script?.content`.
Warnings
- breaking As a pre-1.0 release (currently 0.1.2), the API surface of `vue-sfc-parser` is subject to breaking changes without adherence to semantic versioning. Minor or patch releases may introduce breaking changes.
- gotcha The `SFCDescriptor` properties like `template`, `script`, or `styles` can be `null` if the corresponding block is not present in the parsed SFC. Always perform null checks before accessing their properties or helper methods.
- gotcha While the README examples show CommonJS `require()` syntax, the library ships with TypeScript types and is intended for modern JavaScript/TypeScript environments. For new projects, prefer ESM `import` statements.
Install
-
npm install vue-sfc-parser -
yarn add vue-sfc-parser -
pnpm add vue-sfc-parser
Imports
- parseComponent
const { parseComponent } = require('vue-sfc-parser')import { parseComponent } from 'vue-sfc-parser' - createDiffWatcher
const { createDiffWatcher } = require('vue-sfc-parser')import { createDiffWatcher } from 'vue-sfc-parser' - SFCDescriptor
import { SFCDescriptor } from 'vue-sfc-parser'import type { SFCDescriptor } from 'vue-sfc-parser'
Quickstart
import { parseComponent } from 'vue-sfc-parser';
const code = `
<template>
<p>Hello from SFC!</p>
</template>
<script lang="ts">
export default {
data() {
return { msg: 'world' };
}
}
</script>
<style scoped>
p {
color: blue;
}
</style>
`;
const sfcDescriptor = parseComponent(code);
if (sfcDescriptor.template) {
console.log('Template content:', sfcDescriptor.template.content);
// Calculate global offset for 'Hello' (5 chars into template content)
const templateOffset = sfcDescriptor.template.content.indexOf('Hello');
const globalOffset = sfcDescriptor.template.calcGlobalOffset(templateOffset);
console.log(`Global offset for 'Hello': ${globalOffset}`);
}
if (sfcDescriptor.script) {
console.log('Script content:', sfcDescriptor.script.content);
const scriptOffset = sfcDescriptor.script.content.indexOf('msg');
const globalOffset = sfcDescriptor.script.calcGlobalOffset(scriptOffset);
console.log(`Global offset for 'msg': ${globalOffset}`);
}
if (sfcDescriptor.styles.length > 0) {
console.log('First style content:', sfcDescriptor.styles[0].content);
}