From bf091b4654615139c5c384aad9d0a359e6fa54a2 Mon Sep 17 00:00:00 2001 From: meixg Date: Mon, 9 May 2022 19:08:29 +0800 Subject: [PATCH] feat: add cache to getRenderer and getChildComponentClass --- bin/debug-local.js | 10 +++++----- src/runtime/resolver.ts | 27 ++++++++++++++++++++++++++ test/cases/provide-class/component.js | 13 ++++++++++++- test/cases/provide-class/expected.html | 2 +- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/bin/debug-local.js b/bin/debug-local.js index 64f296e4..c6e98cf7 100644 --- a/bin/debug-local.js +++ b/bin/debug-local.js @@ -15,7 +15,7 @@ function compile (componentPath, externalPath, outputPath) { const MyComponent = require(componentPath) const sanProject = new SanProject() const res = sanProject.compileToSource(MyComponent, 'js', { - // useProvidedComponentClass: true + useProvidedComponentClass: true }) cancelMarkExternalComponent() @@ -24,13 +24,13 @@ function compile (componentPath, externalPath, outputPath) { } compile('./sample/component', './component2', './dist/component.js') -// compile('./component2', './component', './dist/component2') +compile('./sample/component2', './component', './dist/component2.js') // // online -// const Component = require('./component') +const Component = require('./sample/component') const render = require('./dist/component') -const html = render({}) -// const html = render({}, { ComponentClass: Component }) +// const html = render({}) +const html = render({}, { ComponentClass: Component }) console.log(html) diff --git a/src/runtime/resolver.ts b/src/runtime/resolver.ts index ebcff0cf..701d320c 100644 --- a/src/runtime/resolver.ts +++ b/src/runtime/resolver.ts @@ -37,9 +37,17 @@ export interface Resolver { type nodeRequire = typeof require; export function createResolver (exports: {[key: string]: any}, require: nodeRequire): Resolver { + const renderCache = {} as {[key: string]: Function} return { getRenderer: function ({ id, specifier = '.' }, tagName, context) { const customSSRFilePath = context && context.customSSRFilePath + const cacheKey = id + ' ' + specifier + + // 没有自定义时,尝试缓存 + if (!customSSRFilePath && renderCache[cacheKey]) { + return renderCache[cacheKey] + } + let mod: {[key: string]: any} if (specifier === '.') { mod = exports @@ -50,10 +58,26 @@ export function createResolver (exports: {[key: string]: any}, require: nodeRequ } mod = require(path || specifier) } + + if (!customSSRFilePath) { + renderCache[cacheKey] = mod.sanSSRRenders[id] + } + return mod.sanSSRRenders[id] }, getChildComponentClass: function ({ id, specifier = '.' }, instance: Component, tagName: string, context) { const customComponentFilePath = context && context.customComponentFilePath + const pro = Object.getPrototypeOf(instance) + if (!pro.__componentClassCache) { + pro.__componentClassCache = {} + } + const componentClassCache = pro.__componentClassCache as {[key: string]: Component} + const cacheKey = tagName + + // 没有自定义时,尝试缓存 + if (!customComponentFilePath && componentClassCache[cacheKey]) { + return componentClassCache[cacheKey] + } if (customComponentFilePath && specifier !== '.') { const path = customComponentFilePath({ id, specifier, tagName }) @@ -69,6 +93,7 @@ export function createResolver (exports: {[key: string]: any}, require: nodeRequ throw Error(`child component is not fount: ${tagName}${instance.prototype?.id || ''}`) } if (typeof ChildComponentClassOrInstance === 'string' && ChildComponentClassOrInstance === 'self') { + componentClassCache[cacheKey] = instance return instance } // component loader @@ -76,6 +101,7 @@ export function createResolver (exports: {[key: string]: any}, require: nodeRequ Object.prototype.hasOwnProperty.call(ChildComponentClassOrInstance, 'load') && Object.prototype.hasOwnProperty.call(ChildComponentClassOrInstance, 'placeholder') ) { + componentClassCache[cacheKey] = ChildComponentClassOrInstance.placeholder return ChildComponentClassOrInstance.placeholder } if ( @@ -84,6 +110,7 @@ export function createResolver (exports: {[key: string]: any}, require: nodeRequ ) { throw Error(`external component is not provided: ${tagName}${instance.prototype?.id || ''}`) } + componentClassCache[cacheKey] = ChildComponentClassOrInstance return ChildComponentClassOrInstance }, setRenderer: function (id: string, fn: Function) { diff --git a/test/cases/provide-class/component.js b/test/cases/provide-class/component.js index 58e68084..a00f0a77 100644 --- a/test/cases/provide-class/component.js +++ b/test/cases/provide-class/component.js @@ -8,13 +8,24 @@ const List = san.defineComponent({ template: '
{{ text }}
' }) +const CompB = san.defineComponent({ + initData () { + return { + text: 'comp b' + } + }, + template: '
{{ text }}
' +}) const CompA = san.defineComponent({ + components: { + 'x-l': CompB + }, initData () { return { text: 'component a' } }, - template: '
{{ text }}
' + template: '
{{ text }}
' }) const MyComponent = san.defineComponent({ diff --git a/test/cases/provide-class/expected.html b/test/cases/provide-class/expected.html index f4cd82b2..84d3991f 100644 --- a/test/cases/provide-class/expected.html +++ b/test/cases/provide-class/expected.html @@ -1 +1 @@ -
child
child
component a
\ No newline at end of file +
child
child
component a
comp b
\ No newline at end of file