Skip to content

Commit

Permalink
chore: 考虑plugin-vue:export-helper
Browse files Browse the repository at this point in the history
  • Loading branch information
acyza committed May 22, 2024
1 parent 60bcea4 commit df5923d
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 86 deletions.
70 changes: 48 additions & 22 deletions packages/uni-cli-shared/__tests__/usingComponents.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,9 +301,10 @@ export function createApp() {
`const _easycom_test = ()=>import('${inputDir}/components/test/test.vue')`
)
})
test(`recursion`, async () => {
await testLocal(
`
describe(`recursion`, () => {
test('base', async () => {
await testLocal(
`
const _sfc_main = {
};
const __BINDING_COMPONENTS__ = '{"index":{"name":"_component_index","type":"unknown"}}';
Expand All @@ -314,14 +315,16 @@ export function createApp() {
import _export_sfc from "plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
`,
{
index: '/pages/index/index',
},
``
)
{
index: '/pages/index/index',
},
``
)
})

await testLocal(
`import { defineComponent as _defineComponent } from "vue";
test('use defineComponent', async () => {
await testLocal(
`import { defineComponent as _defineComponent } from "vue";
const __BINDING_COMPONENTS__ = '{"test":{"name":"test","type":"unknown"}}';
export default /* @__PURE__ */ _defineComponent({
Expand All @@ -334,14 +337,16 @@ export function createApp() {
});
import "${inputDir}/pages/index/index.vue?vue&type=style&index=0&lang.css";
`,
{
test: '/pages/index/index',
},
``
)
{
test: '/pages/index/index',
},
``
)
})

await testLocal(
`import { defineComponent as _defineComponent } from "vue";
test('export variable', async () => {
await testLocal(
`import { defineComponent as _defineComponent } from "vue";
const __BINDING_COMPONENTS__ = '{"test":{"name":"test","type":"unknown"}}';
const component = _defineComponent({
__name: "test",
Expand All @@ -356,11 +361,32 @@ export function createApp() {
import "${inputDir}/pages/index/index.vue?vue&type=style&index=0&lang.css";
`,
{
test: '/pages/index/index',
},
``
)
{
test: '/pages/index/index',
},
``
)
})
test('use plugin-vue:export-helper', async () => {
await testLocal(
`
const _sfc_main = {
__name: 'Test'
};
const __BINDING_COMPONENTS__ = '{"test":{"name":"_component_test","type":"unknown"}}';
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return {};
}
import "${filename}?vue&type=style&index=0&lang.css";
import _export_sfc from "plugin-vue:export-helper";
export default /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
`,
{
test: '/pages/index/index',
},
``
)
})
})
})
})
150 changes: 86 additions & 64 deletions packages/uni-cli-shared/src/mp/usingComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {
type Statement,
type StringLiteral,
assertExportDefaultDeclaration,
assertIdentifier,
isBlockStatement,
isCallExpression,
isExportDefaultDeclaration,
isExpression,
isIdentifier,
isIfStatement,
isImportDeclaration,
isImportDefaultSpecifier,
isImportSpecifier,
isMemberExpression,
isObjectExpression,
Expand Down Expand Up @@ -197,87 +198,108 @@ export async function updateMiniProgramGlobalComponents(
}

function parseVueComponentName(filename: string) {
let name = path.basename(removeExt(filename))
try {
let name = path.basename(removeExt(filename))

const ast = scriptDescriptors.get(filename)?.ast
if (!ast) return name
const ast = scriptDescriptors.get(filename)?.ast
if (!ast) return name

// 获取默认导出定义
const exportDefaultDecliaration = ast.body.find((node) =>
isExportDefaultDeclaration(node)
)
// 获取默认导出定义
const exportDefaultDecliaration = ast.body.find((node) =>
isExportDefaultDeclaration(node)
)

assertExportDefaultDeclaration(exportDefaultDecliaration)
assertExportDefaultDeclaration(exportDefaultDecliaration)

if (!exportDefaultDecliaration) return name
if (!exportDefaultDecliaration) return name

// 获取vue的defineComponent导入变量名
let defineComponentLocalName: string | null = null
// 获取vue的defineComponent导入变量名和plugin-vue:export-helper默认导入的本地变量名
let defineComponentLocalName: string | null = null
let exportHelperLocalName: string | null = null

for (const node of ast.body) {
if (
isImportDeclaration(node) &&
isStringLiteral(node.source, { value: 'vue' })
) {
const importSpecifer = node.specifiers.find(
(specifer) =>
isImportSpecifier(specifer) &&
isIdentifier(specifer.imported, { name: 'defineComponent' })
)
if (isImportSpecifier(importSpecifer)) {
defineComponentLocalName = importSpecifer.local.name
for (const node of ast.body) {
if (!isImportDeclaration(node)) continue
if (isStringLiteral(node.source, { value: 'vue' })) {
const importSpecifer = node.specifiers.find(
(specifer) =>
isImportSpecifier(specifer) &&
isIdentifier(specifer.imported, { name: 'defineComponent' })
)
if (isImportSpecifier(importSpecifer)) {
defineComponentLocalName = importSpecifer.local.name
}
} else if (
isStringLiteral(node.source, { value: 'plugin-vue:export-helper' })
) {
const importSpecifer = node.specifiers.find((specifer) =>
isImportDefaultSpecifier(specifer)
)
if (isImportDefaultSpecifier(importSpecifer)) {
exportHelperLocalName = importSpecifer.local.name
}
}
}
}

// 获取组件定义对象
let defineComponentDeclaration: ObjectExpression | null = null

let { declaration } = exportDefaultDecliaration
let { declaration } = exportDefaultDecliaration
// 如果默认导出调用plugin-vue:export-helper默认导入的方法则取方法的第一个参数
if (
exportHelperLocalName &&
isCallExpression(declaration) &&
isIdentifier(declaration.callee, { name: exportHelperLocalName }) &&
isExpression(declaration.arguments[0])
) {
declaration = declaration.arguments[0]
}

// 如果默认导出了变量则尝试查找该变量
if (isIdentifier(declaration)) {
const { name } = declaration
for (const node of ast.body) {
if (isVariableDeclaration(node)) {
assertIdentifier(declaration)
const declarator = node.declarations.find((declarator) =>
isIdentifier(declarator.id, { name })
)
if (declarator?.init) {
declaration = declarator.init
// 获取组件定义对象
let defineComponentDeclaration: ObjectExpression | null = null

// 如果declaration是变量则尝试查找该变量
if (isIdentifier(declaration)) {
const { name } = declaration
for (const node of ast.body) {
if (isVariableDeclaration(node)) {
const declarator = node.declarations.find((declarator) =>
isIdentifier(declarator.id, { name })
)
if (declarator?.init) {
declaration = declarator.init
}
} else if (isExportDefaultDeclaration(node)) {
break
}
} else if (isExportDefaultDeclaration(node)) {
break
}
}
}

if (isObjectExpression(declaration)) {
defineComponentDeclaration = declaration
} else if (
defineComponentLocalName &&
isCallExpression(declaration) &&
isIdentifier(declaration.callee, { name: defineComponentLocalName }) &&
isObjectExpression(declaration.arguments[0])
) {
defineComponentDeclaration = declaration.arguments[0]
}
if (isObjectExpression(declaration)) {
defineComponentDeclaration = declaration
} else if (
defineComponentLocalName &&
isCallExpression(declaration) &&
isIdentifier(declaration.callee, { name: defineComponentLocalName }) &&
isObjectExpression(declaration.arguments[0])
) {
defineComponentDeclaration = declaration.arguments[0]
}

if (!defineComponentDeclaration) return name
if (!defineComponentDeclaration) return name

// 尝试从组件定义对象中获取组件名
for (const prop of defineComponentDeclaration.properties) {
if (
isObjectProperty(prop) &&
isIdentifier(prop.key) &&
/(__)?name/.test(prop.key.name) &&
isStringLiteral(prop.value)
) {
return prop.value.value
// 尝试从组件定义对象中获取组件名
for (const prop of defineComponentDeclaration.properties) {
if (
isObjectProperty(prop) &&
isIdentifier(prop.key) &&
/(__)?name/.test(prop.key.name) &&
isStringLiteral(prop.value)
) {
return prop.value.value || name
}
}
return name
} catch (e) {
console.log(e)
return ''
}
return name
}

function createUsingComponents(
Expand Down

0 comments on commit df5923d

Please sign in to comment.