From 637a039dc939b813bb504375f2eba3200630a7eb Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 5 Feb 2024 16:39:06 +0000 Subject: [PATCH 1/2] fix: use `magic-string` to create sourcemaps --- src/index.ts | 74 +++++++++++++++++---------- src/types.ts | 1 + test/__snapshots__/index.test.ts.snap | 47 +++++------------ 3 files changed, 60 insertions(+), 62 deletions(-) diff --git a/src/index.ts b/src/index.ts index 883d65d..841c855 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,12 +5,13 @@ import { resolve } from 'pathe' import { existsSync } from 'fs' import { parse } from '@vue/compiler-dom' import type { RootNode, ElementNode, AttributeNode } from '@vue/compiler-dom' +import MagicString from 'magic-string' const FORMKIT_CONFIG_ID = 'virtual:formkit-config' -const FORMKIT_PROVIDER_IMPORT_STATEMENT = [ - `import { FormKitProvider } from "@formkit/vue";`, - `import __formkitConfig from "${FORMKIT_CONFIG_ID}";`, -].join('\n') +const FORMKIT_PROVIDER_IMPORT_STATEMENT = ` +import { FormKitProvider } from "@formkit/vue"; +import __formkitConfig from "${FORMKIT_CONFIG_ID}"; +` /** * A relatively cheap, albeit not foolproof, regex to determine if the code * being processed contains FormKit usage. @@ -67,15 +68,19 @@ function langAttr(node?: ElementNode): string { * Imports `FormKitProvider` component into the script block of the SFC. * @param code - The SFC source code. * @param id - The ID of the SFC file. + * @param s - A MagicString instance, for tracking sourcemaps. */ -function injectProviderImport(code: string): string { +function injectProviderImport( + code: string, + s = new MagicString(code), +): MagicString | undefined { let root: RootNode try { root = parse(code) } catch (err) { console.warn('Failed to parse SFC:', code) console.error(err) - return code + return } const script = getRootBlock(root, 'script') const setupScript = root.children.find( @@ -83,56 +88,51 @@ function injectProviderImport(code: string): string { node.type === 1 && node.tag === 'script' && isSetupScript(node), ) if (!setupScript) { - return [ - ``, - code, - ].join('\n') + const block = `\n` + return s.prepend(block) } + const startAt = setupScript.children[0].loc.start.offset - const before = code.substring(0, startAt) - const after = code.substring(startAt) - return `${before}\n${FORMKIT_PROVIDER_IMPORT_STATEMENT}${after}` + return s.appendLeft(startAt, FORMKIT_PROVIDER_IMPORT_STATEMENT) } /** * Injects the `` component import into the SFC. * @param code - The SFC source code. * @param id - The ID of the SFC file. + * @param s - A MagicString instance, for tracking sourcemaps. */ function injectProviderComponent( code: string, id: string, -): { code: string; map?: null } { + s = new MagicString(code), +): MagicString | undefined { let root: RootNode try { root = parse(code) } catch (err) { console.warn('Failed to parse SFC:', code) console.error(err) - return { code } + return } + const template = getRootBlock(root, 'template') if (!template) { console.warn( `No