fix: support sourcemap for `nuxt:pages-macros-transform` (#3429)

This commit is contained in:
Anthony Fu 2022-03-01 03:21:03 +08:00 committed by GitHub
parent 3888b0c338
commit 0c99002351
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 13 deletions

View File

@ -1,6 +1,7 @@
import { createUnplugin } from 'unplugin'
import { parseQuery, parseURL, withQuery } from 'ufo'
import { findStaticImports, findExports } from 'mlly'
import MagicString from 'magic-string-extra'
export interface TransformMacroPluginOptions {
macros: Record<string, string>
@ -16,20 +17,20 @@ export const TransformMacroPlugin = createUnplugin((options: TransformMacroPlugi
return pathname.endsWith('.vue') || !!parseQuery(search).macro
},
transform (code, id) {
const originalCode = code
const s = new MagicString(code, { sourcemapOptions: { source: id, includeContent: true } })
const { search } = parseURL(id)
// Tree-shake out any runtime references to the macro.
// We do this first as it applies to all files, not just those with the query
for (const macro in options.macros) {
const match = code.match(new RegExp(`\\b${macro}\\s*\\(\\s*`))?.[0]
if (match) {
code = code.replace(match, `/*#__PURE__*/ false && ${match}`)
const match = code.match(new RegExp(`\\b${macro}\\s*\\(\\s*`))
if (match?.[0]) {
s.overwrite(match.index, match.index + match[0].length, `/*#__PURE__*/ false && ${match[0]}`)
}
}
if (!parseQuery(search).macro) {
return originalCode === code ? undefined : code
return s.toRollupResult()
}
// [webpack] Re-export any imports from script blocks in the components
@ -37,33 +38,39 @@ export const TransformMacroPlugin = createUnplugin((options: TransformMacroPlugi
const scriptImport = findStaticImports(code).find(i => parseQuery(i.specifier.replace('?macro=true', '')).type === 'script')
if (scriptImport) {
const specifier = withQuery(scriptImport.specifier.replace('?macro=true', ''), { macro: 'true' })
return `export { meta } from "${specifier}"`
s.overwrite(0, code.length, `export { meta } from "${specifier}"`)
return s.toRollupResult()
}
const currentExports = findExports(code)
for (const match of currentExports) {
if (match.type !== 'default') { continue }
if (match.type !== 'default') {
continue
}
if (match.specifier && match._type === 'named') {
// [webpack] Export named exports rather than the default (component)
return code.replace(match.code, `export {${Object.values(options.macros).join(', ')}} from "${match.specifier}"`)
s.overwrite(match.start, match.end, `export {${Object.values(options.macros).join(', ')}} from "${match.specifier}"`)
return s.toRollupResult()
} else if (!options.dev) {
// ensure we tree-shake any _other_ default exports out of the macro script
code = code.replace(match.code, '/*#__PURE__*/ false &&')
code += '\nexport default {}'
s.overwrite(match.start, match.end, '/*#__PURE__*/ false &&')
s.append('\nexport default {}')
}
}
for (const macro in options.macros) {
// Skip already-processed macros
if (currentExports.some(e => e.name === options.macros[macro])) { continue }
if (currentExports.some(e => e.name === options.macros[macro])) {
continue
}
const { 0: match, index = 0 } = code.match(new RegExp(`\\b${macro}\\s*\\(\\s*`)) || {} as RegExpMatchArray
const macroContent = match ? extractObject(code.slice(index + match.length)) : 'undefined'
code += `\nexport const ${options.macros[macro]} = ${macroContent}`
s.append(`\nexport const ${options.macros[macro]} = ${macroContent}`)
}
return code
return s.toRollupResult()
}
}
})