Skip to content

Commit 35093df

Browse files
committed
chore: merge dev
2 parents 227cdd6 + 87626c5 commit 35093df

15 files changed

+3256
-2908
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ logs
2121
*.log
2222
# eslint
2323
.eslintcache
24+
.history

docs/zh-cn/changelog.md

+10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77
- 修订版本号:每周末会进行日常 bugfix 更新。(如果有紧急的 bugfix,则任何时候都可发布)
88

99
---
10+
### 1.0.0-rc.20
11+
12+
`待定`
13+
- **Bug Fix**
14+
- 🐞 修复 从rc8升级到rc18后,子应用中使用instanceof判断出现异常 [issue 1497](https://github.com/jd-opensource/micro-app/issues/1497)
15+
- 🐞 修复 setTimeout 执行后未清理记录导致内存泄漏。
16+
- 🐞 修复 子应用采用 "react": "^18.3.1" + jdesign Dragger 上传组件异常问题。
17+
- **Feature**
18+
- 支持 子应用A标签href自定义补齐回调钩子。
19+
1020
### 1.0.0-rc.19
1121

1222
`2025-01-15`

docs/zh-cn/micro-app-devtools.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# 📖简介
22
`Micro-App-DevTools`是基于京东零售推出的一款为`micro-app`框架而开发的`chrome`插件,旨在方便开发者对微前端进行数据查看以及调试,提升工作效率。
3-
Github 地址为:[https://github.com/jd-opensource/micro-app-chrome-plugin](https://github.com/jd-opensource/micro-app-chrome-plugin),欢迎 Star 一下
3+
Github 地址为:[https://github.com/micro-zoe/micro-app-chrome-plugin](https://github.com/micro-zoe/micro-app-chrome-plugin),欢迎 Star 一下
44

55
# 如何使用
66

7-
在chrome中输入`chrome://extensions`打开扩展程序,打开[插件下载地址](https://github.com/jd-opensource/micro-app-chrome-plugin/releases),选择最新Release包的`micro-app-chrome-plugin.zip`
7+
在chrome中输入`chrome://extensions`打开扩展程序,打开[插件下载地址](https://github.com/micro-zoe/micro-app-chrome-plugin/releases),选择最新Release包的`micro-app-chrome-plugin.zip`
88
文件下载,无需解压,将已下载的插件拖入。
99

1010
![扩展程序](https://img12.360buyimg.com/imagetools/jfs/t1/119438/16/38287/53001/646b50e3F9012f2e8/3bba9844bbb1431b.png)
@@ -49,7 +49,7 @@ Github 地址为:[https://github.com/jd-opensource/micro-app-chrome-plugin](ht
4949
#### 快捷打开方式二
5050
点击鼠标右键,选择micro-app下,二级菜单点子应用开发环境模拟
5151

52-
![快捷方式](https://github.com/jd-opensource/micro-app-chrome-plugin/assets/14011130/91b40f7c-a826-4ffe-8c20-0b43a5c3bc6f)
52+
![快捷方式](https://github.com/micro-zoe/micro-app-chrome-plugin/assets/14011130/91b40f7c-a826-4ffe-8c20-0b43a5c3bc6f)
5353

5454

5555
## 常见问题
@@ -61,7 +61,7 @@ Github 地址为:[https://github.com/jd-opensource/micro-app-chrome-plugin](ht
6161

6262
## 🤝 参与共建
6363

64-
如果您对这个项目感兴趣,欢迎提[pull request](https://github.com/jd-opensource/micro-app-chrome-plugin/pulls)参与贡献,也欢迎 [Star](https://github.com/jd-opensource/micro-app-chrome-plugin) 支持一下 ^_^
64+
如果您对这个项目感兴趣,欢迎提[pull request](https://github.com/micro-zoe/micro-app-chrome-plugin/pulls)参与贡献,也欢迎 [Star](https://github.com/micro-zoe/micro-app-chrome-plugin) 支持一下 ^_^
6565
欢迎小伙伴们加入`Micro-App-DevTools`微信群交流^ ^
6666

6767
![image](https://img12.360buyimg.com/imagetools/jfs/t1/29962/13/20207/70265/646c9851Fe104e7c1/fed2ab97e2cf5f29.png)

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@
126126
"node-fetch": "~2.6.1",
127127
"npm-run-all": "~4.1.5",
128128
"pretty-bytes": "~5.5.0",
129-
"react": "~17.0.2",
130129
"rollup": "~2.35.1",
131130
"rollup-plugin-terser": "~7.0.2",
132131
"ts-jest": "~26.5.6",

src/create_app.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export default class CreateApp implements AppInterface {
8181
public fiber = false
8282
public routerMode: string
8383
public attrs?: Record<string, string>
84+
public isReloading = false
8485

8586
constructor ({
8687
name,
@@ -106,6 +107,7 @@ export default class CreateApp implements AppInterface {
106107
// exec before getInlineModeState
107108
this.iframe = iframe ?? false
108109
this.inline = this.getInlineModeState(inline)
110+
this.isReloading = false
109111
/**
110112
* NOTE:
111113
* 1. Navigate after micro-app created, before mount
@@ -544,7 +546,7 @@ export default class CreateApp implements AppInterface {
544546
if (this.umdMode && this.container && !destroy) {
545547
this.cloneContainer(this.source.html, this.container as HTMLElement, false)
546548
}
547-
549+
const shouldClearData = this.isReloading ? false : (clearData || destroy)
548550
/**
549551
* this.container maybe contains micro-app element, stop sandbox should exec after cloneContainer
550552
* NOTE:
@@ -555,7 +557,7 @@ export default class CreateApp implements AppInterface {
555557
umdMode: this.umdMode,
556558
keepRouteState: keepRouteState && !destroy,
557559
destroy,
558-
clearData: clearData || destroy,
560+
clearData: shouldClearData,
559561
})
560562

561563
// dispatch unmount event to base app
@@ -762,7 +764,11 @@ export default class CreateApp implements AppInterface {
762764
*/
763765
private createSandbox (): void {
764766
if (this.useSandbox && !this.sandBox) {
765-
this.sandBox = this.iframe ? new IframeSandbox(this.name, this.url, { attrs: this.attrs }) : new WithSandBox(this.name, this.url)
767+
const iframeOption = {
768+
attrs: this.attrs,
769+
container: this.container
770+
}
771+
this.sandBox = this.iframe ? new IframeSandbox(this.name, this.url, iframeOption) : new WithSandBox(this.name, this.url)
766772
}
767773
}
768774

src/libs/utils.ts

+3
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,9 @@ export function instanceOf<T extends new (...args: unknown[]) => unknown>(
760760
return false
761761
} else if (!isFunction(constructor)) {
762762
throw new TypeError("Right-hand side of 'instanceof' is not callable")
763+
} else if (typeof instance === 'number' || typeof instance === 'string' || typeof instance === 'boolean') {
764+
// 检查 obj 是否是基本类型的包装器实例
765+
return false
763766
}
764767
let proto = Object.getPrototypeOf(instance)
765768
while (proto) {

src/micro_app.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,15 @@ export function reload (appName: string, destroy?: boolean): Promise<boolean> {
191191
if (app) {
192192
const rootContainer = app.container && getRootContainer(app.container)
193193
if (rootContainer) {
194-
resolve(rootContainer.reload(destroy))
194+
const currentData = microApp.getData(appName)
195+
app.isReloading = true
196+
rootContainer.reload(destroy).then(() => {
197+
if (currentData) {
198+
microApp.setData(appName, currentData)
199+
}
200+
app.isReloading = false
201+
resolve(true)
202+
})
195203
} else {
196204
logWarn(`app ${appName} is not rendered, cannot use reload`)
197205
resolve(false)

src/sandbox/adapter.ts

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export class BaseSandbox implements BaseSandboxType {
4545
// TODO: 是否可以和constants/SCOPE_WINDOW_ON_EVENT合并
4646
'onpopstate',
4747
'onhashchange',
48+
'event',
4849
]
4950

5051
public appName: string

src/sandbox/iframe/document.ts

+6
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ function patchDocumentPrototype (appName: string, microAppWindow: microAppWindow
133133
// query element👇
134134
function querySelector (this: Document, selectors: string): any {
135135
const _this = getBindTarget(this)
136+
if (selectors === 'body') {
137+
return this.body
138+
}
136139
if (
137140
!selectors ||
138141
isUniqueElement(selectors) ||
@@ -302,6 +305,9 @@ function patchDocumentProperty (
302305
configurable: true,
303306
get: () => {
304307
throttleDeferForIframeAppName(appName)
308+
if (tagName === 'body') {
309+
return sandbox.options.container?.querySelector('micro-app-body')
310+
}
305311
return rawDocument[tagName]
306312
},
307313
set: (value: unknown) => { rawDocument[tagName] = value },

src/sandbox/iframe/element.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
isDocumentFragment,
1414
isFunction,
1515
isBrowser,
16+
isArray,
1617
} from '../../libs/utils'
1718
import {
1819
updateElementInfo,
@@ -34,7 +35,7 @@ export function patchElement (
3435
sandbox: IframeSandbox,
3536
): void {
3637
patchIframeNode(appName, microAppWindow, sandbox)
37-
patchIframeAttribute(url, microAppWindow)
38+
patchIframeAttribute(url, microAppWindow, appName)
3839
}
3940

4041
/**
@@ -229,7 +230,7 @@ function patchIframeNode (
229230
})
230231
}
231232

232-
function patchIframeAttribute (url: string, microAppWindow: microAppWindowType): void {
233+
function patchIframeAttribute (url: string, microAppWindow: microAppWindowType, appName: string): void {
233234
const microRootElement = microAppWindow.Element
234235
const rawMicroSetAttribute = microRootElement.prototype.setAttribute
235236

@@ -241,7 +242,15 @@ function patchIframeAttribute (url: string, microAppWindow: microAppWindowType):
241242
) {
242243
this.setAttribute(key, value)
243244
} else {
244-
if (
245+
let appPlugins = microApp?.options?.plugins?.modules?.[appName]
246+
if (!isArray(appPlugins)) {
247+
appPlugins = []
248+
}
249+
const aHrefResolver = appPlugins[0]?.aHrefResolver
250+
if (key === 'href' && /^a$/i.test(this.tagName) && typeof aHrefResolver === 'function') {
251+
// 试验性质:a 标签开放自定义补齐功能
252+
value = aHrefResolver(value, appName, url)
253+
} else if (
245254
((key === 'src' || key === 'srcset') && /^(img|script|video|audio|source|embed)$/i.test(this.tagName)) ||
246255
(key === 'href' && /^(link|image)$/i.test(this.tagName)) ||
247256
// If it is the anchor tag,eg. <a href="#xxx"/>, the path will not be completed

src/sandbox/iframe/index.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ import {
6060
patchElementTree
6161
} from '../adapter'
6262

63+
interface IOption {
64+
container: HTMLElement | ShadowRoot | null,
65+
[key: string]: any
66+
}
67+
6368
export default class IframeSandbox {
6469
static activeCount = 0 // number of active sandbox
6570
private active = false
@@ -81,11 +86,11 @@ export default class IframeSandbox {
8186
// TODO: 放到 super中定义,super(appName, url),with沙箱也需要简化
8287
public appName: string
8388
public url: string
84-
public options?: Record<string, any>
89+
public options: IOption
8590
// reset mount, unmount when stop in default mode
8691
public clearHijackUmdHooks!: () => void
8792

88-
constructor (appName: string, url: string, options: Record<string, any>) {
93+
constructor (appName: string, url: string, options: IOption) {
8994
this.appName = appName
9095
this.url = url
9196
this.options = options

src/sandbox/scoped_css.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ export default function scopedCSS (
519519
linkPath,
520520
)
521521
const observer = new MutationObserver(() => {
522-
const isPrefixed = styleElement.textContent && new RegExp(prefix).test(styleElement.textContent)
522+
const escapedPrefix = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
523+
const isPrefixed = styleElement.textContent && new RegExp(escapedPrefix).test(styleElement.textContent)
523524
observer.disconnect()
524525
if (!isPrefixed) {
525526
styleElement.__MICRO_APP_HAS_SCOPED__ = false

src/sandbox/with/window.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,13 @@ function patchWindowEffect (microAppWindow: microAppWindowType, appName: string)
294294
timeout?: number,
295295
...args: any[]
296296
): number {
297-
const timeoutId = rawSetTimeout.call(rawWindow, handler, timeout, ...args)
298-
timeoutIdMap.set(timeoutId, { handler, timeout, args })
297+
const setTimeoutHander = function(...args: any[]) {
298+
timeoutIdMap.delete(timeoutId)
299+
typeof handler === 'function' && handler(...args)
300+
}
301+
const handlerWithCleanup: TimerHandler = typeof handler === 'string' ? handler : setTimeoutHander
302+
const timeoutId = rawSetTimeout.call(rawWindow, handlerWithCleanup, timeout, ...args)
303+
timeoutIdMap.set(timeoutId, { handler: handlerWithCleanup, timeout, args })
299304
return timeoutId
300305
}
301306

typings/global.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ declare module '@micro-app/types' {
188188
routerMode: string // virtual router mode
189189
isPrefetch: boolean // whether prefetch app, default is false
190190
isPrerender: boolean
191+
isReloading?: boolean
191192
prefetchLevel?: number
192193
// defaultPage: string // default page when mount
193194
// baseroute: string // route prefix, default is ''
@@ -311,6 +312,7 @@ declare module '@micro-app/types' {
311312
loader?: (code: string, url: string) => string
312313
// html processor
313314
processHtml?: (code: string, url: string) => string
315+
aHrefResolver?: (hrefValue: string, appName: string, appUrl: string) => string
314316
}>
315317
}
316318
}

0 commit comments

Comments
 (0)