Skip to content

Commit

Permalink
fix: get render start in vue 2 directive (#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
sxzz committed Sep 26, 2022
1 parent 6fa8415 commit abfe3b4
Showing 1 changed file with 13 additions and 8 deletions.
21 changes: 13 additions & 8 deletions src/core/transforms/directive/vue2.ts
@@ -1,8 +1,7 @@
import type {
BlockStatement, CallExpression, File, FunctionExpression, Node, ObjectProperty, VariableDeclaration,
BlockStatement, CallExpression, FunctionExpression, Node, ObjectProperty, Program, VariableDeclaration,
} from '@babel/types'
import type MagicString from 'magic-string'
import type { ParseResult } from '@babel/parser'
import { importModule, isPackageExists } from 'local-pkg'
import type { ResolveResult } from '../../transformer'

Expand All @@ -11,8 +10,8 @@ import type { ResolveResult } from '../../transformer'
* @param ast
* @returns
*/
const getRenderFnStart = (ast: ParseResult<File>): number => {
const renderFn = ast.program.body.find((node): node is VariableDeclaration =>
const getRenderFnStart = (program: Program): number => {
const renderFn = program.body.find((node): node is VariableDeclaration =>
node.type === 'VariableDeclaration'
&& node.declarations[0].id.type === 'Identifier'
&& ['render', '_sfc_render'].includes(node.declarations[0].id.name),
Expand All @@ -28,13 +27,13 @@ export default async function resolveVue2(code: string, s: MagicString): Promise
throw new Error('[unplugin-vue-components:directive] To use Vue 2 directive you will need to install Babel first: "npm install -D @babel/parser"')

const { parse } = await importModule<typeof import('@babel/parser')>('@babel/parser')
const ast = parse(code, {
const { program } = parse(code, {
sourceType: 'module',
})

const nodes: CallExpression[] = []
const { walk } = await import('estree-walker')
walk(ast.program as any, {
walk(program as any, {
enter(node: any) {
if ((node as Node).type === 'CallExpression')
nodes.push(node)
Expand All @@ -44,8 +43,14 @@ export default async function resolveVue2(code: string, s: MagicString): Promise
if (nodes.length === 0)
return []

let _renderStart: number | undefined
const getRenderStart = () => {
if (_renderStart !== undefined)
return _renderStart
return (_renderStart = getRenderFnStart(program))
}

const results: ResolveResult[] = []
const renderStart = getRenderFnStart(ast)
for (const node of nodes) {
const { callee, arguments: args } = node
// _c(_, {})
Expand Down Expand Up @@ -80,7 +85,7 @@ export default async function resolveVue2(code: string, s: MagicString): Promise
results.push({
rawName: name,
replace: (resolved) => {
s.prependLeft(renderStart!, `\nthis.$options.directives["${name}"] = ${resolved};`)
s.prependLeft(getRenderStart(), `\nthis.$options.directives["${name}"] = ${resolved};`)
},
})
}
Expand Down

0 comments on commit abfe3b4

Please sign in to comment.