Vue SFC Transformer
vue-sfc-transformer provides low-level utilities for transpiling Vue Single File Components (SFCs), specifically focusing on TypeScript syntax within `<script setup>` blocks and template expressions. It aims for minimal transformation, leveraging `esbuild` for the actual code transpilation. The current stable version is `0.1.17`, indicating a pre-1.0 status where API changes might occur in minor releases. This package is actively maintained, receiving frequent bug fixes and minor feature additions as evidenced by its release history, with its last publish being 4 months ago. It is part of the `nuxt-contrib` organization, suggesting its role in the Nuxt ecosystem for build tooling. Its key differentiators include its granular control over SFC block transformation, reliance on `esbuild` for performance, and specific support for handling TypeScript within Vue templates and `script setup` blocks, making it suitable for bundler integrations and custom build pipelines.
Common errors
-
Error: Cannot find module 'vue' or '@vue/compiler-core' or 'esbuild'
cause One or more required peer dependencies (`vue`, `@vue/compiler-core`, `esbuild`) are not installed.fixInstall all necessary peer dependencies: `npm install vue @vue/compiler-core esbuild`. -
SyntaxError: Cannot use import statement outside a module
cause Attempting to use `require()` for this ESM-only package or running an ESM file in a CommonJS context.fixEnsure your project is configured for ES Modules (e.g., add `"type": "module"` to your `package.json` or use `.mjs` file extension) and use `import` statements. -
TypeError: Cannot read properties of undefined (reading 'content') or similar errors related to SFC descriptor.
cause The `@vue/compiler-sfc` package was not imported, installed, or `parseSFC` failed to produce a valid descriptor.fixEnsure `@vue/compiler-sfc` is installed (`npm install @vue/compiler-sfc`) and correctly imported, e.g., `import { parse as parseSFC } from '@vue/compiler-sfc'`. -
(node:...) V8: API mismatch: argument #1 to V8::HandleScope::Create should be a v8::Isolate.
cause Running `vue-sfc-transformer` on an unsupported Node.js version (below 18.0.0).fixUpgrade your Node.js installation to version 18.0.0 or higher.
Warnings
- gotcha This package requires explicit installation of its peer dependencies: `vue`, `@vue/compiler-core`, and `esbuild`. These are not automatically installed and must be added to your project's dependencies.
- breaking As a package in the `0.x.x` version range, API stability is not guaranteed. Breaking changes may be introduced in minor (`0.x.y`) versions without a major version bump, requiring careful review of changelogs during upgrades.
- gotcha The package strictly requires Node.js version 18.0.0 or higher, as specified in its `engines` field. Using older Node.js versions will lead to runtime errors.
- gotcha Users are responsible for integrating and configuring `esbuild` for the actual JavaScript/TypeScript transpilation. `vue-sfc-transformer` provides the Vue-specific parsing and transformation logic but delegates the underlying code transformation to an `esbuild` instance provided by the user.
Install
-
npm install vue-sfc-transformer -
yarn add vue-sfc-transformer -
pnpm add vue-sfc-transformer
Imports
- preTranspileScriptSetup
const { preTranspileScriptSetup } = require('vue-sfc-transformer')import { preTranspileScriptSetup } from 'vue-sfc-transformer' - transpileVueTemplate
import transpileVueTemplate from 'vue-sfc-transformer'
import { transpileVueTemplate } from 'vue-sfc-transformer' - vueLoader
import { vueLoader } from 'vue-sfc-transformer'import { vueLoader } from 'vue-sfc-transformer/mkdist'
Quickstart
import { parse as parseSFC } from '@vue/compiler-sfc'
import { transform } from 'esbuild'
import { preTranspileScriptSetup, transpileVueTemplate } from 'vue-sfc-transformer'
const src = `
<template>
<div v-if="test as any" />
</template>
<script setup lang="ts">
defineProps<{
test?: string
}>()
</script>
`
async function processSFC() {
const sfc = parseSFC(src, {
filename: 'test.vue',
ignoreEmpty: true,
})
// Transpile the template block
const templateBlockContents = await transpileVueTemplate(
sfc.descriptor.template.content,
sfc.descriptor.template.ast,
sfc.descriptor.template.loc.start.offset,
async (code) => {
const res = await transform(code, { loader: 'ts', target: 'esnext' })
return res.code
},
)
console.log('Transpiled Template:\n', templateBlockContents)
// Expected output (roughly): <div v-if="test" />
// Pre-transpile the script setup block
const { content: scriptBlockContents } = await preTranspileScriptSetup(sfc.descriptor, 'test.vue')
console.log('Transpiled Script Setup:\n', scriptBlockContents)
// Expected output (roughly): defineProps({\n// test: { type: String, required: false }\n// })
}
processSFC().catch(console.error)