Skip to content

Commit 9de2ba1

Browse files
committed
Pull magicString from transform meta instead of constructing new instances
Reuse the lazily-created RolldownMagicString that Rolldown provides via the transform hook's meta parameter, avoiding redundant instance creation. The wrapLayout and wrapIslandsInSFC helpers now receive the magic string from their callers instead of constructing their own. https://claude.ai/code/session_01Gk9SG3CqsszLBotJRTf45S
1 parent 8057c27 commit 9de2ba1

2 files changed

Lines changed: 17 additions & 16 deletions

File tree

packages/iles/src/node/plugin/plugin.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { basename, resolve, relative } from 'pathe'
33
import type { PluginOption, ResolvedConfig, ViteDevServer } from 'vite'
44
import { transformWithOxc } from 'vite'
55

6-
import { RolldownMagicString as MagicString } from 'rolldown'
6+
import type { RolldownMagicString as MagicString } from 'rolldown'
77

88
import type { AppConfig, AppClientConfig } from '../shared'
99
import { ILES_APP_ENTRY } from '../constants'
@@ -128,25 +128,25 @@ export default function IslandsPlugins (appConfig: AppConfig): PluginOption[] {
128128
{
129129
name: 'iles:detect-islands-in-vue',
130130
enforce: 'pre',
131-
async transform (code, id) {
131+
async transform (code, id, meta) {
132132
const { path, query } = parseId(id)
133133

134134
if (query.vue !== undefined && query.type === 'script-client')
135135
return 'export default {}; if (import.meta.hot) import.meta.hot.accept()'
136136

137137
if (isSFCMain(path, query) && code.includes('client:') && code.includes('<template'))
138-
return wrapIslandsInSFC(appConfig, code, path)
138+
return wrapIslandsInSFC(appConfig, code, path, (meta as any).magicString)
139139
},
140140
},
141141
{
142142
name: 'iles:layouts',
143143
enforce: 'pre',
144-
transform (code, id) {
144+
transform (code, id, meta) {
145145
const { path, query } = parseId(id)
146146
if (!isSFCMain(path, query) || !isLayout(path)) return
147147
const layoutName = code.match(templateLayoutRegex)?.[1] || false
148148
if (String(layoutName) === 'false') return
149-
return wrapLayout(code, path)
149+
return wrapLayout(code, path, (meta as any).magicString)
150150
},
151151
},
152152

@@ -171,7 +171,7 @@ export default function IslandsPlugins (appConfig: AppConfig): PluginOption[] {
171171
{
172172
name: 'iles:page-data',
173173
enforce: 'post',
174-
async transform (code, id, options) {
174+
async transform (code, id, transformMeta) {
175175
const { path, query } = parseId(id)
176176
const isMdx = isMarkdown(path)
177177
if (!isMdx && !isVueScript(path, query)) return
@@ -184,7 +184,7 @@ export default function IslandsPlugins (appConfig: AppConfig): PluginOption[] {
184184
if (!sfcIndex || sfcIndex === -1)
185185
return
186186

187-
const s = new MagicString(code)
187+
const s = (transformMeta as any).magicString as MagicString
188188
const appendToSfc = (key: string, value?: string) =>
189189
s.appendRight(sfcIndex, value ? `${key}:${value},` : `${key},`)
190190

packages/iles/src/node/plugin/wrap.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { RolldownMagicString as MagicString } from 'rolldown'
1+
import type { RolldownMagicString as MagicString } from 'rolldown'
22
import type { SFCBlock } from 'vue/compiler-sfc'
33
import { parse } from 'vue/compiler-sfc'
44
import type { ComponentInfo, PublicPluginAPI as ComponentsApi } from 'unplugin-vue-components/types'
@@ -15,12 +15,10 @@ interface SfcRootNode extends RootNode {
1515

1616
export const unresolvedIslandKey = '__viteIslandComponent'
1717

18-
export async function wrapLayout (code: string, filename: string) {
18+
export async function wrapLayout (code: string, filename: string, s: MagicString) {
1919
const { descriptor: { template }, errors } = parse(code, { filename })
2020
if (errors.length > 0 || !template || !isString(template.attrs.layout)) return
2121

22-
const s = new MagicString(code)
23-
2422
const nodes = template.ast?.children
2523
if (!nodes?.length) {
2624
return
@@ -38,9 +36,14 @@ export async function wrapLayout (code: string, filename: string) {
3836

3937
const scriptClientRE = /<script\b([^>]*\bclient:[^>]*)>([^]*?)<\/script>/
4038

41-
export async function wrapIslandsInSFC (config: AppConfig, code: string, filename: string) {
42-
code = code.replace(scriptClientRE, (_, attrs, content) =>
43-
`<script-client${attrs}>${content}</script-client>`)
39+
export async function wrapIslandsInSFC (config: AppConfig, code: string, filename: string, s: MagicString) {
40+
const match = scriptClientRE.exec(code)
41+
if (match) {
42+
const [full, attrs, content] = match
43+
const replacement = `<script-client${attrs}>${content}</script-client>`
44+
s.overwrite(match.index, match.index + full.length, replacement)
45+
code = s.toString()
46+
}
4447

4548
const { descriptor: { template, script, scriptSetup, customBlocks }, errors } = parse(code, { filename })
4649
const scriptClientIndex = customBlocks.findIndex(b => b.type === 'script-client')
@@ -55,8 +58,6 @@ export async function wrapIslandsInSFC (config: AppConfig, code: string, filenam
5558
return
5659
}
5760
const sfcRootNode = template.ast as any as SfcRootNode
58-
59-
const s = new MagicString(code)
6061
const components: ComponentsApi = config.namedPlugins.components.api
6162

6263
if (scriptClient) { await injectClientScript(sfcRootNode, s, filename, scriptClientIndex, scriptClient) }

0 commit comments

Comments
 (0)