Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat]feat-dynamic #1255

Merged
merged 50 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
0bf2108
[feat]feat-dynamic
CommanderXL Aug 22, 2023
0e2203f
[refactor]优化构建流程&解释器
CommanderXL Sep 6, 2023
d41a5a6
[merge]merge from master
CommanderXL Sep 6, 2023
ec2734b
[chore]add some comments
CommanderXL Sep 6, 2023
41bd2e8
[merge]merge from master
CommanderXL Sep 8, 2023
f08fe50
[merge]merge 2.9
CommanderXL Jan 24, 2024
d706487
Merge branch 'master' into feat-dynamic
CommanderXL Jan 29, 2024
b4091f9
[update]支持自定义组件
CommanderXL Feb 5, 2024
597967b
[merge]merge from remote
CommanderXL Feb 5, 2024
f33bce4
[update]add style scope feature
CommanderXL Feb 5, 2024
f7a81eb
fix: ali support
mater1996 Feb 20, 2024
f948d70
[update]样式隔离优化
CommanderXL Feb 27, 2024
67f9e6f
Merge branch 'master' into feat-dynamic
CommanderXL Feb 27, 2024
2f34dc7
[update]处理mpx-custom-element动态注入组件逻辑
CommanderXL Feb 27, 2024
7367296
fix: ali support
mater1996 Feb 27, 2024
c64d241
[fix]列表循环数据污染问题
CommanderXL Feb 27, 2024
d149544
[update]自定义组件渲染优化
CommanderXL Mar 6, 2024
ef5556e
[update]clear code
CommanderXL Mar 12, 2024
2f5a80b
Merge branch 'master' into feat-dynamic
CommanderXL Mar 12, 2024
45c6da5
[fix]fix reactive data diff
CommanderXL Mar 12, 2024
52e7ffc
fix: 收集compoent优化
mater1996 Mar 14, 2024
4b097a8
fix: postProcessRuntime top
mater1996 Mar 14, 2024
880323a
fix: 优化buildTemplate
mater1996 Mar 14, 2024
9bcf15c
refactor: 优化查找runtimeComponent tag逻辑
mater1996 Mar 15, 2024
8289f92
fix: conflict
mater1996 Mar 15, 2024
1165e4f
Merge pull request #2 from CommanderXL/feature/ali-support
CommanderXL Mar 15, 2024
ec830dd
[optimize]优化编译产出ast node体积
CommanderXL Mar 18, 2024
33661a6
Merge branch 'feat-dynamic' of github.com:CommanderXL/mpx into feat-d…
CommanderXL Mar 18, 2024
b2fd0c3
[chore]fix lint
CommanderXL Mar 19, 2024
1e8d328
[optimize]parse exps types
CommanderXL Mar 21, 2024
8579f1b
feat: static view + default block node
mater1996 Mar 21, 2024
d87faa5
fix: comment
mater1996 Mar 21, 2024
865836b
feat: 只支持类选择器
mater1996 Mar 22, 2024
7fe2ca8
Merge branch 'feat-dynamic' into feat-class-selector
mater1996 Mar 22, 2024
f9e9117
feat: minisize
mater1996 Apr 1, 2024
f299b5c
[optimize]some code
CommanderXL Apr 1, 2024
19d9324
feat: minisize
mater1996 Apr 2, 2024
f8630df
fix: remove console
mater1996 Apr 2, 2024
18e9455
fix: revert
mater1996 Apr 2, 2024
c4f50fe
fix: revert
mater1996 Apr 2, 2024
4541171
fix: remove node minisize
mater1996 Apr 7, 2024
bad7e91
fix: foamt
mater1996 Apr 7, 2024
815dcff
fix: remove render.old
mater1996 Apr 7, 2024
27d3da1
[optimize]优化体积&支持属性单值写法
CommanderXL Apr 9, 2024
f50d626
[fix]lint
CommanderXL Apr 9, 2024
468ddbe
[optimize]暂时去掉 mpxAttrs 大对象属性,目前使用不到
CommanderXL Apr 9, 2024
611ff78
[update]optimize some code
CommanderXL Apr 17, 2024
f7d5b88
Merge pull request #3 from CommanderXL/feature/ali-support
CommanderXL Apr 17, 2024
f9a1fe7
fix: conflict
mater1996 Apr 17, 2024
3ca7b38
Merge pull request #5 from CommanderXL/feat-minisize
CommanderXL Apr 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions packages/core/src/core/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
ONHIDE,
ONRESIZE
} from './innerLifecycle'
import contextMap from '../vnode/context'

let uid = 0

Expand Down Expand Up @@ -129,6 +130,8 @@ export default class MpxProxy {
}

created () {
// 缓存上下文,在 destoryed 阶段删除
contextMap.set(this.uid, this.target)
if (__mpx_mode__ !== 'web') {
// web中BEFORECREATE钩子通过vue的beforeCreate钩子单独驱动
this.callHook(BEFORECREATE)
Expand Down Expand Up @@ -188,6 +191,8 @@ export default class MpxProxy {
}

unmounted () {
// 页面/组件销毁清除上下文的缓存
contextMap.remove(this.uid)
this.callHook(BEFOREUNMOUNT)
this.scope?.stop()
if (this.update) this.update.active = false
Expand Down Expand Up @@ -377,7 +382,10 @@ export default class MpxProxy {
this.doRender(this.processRenderDataWithStrictDiff(renderData))
}

renderWithData (skipPre) {
renderWithData (skipPre, vnode) {
if (vnode) {
return this.doRenderWithVNode(vnode)
}
const renderData = skipPre ? this.renderData : preProcessRenderData(this.renderData)
this.doRender(this.processRenderDataWithStrictDiff(renderData))
// 重置renderData准备下次收集
Expand Down Expand Up @@ -476,6 +484,25 @@ export default class MpxProxy {
return result
}

doRenderWithVNode (vnode) {
if (!this._vnode) {
this.target.__render({ r: vnode })
} else {
let diffPath = diffAndCloneA(vnode, this._vnode).diffData
if (!isEmptyObject(diffPath)) {
// 构造 diffPath 数据
diffPath = Object.keys(diffPath).reduce((preVal, curVal) => {
const key = 'r' + curVal
preVal[key] = diffPath[curVal]
return preVal
}, {})
this.target.__render(diffPath)
}
}
// 缓存本地的 vnode 用以下一次 diff
this._vnode = diffAndCloneA(vnode).clone
}

doRender (data, cb) {
if (typeof this.target.__render !== 'function') {
error('Please specify a [__render] function to render view.', this.options.mpxFileResource)
Expand Down Expand Up @@ -543,15 +570,22 @@ export default class MpxProxy {
const _c = this.target._c.bind(this.target)
const _r = this.target._r.bind(this.target)
const _sc = this.target._sc.bind(this.target)
const _g = this.target._g.bind(this.target)
const effect = this.effect = new ReactiveEffect(() => {
// pre render for props update
if (this.propsUpdatedFlag) {
this.updatePreRender()
}

// const ast = this.target.dynamicRender?.() || this.getTplAst(this.moduleId)

// if (ast) {
// return _r(_g(ast))
// }

if (this.target.__injectedRender) {
try {
return this.target.__injectedRender(_i, _c, _r, _sc)
return this.target.__injectedRender(_i, _c, _r, _sc, _g)
} catch (e) {
warn('Failed to execute render function, degrade to full-set-data mode.', this.options.mpxFileResource, e)
this.render()
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/platform/builtInMixins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import pageScrollMixin from './pageScrollMixin'
import componentGenericsMixin from './componentGenericsMixin'
import getTabBarMixin from './getTabBarMixin'
import pageRouteMixin from './pageRouteMixin'
import runtimeModulesMixin from './runtimeModulesMixin'

export default function getBuiltInMixins (options, type) {
let bulitInMixins = []
Expand Down Expand Up @@ -39,7 +40,8 @@ export default function getBuiltInMixins (options, type) {
bulitInMixins = bulitInMixins.concat([
renderHelperMixin(),
showMixin(type),
i18nMixin()
i18nMixin(),
runtimeModulesMixin()
])
}
}
Expand Down
15 changes: 12 additions & 3 deletions packages/core/src/platform/builtInMixins/proxyEventMixin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { setByPath, error, hasOwn, dash2hump } from '@mpxjs/utils'
import Mpx from '../../index'
import contextMap from '../../vnode/context'

const datasetReg = /^data-(.+)$/

Expand All @@ -16,6 +17,11 @@ function collectDataset (props) {
return dataset
}

function logCallbackNotFound (context, callbackName) {
const location = context.__mpxProxy && context.__mpxProxy.options.mpxFileResource
error(`Instance property [${callbackName}] is not function, please check.`, location)
}

export default function proxyEventMixin () {
const methods = {
__invoke ($event) {
Expand Down Expand Up @@ -48,6 +54,9 @@ export default function proxyEventMixin () {
}
const eventConfigs = target.dataset.eventconfigs || {}
const curEventConfig = eventConfigs[type] || eventConfigs[fallbackType] || []
// 如果有 mpxuid 说明是运行时组件,那么需要设置对应的上下文
const rootRuntimeContext = contextMap.get(target.dataset.mpxuid)
const context = rootRuntimeContext || this
let returnedValue
curEventConfig.forEach((item) => {
const callbackName = item[0]
Expand All @@ -71,10 +80,10 @@ export default function proxyEventMixin () {
}
})
: [$event]
if (typeof this[callbackName] === 'function') {
returnedValue = this[callbackName].apply(this, params)
if (typeof context[callbackName] === 'function') {
returnedValue = context[callbackName].apply(context, params)
} else {
error(`Instance property [${callbackName}] is not function, please check.`, location)
logCallbackNotFound(context, callbackName)
}
}
})
Expand Down
31 changes: 31 additions & 0 deletions packages/core/src/platform/builtInMixins/refsMixin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CREATED, BEFORECREATE, BEFOREUPDATE, UNMOUNTED } from '../../core/innerLifecycle'
import { noop, error, getEnvObj } from '@mpxjs/utils'
import contextMap from '../../vnode/context'

const envObj = getEnvObj()

Expand Down Expand Up @@ -44,6 +45,13 @@ export default function getRefsMixin () {
this.__refCacheMap.clear()
this.__asyncRefCacheMap.clear()
},
[CREATED] () {
// todo 需要确认下这部分的逻辑,如果是在 beforeCreate 钩子里面执行,部分数据取不到
// 如果是在运行时组件的上下文渲染
if (this.mpxCustomElement) {
this.__getRuntimeRefs()
}
},
methods: {
__getRefs () {
if (this.__getRefsData) {
Expand Down Expand Up @@ -72,6 +80,29 @@ export default function getRefsMixin () {
return ref.all ? this.selectAllComponents(selector) : this.selectComponent(selector)
}
}
},
__getRuntimeRefs () {
const vnodeContext = contextMap.get(this.uid)
if (vnodeContext) {
const refsArr = vnodeContext.__getRefsData && vnodeContext.__getRefsData()
if (Array.isArray(refsArr)) {
refsArr.forEach((ref) => {
const all = ref.all
if (!vnodeContext.$refs[ref.key] || (all && !vnodeContext.$refs[ref.key].length)) {
const refNode = this.__getRefNode(ref)
if ((all && refNode.length) || refNode) {
Object.defineProperty(vnodeContext.$refs, ref.key, {
enumerable: true,
configurable: true,
get: () => {
return refNode
}
})
}
}
})
}
}
}
}
}
Expand Down
11 changes: 9 additions & 2 deletions packages/core/src/platform/builtInMixins/renderHelperMixin.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { getByPath, hasOwn, isObject } from '@mpxjs/utils'
import genVnodeTree from '../../vnode/render'
import dynamicComponentsMap from '../../vnode/staticMap'

export default function renderHelperMixin () {
return {
Expand Down Expand Up @@ -36,8 +38,13 @@ export default function renderHelperMixin () {
_sc (key) {
return (this.__mpxProxy.renderData[key] = this[key])
},
_r (skipPre) {
this.__mpxProxy.renderWithData(skipPre)
_r (skipPre, vnode) {
this.__mpxProxy.renderWithData(skipPre, vnode)
},
_g (moduleId) {
const { template = {}, styles = [] } = dynamicComponentsMap[moduleId]
const vnodeTree = genVnodeTree(template, [this], styles, moduleId)
return vnodeTree
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions packages/core/src/platform/builtInMixins/runtimeModulesMixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { CREATED } from '../../core/innerLifecycle'
import staticMap from '../../vnode/staticMap'

// todo 后续这部分的逻辑应该收敛至业务侧
export default function getRuntimeModulesMixin () {
return {
data: {
__mpxDynamicLoaded: false
},
[CREATED] () {
const runtimeModules = this.__getRuntimeModules && this.__getRuntimeModules()
if (runtimeModules) {
// 判断是否有还未获取的组件内容
const moduleIds = []
for (const component in runtimeModules) {
const moduleId = runtimeModules[component]
if (!staticMap[moduleId]) {
moduleIds.push(moduleId)
}
}
if (typeof this.mpxLoadDynamic === 'function' && moduleIds.length) {
// todo: 依赖业务侧的约定,在业务侧的具体实现一个资源位对应一个 id,请求数据后在内存当中挂载
this.mpxLoadDynamic().then(data => {
this.__mpxDynamicLoaded = true
Object.assign(staticMap, data)
}).catch(e => {
// do something
})
}
}
}
}
}
10 changes: 10 additions & 0 deletions packages/core/src/platform/patch/ali/getDefaultOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ function transformApiForProxy (context, currentInject) {
}
})
}
if (currentInject.getRuntimeModules) {
Object.defineProperties(context, {
__getRuntimeModules: {
get () {
return currentInject.getRuntimeModules
},
configurable: false
}
})
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions packages/core/src/platform/patch/wx/getDefaultOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ function transformApiForProxy (context, currentInject) {
}
})
}
if (currentInject.getRuntimeModules) {
Object.defineProperties(context, {
__getRuntimeModules: {
get () {
return currentInject.getRuntimeModules
},
configurable: false
}
})
}
}
}

Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/vnode/context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const cache = {}

const contextMap = {
set (id, context) {
cache[id] = context
},
get (id) {
return cache[id]
},
remove (id) {
if (cache[id]) {
delete cache[id]
}
}
}

export default contextMap
Loading