Skip to content

Commit

Permalink
refactor: use compiler-sfc 3.3 genDefaultAs option to avoid rewriteDe…
Browse files Browse the repository at this point in the history
…fault
  • Loading branch information
yyx990803 committed Mar 30, 2023
1 parent 199f0cb commit 2c35a66
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 23 deletions.
45 changes: 24 additions & 21 deletions packages/plugin-vue/src/main.ts
Expand Up @@ -12,7 +12,12 @@ import {
getPrevDescriptor,
setSrcDescriptor,
} from './utils/descriptorCache'
import { isUseInlineTemplate, resolveScript } from './script'
import {
canInlineMain,
isUseInlineTemplate,
resolveScript,
scriptIdentifier,
} from './script'
import { transformTemplateInMain } from './template'
import { isEqualBlock, isOnlyTemplateChanged } from './handleHotUpdate'
import { createRollupError } from './utils/error'
Expand Down Expand Up @@ -303,33 +308,31 @@ async function genScriptCode(
code: string
map: RawSourceMap | undefined
}> {
let scriptCode = `const _sfc_main = {}`
let scriptCode = `const ${scriptIdentifier} = {}`
let map: RawSourceMap | undefined

const script = resolveScript(descriptor, options, ssr)
if (script) {
// If the script is js/ts and has no external src, it can be directly placed
// in the main module.
if (
(!script.lang || (script.lang === 'ts' && options.devServer)) &&
!script.src
) {
const userPlugins = options.script?.babelParserPlugins || []
const defaultPlugins =
script.lang === 'ts'
? userPlugins.includes('decorators')
? (['typescript'] as const)
: (['typescript', 'decorators-legacy'] as const)
: []
const as = '_sfc_main'
if (options.compiler.rewriteDefaultAST && script.scriptAst && script.s) {
options.compiler.rewriteDefaultAST(script.scriptAst, script.s, as)
scriptCode = script.s.toString()
if (canInlineMain(descriptor, options)) {
if (!options.compiler.version) {
// if compiler-sfc exposes no version, it's < 3.3 and doesn't support
// genDefaultAs option.
const userPlugins = options.script?.babelParserPlugins || []
const defaultPlugins =
script.lang === 'ts'
? userPlugins.includes('decorators')
? (['typescript'] as const)
: (['typescript', 'decorators-legacy'] as const)
: []
scriptCode = options.compiler.rewriteDefault(
script.content,
scriptIdentifier,
[...defaultPlugins, ...userPlugins],
)
} else {
scriptCode = options.compiler.rewriteDefault(script.content, as, [
...defaultPlugins,
...userPlugins,
])
scriptCode = script.content
}
map = script.map
} else {
Expand Down
24 changes: 24 additions & 0 deletions packages/plugin-vue/src/script.ts
Expand Up @@ -31,6 +31,8 @@ export function isUseInlineTemplate(
return isProd && !!descriptor.scriptSetup && !descriptor.template?.src
}

export const scriptIdentifier = `_sfc_main`

export function resolveScript(
descriptor: SFCDescriptor,
options: ResolvedOptions,
Expand All @@ -56,8 +58,30 @@ export function resolveScript(
reactivityTransform: options.reactivityTransform !== false,
templateOptions: resolveTemplateCompilerOptions(descriptor, options, ssr),
sourceMap: options.sourceMap,
genDefaultAs: canInlineMain(descriptor, options)
? scriptIdentifier
: undefined,
})

cacheToUse.set(descriptor, resolved)
return resolved
}

// If the script is js/ts and has no external src, it can be directly placed
// in the main module. Skip for build
export function canInlineMain(
descriptor: SFCDescriptor,
options: ResolvedOptions,
): boolean {
if (!options.devServer) {
return false
}
if (descriptor.script?.src || descriptor.scriptSetup?.src) {
return false
}
const lang = descriptor.script?.lang || descriptor.scriptSetup?.lang
if (lang && lang !== 'ts') {
return false
}
return true
}
7 changes: 5 additions & 2 deletions packages/plugin-vue/src/template.ts
Expand Up @@ -11,14 +11,17 @@ import { getResolvedScript } from './script'
import { createRollupError } from './utils/error'
import type { ResolvedOptions } from '.'

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export async function transformTemplateAsModule(
code: string,
descriptor: SFCDescriptor,
options: ResolvedOptions,
pluginContext: TransformPluginContext,
ssr: boolean,
) {
): Promise<{
code: string
map: any
}> {
const result = compile(code, descriptor, options, pluginContext, ssr)

let returnCode = result.code
Expand Down

0 comments on commit 2c35a66

Please sign in to comment.