diff --git a/src/core/transform/compilers/index.ts b/src/core/transform/compilers/index.ts index 01bb9f3..317b31c 100644 --- a/src/core/transform/compilers/index.ts +++ b/src/core/transform/compilers/index.ts @@ -1,10 +1,12 @@ import type { CompileResult, Compiler, Context } from '../../../types' -import { vueCompiler } from './vue' +import { vue3Compiler } from './vue3' +import { vue2Compiler } from './vue2' import { vanillaCompiler } from './vanilla' import { svelteCompiler } from './svelte' export const compilers: Record Promise> = { - vue: vueCompiler, + vue3: vue3Compiler, + vue2: vue2Compiler, vanilla: vanillaCompiler, svelte: svelteCompiler, } diff --git a/src/core/transform/compilers/vue.ts b/src/core/transform/compilers/vue.ts deleted file mode 100644 index 0eba723..0000000 --- a/src/core/transform/compilers/vue.ts +++ /dev/null @@ -1,73 +0,0 @@ -import type { CompilerError, SFCDescriptor } from 'vue/compiler-sfc' -import { PLUGIN_NAME } from '../../constants' -import type { CompileResult, Context } from './../../../types' - -export async function vueCompiler(context: Context): Promise { - try { - const { code, id } = context - - const compileResults = { - script: '', - line: 0, - offset: 0, - } - - let descriptor: SFCDescriptor | undefined - let errors: (CompilerError | SyntaxError)[] = [] - - const Vue = await import('vue') - - if (!Vue || typeof Vue.version !== 'string') { - throw new Error(`[${PLUGIN_NAME}]: Vue is not installed`) - } - else if (Vue.version.startsWith('2.')) { - const { parse } = await import('vue/compiler-sfc') - // @ts-expect-error vue2 compiler-sfc - const _descriptor: any = parse({ - source: code, - filename: id, - }) - - descriptor = _descriptor - errors = _descriptor.errors - } - else if (Vue.version.startsWith('3.')) { - const { parse } = await import('vue/compiler-sfc') - const { descriptor: _descriptor, errors: _errors } = parse(code, { - filename: id, - }) - - descriptor = _descriptor - errors = _errors - } - else { - throw new Error(`[${PLUGIN_NAME}]: Unsupported Vue version: ${Vue.version}`) - } - - if (errors.length === 0) { - if (descriptor?.script) { - compileResults.script = descriptor.script.content - const { line, offset } = descriptor.script.loc.start - compileResults.line = line - 1 - compileResults.offset = offset - } - - else if (descriptor?.scriptSetup) { - compileResults.script = descriptor.scriptSetup.content - const { line, offset } = descriptor.scriptSetup.loc.start - compileResults.line = line - 1 - compileResults.offset = offset - } - } - - return compileResults - } - catch (error) { - console.error(`[${PLUGIN_NAME}]`, error) - return { - script: '', - offset: 0, - line: 0, - } - } -} diff --git a/src/core/transform/compilers/vue2.ts b/src/core/transform/compilers/vue2.ts new file mode 100644 index 0000000..1560265 --- /dev/null +++ b/src/core/transform/compilers/vue2.ts @@ -0,0 +1,48 @@ +import { PLUGIN_NAME } from '../../constants' +import type { CompileResult, Context } from '../../../types' + +export async function vue2Compiler(context: Context): Promise { + try { + const { code, id } = context + const { parse } = await import('vue/compiler-sfc') + + const compileResults = { + script: '', + line: 0, + offset: 0, + } + + // @ts-expect-error vue2 compiler-sfc + const descriptor: any = parse({ + source: code, + filename: id, + }) + + if (descriptor.errors.length === 0) { + if (descriptor.script) { + compileResults.script = descriptor.script.content + const offset = descriptor.script.start + const line = code.slice(0, offset).split('\n').length + compileResults.line = line + compileResults.offset = offset + } + else if (descriptor.scriptSetup) { + compileResults.script = descriptor.scriptSetup.content + const offset = descriptor.scriptSetup.start + const line = code.slice(0, offset).split('\n').length + compileResults.line = line + compileResults.offset = offset + } + } + + return compileResults + } + catch (error) { + console.error(`[${PLUGIN_NAME}]`, error) + return { + script: '', + offset: 0, + line: 0, + } + } +} diff --git a/src/core/transform/compilers/vue3.ts b/src/core/transform/compilers/vue3.ts new file mode 100644 index 0000000..0b76f96 --- /dev/null +++ b/src/core/transform/compilers/vue3.ts @@ -0,0 +1,45 @@ +import { PLUGIN_NAME } from '../../constants' +import type { CompileResult, Context } from '../../../types' + +export async function vue3Compiler(context: Context): Promise { + try { + const { code, id } = context + const { parse } = await import('vue/compiler-sfc') + + const compileResults = { + script: '', + line: 0, + offset: 0, + } + + const { descriptor, errors } = parse(code, { + filename: id, + }) + + if (errors.length === 0) { + if (descriptor.script) { + compileResults.script = descriptor.script.content + const { line, offset } = descriptor.script.loc.start + compileResults.line = line - 1 + compileResults.offset = offset + } + + else if (descriptor.scriptSetup) { + compileResults.script = descriptor.scriptSetup.content + const { line, offset } = descriptor.scriptSetup.loc.start + compileResults.line = line - 1 + compileResults.offset = offset + } + } + + return compileResults + } + catch (error) { + console.error(`[${PLUGIN_NAME}]`, error) + return { + script: '', + offset: 0, + line: 0, + } + } +} diff --git a/src/core/transform/index.ts b/src/core/transform/index.ts index d112d15..b479d6b 100644 --- a/src/core/transform/index.ts +++ b/src/core/transform/index.ts @@ -10,7 +10,7 @@ export async function transform(context: Context) { const { code, id, options } = context const magicString = new MagicString(code) - const compiler = getCompiler(id) + const compiler = await getCompiler(id) if (!compiler) { return { @@ -31,7 +31,13 @@ export async function transform(context: Context) { plugins: ['jsx', 'typescript'], }) - if (isPluginDisable({ comments: program.comments || [], originalLine: 1, id, type: 'top-file' })) { + if (isPluginDisable({ + comments: program.comments || [], + originalLine: 1, + id, + type: 'top-file', + compiler, + })) { return { code: magicString.toString(), map: magicString.generateMap({ @@ -58,7 +64,13 @@ export async function transform(context: Context) { const originalLine = line + compileResult.line const originalColumn = column - if (isPluginDisable({ comments: program.comments || [], originalLine: line, id, type: 'inline-file' })) + if (isPluginDisable({ + comments: program.comments || [], + originalLine: line, + id, + type: 'inline-file', + compiler, + })) return false // @ts-expect-error any diff --git a/src/core/utils.ts b/src/core/utils.ts index 1672cc1..76c9be7 100644 --- a/src/core/utils.ts +++ b/src/core/utils.ts @@ -58,13 +58,28 @@ export function getExtendedPath(filePath: string, extendedPathFileNames?: string return basename } -export function getCompiler(id: string): Compiler | undefined { +export async function getCompiler(id: string): Promise { const urlObject = new URL(id, 'file://') const fileType = extname(urlObject.pathname) switch (fileType) { - case '.vue': - return 'vue' + case '.vue': { + const Vue = await import('vue') + if (!Vue || typeof Vue.version !== 'string') { + console.warn(`[${PLUGIN_NAME}]: Vue is not installed`) + return undefined + } + else if (Vue.version.startsWith('2.')) { + return 'vue2' + } + else if (Vue.version.startsWith('3.')) { + return 'vue3' + } + else { + console.warn(`[${PLUGIN_NAME}]: Unsupported Vue version: ${Vue.version}`) + return undefined + } + } case '.svelte': return 'svelte' case '.js': @@ -87,14 +102,14 @@ export function isPluginDisable(meta: { originalLine: number id: string type: 'top-file' | 'inline-file' + compiler: Compiler }) { - const { comments, originalLine, id, type } = meta + const { comments, originalLine, type, compiler } = meta if (comments?.length === 0) return false if (type === 'top-file') { - const compiler = getCompiler(id) const startLine = compiler === 'vanilla' ? 1 : 2 const disablePluginComment = comments?.find(comment => comment.value.includes('turbo-console-disable')) diff --git a/src/types.ts b/src/types.ts index 11b1c24..fe01dfd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -57,7 +57,7 @@ export interface GenContext { id: string } -export type Compiler = 'vanilla' | 'vue' | 'svelte' +export type Compiler = 'vanilla' | 'vue3' | 'vue2' | 'svelte' export interface Context { code: string