Skip to content

Commit

Permalink
feat: 支持输入为 class 时,标记外部组件
Browse files Browse the repository at this point in the history
  • Loading branch information
meixg committed Dec 3, 2021
1 parent f12876a commit 0537911
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 3 deletions.
38 changes: 38 additions & 0 deletions src/helpers/markExternalComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import Module from 'module'
import { ComponentReference } from '../models/component-reference'

export const COMPONENT_REFERENCE = Symbol('component-reference')

export function markExternalComponent (options: {isExternalComponent: (id: string, currentFilename: string) => boolean}) {
const { isExternalComponent } = options
const originRequire = Module.prototype.require
Module.prototype.require = Object.assign(function (this: Module, id: string) {
const currentFilename = this.filename

if (isExternalComponent(id, currentFilename)) {
return new Proxy({}, {
get (target, p) {
if (p === COMPONENT_REFERENCE) {
return new ComponentReference(id, 'default')
}

return {
[COMPONENT_REFERENCE]: new ComponentReference(id, p as string)
}
}
})
}

return originRequire.call(this, id)
}, originRequire)
}

// markExternalComponent({
// isExternalComponent () {
// return true
// }
// })

// const a = require('aaa')
// const { b } = require('bbb')
// console.log(a, b)
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export { _ } from './runtime/underscore'
export { SyntaxKind } from './ast/renderer-ast-dfn'
export type { Expression, Statement, FunctionDefinition, VariableDefinition, Literal, MapLiteral, ArrayLiteral, UnaryExpression, Foreach, BinaryExpression, SlotRendererDefinition, SlotRenderCall } from './ast/renderer-ast-dfn'
export { assertNever } from './utils/lang'
export { markExternalComponent } from './helpers/markExternalComponent'

// class types
export { SanSourceFile, TypedSanSourceFile, DynamicSanSourceFile, isTypedSanSourceFile } from './models/san-source-file'
Expand Down
22 changes: 19 additions & 3 deletions src/parsers/component-class-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getMember } from '../utils/lang'
import { isComponentLoader, ComponentClass } from '../models/component'
import { parseAndNormalizeTemplate } from './parse-template'
import { componentID, DynamicComponentReference } from '../models/component-reference'
import { COMPONENT_REFERENCE } from '../helpers/markExternalComponent'

/*
* ComponentClass 解析器
Expand All @@ -29,8 +30,9 @@ export class ComponentClassParser {

parse (): DynamicSanSourceFile {
const componentInfos = []
const rootId = getMember(this.root, 'id')
const stack: DynamicComponentReference[] = [
new DynamicComponentReference('.', '' + this.id++, this.root)
new DynamicComponentReference('.', typeof rootId === 'string' ? rootId : '' + this.id++, this.root)
]
const parsed = new Set()
while (stack.length) {
Expand All @@ -41,7 +43,11 @@ export class ComponentClassParser {
const info = this.createComponentInfoFromComponentClass(componentClass, id)
// 先序遍历,结果列表中第一个为根
componentInfos.push(info)
for (const child of info.childComponents.values()) stack.push(child)
for (const child of info.childComponents.values()) {
if (child.specifier === '.') {
stack.push(child)
}
}
}
return new DynamicSanSourceFile(componentInfos, this.filePath, componentInfos[0])
}
Expand Down Expand Up @@ -85,6 +91,13 @@ export class ComponentClassParser {
))
continue
}

// 外部组件
if (componentClass[COMPONENT_REFERENCE]) {
children.set(tagName, componentClass[COMPONENT_REFERENCE])
continue
}

// 可能是空,例如 var Foo = defineComponent({components: {foo: Foo}})
children.set(tagName, new DynamicComponentReference(
'.',
Expand All @@ -100,7 +113,10 @@ export class ComponentClassParser {
* 因此生成一个递增的 id 来标识它。
*/
private getOrSetID (componentClass: ComponentConstructor<{}, {}>): string {
if (!this.cids.has(componentClass)) this.cids.set(componentClass, String(this.id++))
if (!this.cids.has(componentClass)) {
const id = getMember(componentClass, 'id')
this.cids.set(componentClass, typeof id === 'string' ? id : String(this.id++))
}
return this.cids.get(componentClass)!
}
}

0 comments on commit 0537911

Please sign in to comment.