Skip to content

Commit

Permalink
feat: support auto require entry component
Browse files Browse the repository at this point in the history
while using useProvidedComponentClass
  • Loading branch information
meixg committed Apr 1, 2022
1 parent b3426ab commit 2ca6c32
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/compilers/renderer-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class RendererCompiler {
body.push(new ImportHelper('SanSSRData'))

if (this.options.useProvidedComponentClass) {
body.push(DEF('ComponentClass', new BinaryExpression(I('info'), '.', I('ComponentClass'))))
body.push(DEF('ComponentClass', BINARY(I('info'), '.', I('ComponentClass'))))
body.push(STATEMENT(new CreateComponentPrototype(info)))
}

Expand Down
17 changes: 16 additions & 1 deletion src/compilers/renderer-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,24 @@ export interface RenderOptions {
functionName?: string
ssrOnly?: boolean
importHelpers?: string

/**
* 使用调用 render 时提供的组件类,编译产物中不再包含组件类
*/
useProvidedComponentClass?: boolean
useProvidedComponentClass?: boolean | {
/**
* 会在 render 函数中自动 require 该路径获取组件
*/
componentPath: string;

/**
* export 出的组件类名
* - undefined 或者空字符串:const componentClass = require(componentPath)
* - 非空字符串:const componentClass = require(componentPath)[componentName]
*/
componentName: string;
}

/**
* 删除 ssr 不需要引入的模块,仅对 TypedSanSourceFile 有效
*/
Expand All @@ -21,6 +35,7 @@ export interface RenderOptions {
moduleName?: string
className?: string
}

/**
* 不同 target 实现的 CompilerOptions 可以继承并扩充字段
*/
Expand Down
16 changes: 15 additions & 1 deletion src/target-js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,26 @@ export default class ToJSCompiler implements TargetCodeGenerator {
else if (isJSSanSourceFile(sourceFile)) this.compileJSComponentToSource(sourceFile, emitter)
// DynamicSanSourceFile
else this.compileComponentClassToSource(sourceFile, emitter)
} else if (typeof options.useProvidedComponentClass === 'object') {
const { componentPath, componentName } = options.useProvidedComponentClass
emitter.nextLine(
'sanSSRResolver.setPrototype(' +
`"${sourceFile.entryComponentInfo!.id}", ` +
'sanSSRHelpers._.createInstanceFromClass(' +
`require('${componentPath}')` +
`${componentName ? '.' + componentName : ''}` +
')' +
');')
}

// 编译 render 函数
for (const info of sourceFile.componentInfos) {
emitter.nextLine(`sanSSRResolver.setRenderer("${info.id}", `)
emitter.writeFunctionDefinition(this.optimize(info.compileToRenderer(options)))
emitter.writeFunctionDefinition(
this.optimize(
info.compileToRenderer(options)
)
)
emitter.feedLine(');')
}

Expand Down
44 changes: 44 additions & 0 deletions test/cases/provide-class-auto-with-name/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const san = require('san')
const List = san.defineComponent({
initData () {
return {
text: 'child'
}
},
template: '<div>{{ text }}</div>'
})

const CompA = san.defineComponent({
initData () {
return {
text: 'component a'
}
},
template: '<div>{{ text }}</div>'
})

const MyComponent = san.defineComponent({
components: {
'x-l': List,
'x-g': san.createComponentLoader({
load: () => {
return List
},
placeholder: CompA
})
},
initData () {
return {
c: 'x-l'
}
},
trimWhitespace: 'all',
template: `<div>
<div s-is="c"></div>
<x-l/>
<x-g/>
</div>`
})

exports = module.exports = MyComponent
exports.MyComponent = MyComponent
2 changes: 2 additions & 0 deletions test/cases/provide-class-auto-with-name/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
1 change: 1 addition & 0 deletions test/cases/provide-class-auto-with-name/expected.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div><!--s-data:{"c": "x-l"}--><div>child</div><div>child</div><div>component a</div></div>
15 changes: 15 additions & 0 deletions test/cases/provide-class-auto-with-name/ssr-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { SsrSpecConfig } from '../../e2e.spec'

export default {
enabled: {
jssrc: false,
comsrc: true,
comrdr: false
},
compileOptions: {
useProvidedComponentClass: {
componentPath: '../../component.js',
componentName: 'MyComponent'
}
}
} as SsrSpecConfig
44 changes: 44 additions & 0 deletions test/cases/provide-class-auto/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const san = require('san')
const List = san.defineComponent({
initData () {
return {
text: 'child'
}
},
template: '<div>{{ text }}</div>'
})

const CompA = san.defineComponent({
initData () {
return {
text: 'component a'
}
},
template: '<div>{{ text }}</div>'
})

const MyComponent = san.defineComponent({
components: {
'x-l': List,
'x-g': san.createComponentLoader({
load: () => {
return List
},
placeholder: CompA
})
},
initData () {
return {
c: 'x-l'
}
},
trimWhitespace: 'all',
template: `<div>
<div s-is="c"></div>
<x-l/>
<x-g/>
</div>`
})

exports = module.exports = MyComponent
exports.MyComponent = MyComponent
2 changes: 2 additions & 0 deletions test/cases/provide-class-auto/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{
}
1 change: 1 addition & 0 deletions test/cases/provide-class-auto/expected.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div><!--s-data:{"c": "x-l"}--><div>child</div><div>child</div><div>component a</div></div>
14 changes: 14 additions & 0 deletions test/cases/provide-class-auto/ssr-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { SsrSpecConfig } from '../../e2e.spec'

export default {
enabled: {
jssrc: false,
comsrc: true,
comrdr: false
},
compileOptions: {
useProvidedComponentClass: {
componentPath: '../../component.js'
}
}
} as SsrSpecConfig

0 comments on commit 2ca6c32

Please sign in to comment.