diff --git a/packages/uni-cli-shared/package.json b/packages/uni-cli-shared/package.json
index c5ebc7d577fa99d5e3d3fd75e2cc4a56fcd7e58e..17577cd4566fb6cefdf8986dc3134fc1e9361c5d 100644
--- a/packages/uni-cli-shared/package.json
+++ b/packages/uni-cli-shared/package.json
@@ -19,6 +19,8 @@
"url": "https://github.com/dcloudio/uni-app/issues"
},
"dependencies": {
+ "@babel/parser": "^7.15.0",
+ "@babel/types": "^7.15.0",
"@rollup/pluginutils": "^4.1.1",
"chokidar": "^3.5.2",
"compare-versions": "^3.6.0",
diff --git a/packages/uni-cli-shared/src/mp/imports.ts b/packages/uni-cli-shared/src/mp/imports.ts
index 84523d2c99c28892ecf558765975dcd7d884e657..07f535d05d64bfe0b3abf2d3d8db13d176862a2b 100644
--- a/packages/uni-cli-shared/src/mp/imports.ts
+++ b/packages/uni-cli-shared/src/mp/imports.ts
@@ -2,6 +2,8 @@ import path from 'path'
import { PluginContext } from 'rollup'
import { init, parse as parseImports, ImportSpecifier } from 'es-module-lexer'
import { extend } from '@vue/shared'
+import { isImportDeclaration, isImportDefaultSpecifier } from '@babel/types'
+import { parse } from '@babel/parser'
import { EXTNAME_VUE, EXTNAME_VUE_RE } from '../constants'
export async function findVueComponentImports(
@@ -24,7 +26,7 @@ export async function findVueComponentImports(
return []
}
- const rewriteImports: ImportSpecifier[] = []
+ const rewriteImports: (ImportSpecifier & { i: string })[] = []
for (let i = 0; i < imports.length; i++) {
const importSpecifier = imports[i]
const { n } = importSpecifier
@@ -41,7 +43,21 @@ export async function findVueComponentImports(
continue
}
if (EXTNAME_VUE_RE.test(res.id)) {
- rewriteImports.push(extend(importSpecifier, { n: res.id }))
+ const expr = parse(source.slice(importSpecifier.ss, importSpecifier.se), {
+ sourceType: 'module',
+ }).program.body[0]
+ if (isImportDeclaration(expr) && expr.specifiers.length === 1) {
+ const importDefaultSpecifier = expr.specifiers[0]
+ if (!isImportDefaultSpecifier(importDefaultSpecifier)) {
+ continue
+ }
+ rewriteImports.push(
+ extend(importSpecifier, {
+ n: res.id,
+ i: importDefaultSpecifier.local.name,
+ })
+ )
+ }
}
}
return rewriteImports
diff --git a/packages/uni-mp-compiler/__tests__/transformElement.spec.ts b/packages/uni-mp-compiler/__tests__/transformElement.spec.ts
index 617f8a1def2d02a4670464d1f7d9c384141fa4ed..e0072a968e3b302094e30c57c44b3cdd65bd7be7 100644
--- a/packages/uni-mp-compiler/__tests__/transformElement.spec.ts
+++ b/packages/uni-mp-compiler/__tests__/transformElement.spec.ts
@@ -25,11 +25,11 @@ function parseWithElementTransform(
describe('compiler: element transform', () => {
test('import + resolve component', () => {
- const { root, code } = parseWithElementTransform(``)
+ const { root } = parseWithElementTransform(``)
expect((root as CodegenRootNode).bindingComponents).toEqual({
Foo: { name: '_component_Foo', type: BindingComponentTypes.UNKNOWN },
})
- expect(code).toContain(`if (!Math) {Math.max.call(Max, _component_Foo)}`)
+ // expect(code).toContain(`if (!Math) {Math.max.call(Max, _component_Foo)}`)
})
test('import + resolve component multi', () => {
@@ -48,21 +48,16 @@ describe('compiler: element transform', () => {
Example: { name: '$setup["Example"]', type: BindingComponentTypes.SETUP },
Test: { name: '_component_Test', type: BindingComponentTypes.SELF },
})
- expect(code).toContain(
- `if (!Math) {Math.max.call(Max, _component_Foo, _component_Bar, $setup["Example"], _component_Test)}`
- )
+ expect(code).toContain(`if (!Math) {Math.max.call(Max, $setup["Example"])}`)
})
test('resolve implcitly self-referencing component', () => {
- const { root, code } = parseWithElementTransform(``, {
+ const { root } = parseWithElementTransform(``, {
filename: `/foo/bar/Example.vue?vue&type=template`,
})
expect((root as CodegenRootNode).bindingComponents).toEqual({
Example: { name: '_component_Example', type: BindingComponentTypes.SELF },
})
- expect(code).toContain(
- `if (!Math) {Math.max.call(Max, _component_Example)}`
- )
})
test('resolve component from setup bindings', () => {
diff --git a/packages/uni-mp-compiler/src/codegen.ts b/packages/uni-mp-compiler/src/codegen.ts
index c08cdc4f4f529faa7cbf45ddd01b5406c7103edd..d029b140adadc398d2306d3330cd681eab84daa6 100644
--- a/packages/uni-mp-compiler/src/codegen.ts
+++ b/packages/uni-mp-compiler/src/codegen.ts
@@ -151,25 +151,21 @@ function genComponentImports(
{ push }: CodegenContext
) {
const importDeclarations: string[] = []
+ // 仅记录easycom和setup组件
+ const components: string[] = []
Object.keys(bindingComponents).forEach((tag) => {
const { name, type } = bindingComponents[tag]
if (type === BindingComponentTypes.UNKNOWN) {
const source = matchEasycom(tag)
if (source) {
+ components.push(name)
addImportDeclaration(importDeclarations, name, source)
}
+ } else if (type === BindingComponentTypes.SETUP) {
+ components.push(name)
}
})
importDeclarations.forEach((str) => push(str))
-}
-
-function genComponents(
- bindingComponents: TransformContext['bindingComponents'],
- { push }: CodegenContext
-) {
- const components = Object.keys(bindingComponents).map(
- (tag) => bindingComponents[tag].name
- )
if (components.length) {
push(`if (!Math) {`)
push(`Math.max.call(Max, ${components.map((name) => name).join(', ')})`)
@@ -197,7 +193,6 @@ function genFunctionPreamble(ast: RootNode, context: CodegenContext) {
}
}
genComponentImports(bindingComponents, context)
- genComponents(bindingComponents, context)
newline()
push(`return `)
}
@@ -216,7 +211,6 @@ function genModulePreamble(
)
}
genComponentImports(bindingComponents, context)
- genComponents(bindingComponents, context)
newline()
if (!inline) {
push(`export `)
diff --git a/packages/uni-mp-vite/src/plugins/component.ts b/packages/uni-mp-vite/src/plugins/component.ts
index 3bf13f409c25125cffa9177d601a566d493ca022..79d706ed418a1634b78d6a3e5cab1eebfaf5b510 100644
--- a/packages/uni-mp-vite/src/plugins/component.ts
+++ b/packages/uni-mp-vite/src/plugins/component.ts
@@ -29,11 +29,13 @@ export function uniComponentPlugin(): Plugin {
}
const s = new MagicString(code)
const rewriteImports: string[] = []
- vueComponentImports.forEach(({ n, ss, se }) => {
+ vueComponentImports.forEach(({ n, ss, se, i }) => {
s.remove(ss, se)
- rewriteImports.push(`import('${virtualComponentPath(n!)}')`)
+ rewriteImports.push(
+ `const ${i} = ()=>import('${virtualComponentPath(n!)}')`
+ )
})
- s.prepend(`if(!Math){${rewriteImports.join(';')}}`)
+ s.prepend(rewriteImports.join(';') + ';\n')
return s.toString()
},
}