@xingtukeji/micro 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xingtukeji/micro",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "private": false,
5
5
  "description": "",
6
6
  "main": "dist/index.js",
package/vite.config.ts CHANGED
@@ -12,7 +12,6 @@ export default defineConfig(({ mode }) => {
12
12
  name: '__xt_micro__',
13
13
  formats: ['es'],
14
14
  fileName: (format, entryName) => `index.js`,
15
- cssFileName: 'my-lib-style',
16
15
  },
17
16
  target: 'es2015',
18
17
  emptyOutDir: true, //去掉打包到项目外的警告
package/src/api.ts DELETED
@@ -1,108 +0,0 @@
1
- import type {AppOption, App} from './index.d'
2
- import {MicroApp} from './parent'
3
- import {microInit} from './child'
4
-
5
- let _apps: Record<string, App> = {}
6
-
7
- const defaultAppOption: AppOption = {
8
- url: '',
9
- name: '',
10
- sync: true
11
- }
12
- /**
13
- * 安装微应用
14
- * @param app
15
- */
16
- export const setupApp = (app: AppOption): App | undefined => {
17
- // 如果app的url属性不存在或者为空字符串或者为'undefined',则打印错误信息并返回
18
- if(!app.url || app.url === '' || app.url === 'undefined'){
19
- console.error('app url is required', app)
20
- return
21
- }
22
- // 将defaultAppOption对象中的属性赋值给app对象
23
- const op = Object.assign({}, app, defaultAppOption)
24
- // 将app对象中的属性和MicroApp类的实例赋值给_apps对象中的app.name属性
25
- _apps[app.name] = {
26
- ...op,
27
- instance: new MicroApp(app),
28
- }
29
- // 返回_apps对象中的app.name属性
30
- return _apps[app.name]
31
- }
32
-
33
- // 导出一个函数,用于获取指定名称的应用
34
- export const getApp = (name: string): App => {
35
- // 返回指定名称的应用
36
- return _apps[name]
37
- }
38
-
39
- /**
40
- * 设置应用配置
41
- * @param {App} app - 应用对象
42
- * @param {Partial<AppOption>} options - 应用选项(可选)
43
- * @returns {App} - 设置后的应用对象
44
- */
45
- const setApp = (app: App, options?: Partial<AppOption>) => {
46
- // 返回一个对象,该对象将app和options合并
47
- return (_apps[app.name] = {
48
- ...app,
49
- ...options,
50
- })
51
- }
52
- /**
53
- * 启动微应用
54
- * @param name 应用名称
55
- * @param options 应用配置
56
- * @returns
57
- */
58
- export const startApp = (name: string, options?: Partial<AppOption>) => {
59
- // 返回一个Promise对象
60
- return new Promise((resolve, reject) => {
61
- // 调用getApp函数,传入name参数,获取app对象
62
- let app = getApp(name)
63
- // 如果app对象存在
64
- if (app) {
65
- // 如果options参数存在
66
- if (options) {
67
- // 调用app对象的changeOptions方法,传入options参数
68
- app.instance.changeOptions(options)
69
- // 调用setApp函数,传入app对象和options参数,重新设置app对象
70
- app = setApp(app, options)
71
- }
72
- // 如果app对象的preload属性存在
73
- if (app.preload) {
74
- // 调用app对象的preloadRender方法,传入app对象的el属性
75
- app.instance.preloadRender(app.el)
76
- } else {
77
- // 否则,调用app对象的mount方法,传入app对象的el属性
78
- app.instance.mount(app.el)
79
- }
80
- // 调用_postMicro函数,传入app对象
81
- // _postMicro(app)
82
- // 调用resolve方法,传入app对象
83
- resolve(app)
84
- } else {
85
- // 否则,调用reject方法,传入'app not found'字符串
86
- reject('app not found')
87
- }
88
- })
89
- }
90
-
91
- /**
92
- * 停止指定名称的应用程序
93
- * @param {string} name - 应用程序的名称
94
- */
95
- export const stopApp = (name: string) => {
96
- // 获取名为name的app
97
- let app = getApp(name)
98
- // 如果app存在
99
- if (app) {
100
- // 调用app的unmount方法
101
- app.instance.unmount()
102
- }
103
- }
104
-
105
-
106
- export {
107
- microInit
108
- }
package/src/child.ts DELETED
@@ -1,186 +0,0 @@
1
- import {getQueryParameter} from './utils'
2
- import {CONSTANT} from './types'
3
- import {MicroApp} from './parent'
4
- import {MicroInitOptions} from './index.d'
5
- /**
6
- * 微应用-子应用初始化
7
- * 此时方法上下文是子应用
8
- * 非必须,但建议使用
9
- * @param options
10
- */
11
- export const microInit = async (options: MicroInitOptions = {}) => {
12
- //处理url参数
13
- const micro = getQueryParameter(CONSTANT.IS_MICRO)
14
- const microName = getQueryParameter(CONSTANT.MICRO_NAME)
15
- //设置环境变量
16
- if (micro) {
17
- window[CONSTANT.IS_MICRO] = true
18
- }
19
- // console.log(`子应用「${microName}」初始化`, document)
20
- // 尝试全局隐藏 header,该方式有一定的入侵,
21
- function addGlobalStyle(css: string) {
22
- var styleSheet = document.styleSheets[0];
23
- if (!styleSheet) {
24
- var style = document.createElement('style');
25
- document.head.appendChild(style);
26
- styleSheet = style.sheet!;
27
- }
28
- styleSheet.insertRule(css, styleSheet.cssRules.length);
29
- }
30
- // addGlobalStyle('._hedaui-header { display: none !important; }')
31
- if(options.hideHeaderCssSelector) {
32
- addGlobalStyle(`${options.hideHeaderCssSelector} { display: none !important; }`)
33
- }
34
- // 子应用监听message,设置环境变量
35
- window.addEventListener('message', (e) => {
36
- if (e.data.cmd === `$xt/micro/${microName}`) {
37
- console.log('子应用收到消息:', microName, )
38
- window[CONSTANT.MICRO_APP] = { ...e.data.data, mainBaseURL: e.origin }
39
- }
40
- })
41
- patchIframeHistory(window)
42
-
43
- // window.addEventListener('load', () => {
44
- // console.log('子应用加载完成:', microName, window.location.href)
45
- // // 监听 popstate 事件
46
- // // window.addEventListener('popstate', function (event) {
47
- // // console.log('History state changed:', event.state);
48
- // // // 在这里可以根据新的历史状态进行相应的页面更新操作
49
- // // });
50
- // // patchIframeHistory(window, "http://localhost:5173", "http://localhost:8888")
51
- // })
52
-
53
-
54
-
55
- //处理token
56
- const token = getQueryParameter(CONSTANT.MICRO_TOKEN)
57
- options.authHandler && token && await options.authHandler(token)
58
- }
59
-
60
- //子应用给父应用同步路由
61
- const _syncMicroPath = (app: MicroApp) => {
62
- // console.log(`子应用给父应用「${app.app.name}」同步路由`, app.dom)
63
- const parentWindow = window.parent;
64
- const message = 'Hello from child!';
65
- parentWindow.postMessage(message, 'http://localhost:8080');
66
- app.dom?.contentWindow?.postMessage
67
- ({
68
- cmd: `$xt/micro/${app.app.name}/sync`,
69
- data: {
70
- name: app.app.name,
71
- url: app.app.url,
72
- preload: app.app.preload,
73
- // params: app.params
74
- }
75
- })
76
- }
77
-
78
- /**
79
- * 对iframe的history的pushState和replaceState进行修改
80
- * 将从location劫持后的数据修改回来,防止跨域错误
81
- * 同步路由到主应用
82
- * @param iframeWindow
83
- * @param appHostPath 子应用的 host path
84
- * @param mainHostPath 主应用的 host path
85
- */
86
- function patchIframeHistory(iframeWindow: Window): void {
87
- const history = iframeWindow.history;
88
- const rawHistoryPushState = history.pushState;
89
- const rawHistoryReplaceState = history.replaceState;
90
- history.pushState = function (data: any, title: string, url?: string): void {
91
- // debugger;
92
- // const baseUrl =
93
- // mainHostPath + iframeWindow.location.pathname + iframeWindow.location.search + iframeWindow.location.hash;
94
- // const mainUrl = getAbsolutePath(url?.replace(appHostPath, ""), baseUrl);
95
- // const ignoreFlag = url === undefined;
96
-
97
- rawHistoryPushState.call(history, data, title, url);
98
- // if (ignoreFlag) return;
99
- // updateBase(iframeWindow, appHostPath, mainHostPath);
100
- syncUrlToWindow();
101
- };
102
- history.replaceState = function (data: any, title: string, url?: string): void {
103
- // debugger;
104
- // const baseUrl =
105
- // mainHostPath + iframeWindow.location.pathname + iframeWindow.location.search + iframeWindow.location.hash;
106
- // const mainUrl = getAbsolutePath(url?.replace(appHostPath, ""), baseUrl);
107
- // const ignoreFlag = url === undefined;
108
-
109
- rawHistoryReplaceState.call(history, data, title, url);
110
- // if (ignoreFlag) return;
111
- // updateBase(iframeWindow, appHostPath, mainHostPath);
112
- syncUrlToWindow();
113
- };
114
- }
115
- /**
116
- * 同步子应用路由到主应用路由
117
- */
118
- // 导出一个函数,用于同步url到window
119
- export function syncUrlToWindow(): void {
120
- if(!window[CONSTANT.MICRO_APP]) return
121
- const { name, sync, mainBaseURL } = window[CONSTANT.MICRO_APP];
122
- // console.trace('syncUrlToWindow')
123
- //todo 此处应该postmessage到主应用,主应用再进行同步路由
124
- const curUrl = window.location.pathname + window.location.search + window.location.hash;
125
- window.parent.postMessage({
126
- cmd: '$xt/micro/sync',
127
- data: {
128
- name: name,
129
- url: window.encodeURIComponent(curUrl)
130
- }
131
- }, mainBaseURL);
132
-
133
- // debugger
134
- // let winUrlElement = anchorElementGenerator(window.parent.location.href);
135
- // const queryMap = getAnchorElementQueryMap(winUrlElement);
136
- // // 非同步且url上没有当前id的查询参数,否则就要同步参数或者清理参数
137
- // if (!sync && !queryMap[name]) {
138
- // (winUrlElement = null)
139
- // return
140
- // };
141
-
142
- // const curUrl = iframeWindow.location.pathname + iframeWindow.location.search + iframeWindow.location.hash;
143
- // let validShortPath = "";
144
- // // 同步
145
- // if (sync) {
146
- // queryMap[name] = window.encodeURIComponent(
147
- // curUrl
148
- // );
149
- // // 清理
150
- // } else {
151
- // delete queryMap[name];
152
- // }
153
- // const newQuery =
154
- // "?" +
155
- // Object.keys(queryMap)
156
- // .map((key) => key + "=" + queryMap[key])
157
- // .join("&");
158
- // winUrlElement.search = newQuery;
159
- // console.log('window', iframeWindow.parent.location.href)
160
- // // if (winUrlElement.href !== iframeWindow.parent.location.href) {
161
- // // console.log('window', iframeWindow.parent)
162
- // // // iframeWindow.parent.history.replaceState(null, "", winUrlElement.href);
163
- // // // window.history.replaceState(null, "", winUrlElement.href);
164
- // // }
165
- // winUrlElement = null;
166
- }
167
-
168
- /**
169
- * 同步主应用路由到子应用
170
- */
171
- export function syncUrlToIframe(iframeWindow: Window): void {
172
- // 获取当前路由路径
173
- const { pathname, search, hash } = iframeWindow.location;
174
- const { id, url, sync, execFlag, prefix, inject } = iframeWindow.__WUJIE;
175
-
176
- // 只在浏览器刷新或者第一次渲染时同步
177
- const idUrl = sync && !execFlag ? getSyncUrl(id, prefix) : url;
178
- // 排除href跳转情况
179
- const syncUrl = (/^http/.test(idUrl) ? null : idUrl) || url;
180
- const { appRoutePath } = appRouteParse(syncUrl);
181
-
182
- const preAppRoutePath = pathname + search + hash;
183
- if (preAppRoutePath !== appRoutePath) {
184
- iframeWindow.history.replaceState(null, "", inject.mainHostPath + appRoutePath);
185
- }
186
- }
@@ -1,72 +0,0 @@
1
- <script lang="ts" setup>
2
- import { onMounted, ref, watch, onUnmounted } from 'vue';
3
- import { startApp, stopApp } from '../api'
4
- const props = defineProps({
5
- appId: String
6
- })
7
-
8
- const refPanel = ref()
9
- const init = () => {
10
- props.appId && startApp(props.appId, {
11
- el: refPanel.value
12
- });
13
- }
14
-
15
- watch(() => props.appId, (newVal, oldVal) => {
16
- if(newVal !== oldVal && oldVal){
17
- stopApp(oldVal)
18
- }
19
- init()
20
- })
21
-
22
-
23
- onMounted(() => {
24
- init()
25
- })
26
-
27
- onUnmounted(()=>{
28
- console.log('微应用销毁', props.appId)
29
- })
30
- </script>
31
-
32
- <template>
33
- <div ref="refPanel" class="xt-micro w-100% h-100% overflow-hidden"></div>
34
- </template>
35
-
36
- <style lang="postcss" scoped></style>
37
- <style>
38
- .xt-micro{
39
- background-color: #fff;
40
- }
41
- .xt-micro::before{
42
- content: '加载中';
43
- position: absolute;
44
- top: 0;
45
- left: 0;
46
- right:0;
47
- bottom: 0;
48
- display: flex;
49
- justify-content: center;
50
- align-items: center;
51
- z-index: -1;
52
- }
53
- .micro-iframe{
54
- width: 100%;
55
- height: 100%;
56
- border: none;
57
- margin: 0;
58
- padding: 0;
59
- }
60
- .micro-iframe::after{
61
- content: '加载中';
62
- position: absolute;
63
- top: 0;
64
- left: 0;
65
- right:0;
66
- bottom: 0;
67
- display: flex;
68
- justify-content: center;
69
- align-items: center;
70
- background: #fff;
71
- }
72
- </style>
package/src/index.d.ts DELETED
@@ -1,29 +0,0 @@
1
-
2
- import {MicroApp} from './parent'
3
-
4
- export interface AppOption {
5
- name: string
6
- url: string
7
- el?: HTMLElement | string
8
- preload?: boolean
9
- token?: () => string | string
10
- params?: { [key: string]: any }
11
- sync?: boolean
12
- }
13
- export interface App extends AppOption {
14
- instance: MicroApp
15
- }
16
- export interface MicroInitOptions {
17
- hideHeaderCssSelector?: string
18
- authHandler?: (token: string) => void
19
- }
20
-
21
- // 扩展 Window 接口,防止ts报错
22
- declare global {
23
- interface Window {
24
- [key: string]: any
25
- }
26
- }
27
-
28
-
29
- export * from './api'
package/src/index.ts DELETED
@@ -1,16 +0,0 @@
1
-
2
-
3
- import type { App } from 'vue'
4
- import XTMicroView from './components/XTMicroView.vue'
5
-
6
-
7
-
8
- import {mainMicroInit} from './parent'
9
- export * from './api'
10
-
11
- export default {
12
- install: (app: App, _options: any = {}) => {
13
- app.component("xt-micro-view", XTMicroView);
14
- mainMicroInit()
15
- }
16
- }
package/src/parent.ts DELETED
@@ -1,268 +0,0 @@
1
- import { ref } from 'vue'
2
- import {AppOption, App} from './index.d'
3
- import {CONSTANT} from './types'
4
- import {getQueryParameter, addOrReplaceUrlParam, getAbsolutePath} from './utils'
5
-
6
- /**
7
- * 判断是否在微应用中
8
- */
9
- const _isMicro = ref(false)
10
- Object.defineProperty(window, CONSTANT.IS_MICRO, {
11
- get: function () {
12
- return _isMicro.value
13
- },
14
- set: function (newValue) {
15
- _isMicro.value = newValue
16
- },
17
- })
18
- export const isMicro = _isMicro
19
-
20
- /**
21
- * 生成微应用id
22
- * 增加前缀
23
- * @param name 微应用名称(唯一)
24
- * @returns 返回dom id
25
- */
26
- const generateId = (name: string) => {
27
- return `${CONSTANT.DOM_ID_PREFIX}${name}`
28
- }
29
- /**
30
- * 处理微应用url
31
- * @param url 微应用url
32
- * @param params 携带参数
33
- * @returns 拼接后的url
34
- */
35
- const generateURL = (app: AppOption) => {
36
- // 判断变量是否为对象
37
- function isObject(variable: unknown) {
38
- return variable !== null && typeof variable === 'object' && !Array.isArray(variable)
39
- }
40
- // 获取params参数
41
- const _parmas = typeof app.params === 'function' ? app.params() : isObject(app.params) ? app.params : {}
42
- // 获取token参数
43
- const _token = typeof app.token === 'function' ? app.token() : isObject(app.token) ? app.token : ''
44
- // 创建URL对象
45
- const url = new URL(app.url.indexOf('http') > -1 ? app.url : window.location.origin + app.url)
46
- // 获取microBakUrl参数
47
- const microBakUrl = getQueryParameter(app.name)
48
- // 如果microBakUrl存在
49
- if(microBakUrl){
50
- // 获取绝对路径
51
- const temp = getAbsolutePath(microBakUrl, app.url, true)
52
- // 如果绝对路径存在
53
- if(temp){
54
- // 创建URL对象
55
- const tempURL = new URL(temp);
56
- // 获取searchParams参数
57
- const tempSearchParams = tempURL.searchParams
58
- // 遍历searchParams参数
59
- tempSearchParams.forEach((value, key) => {
60
- // 设置url的searchParams参数
61
- url.searchParams.set(key, value)
62
- })
63
- // 设置url的hash参数
64
- url.hash = tempURL.hash
65
- }
66
- }
67
-
68
- // 设置url的searchParams参数
69
- url.searchParams.set(CONSTANT.IS_MICRO, true+'')
70
- url.searchParams.set(CONSTANT.MICRO_NAME, app.name)
71
- _token && url.searchParams.set(CONSTANT.MICRO_TOKEN, _token)
72
-
73
- if(_parmas){
74
- // 设置url的searchParams参数
75
- for(let key of Object.keys(_parmas)){
76
- url.searchParams.set(key, _parmas[key])
77
- }
78
- }
79
-
80
- // 清空主路由上的子应用路由sync参数
81
- const mainURL = new URL(window.location.href)
82
- mainURL.searchParams.delete(app.name)
83
- window.history.replaceState({}, '', mainURL.href)
84
- // 返回url的href属性
85
- return url.href
86
- }
87
-
88
- export class MicroApp {
89
- app: App | AppOption
90
- dom: HTMLIFrameElement | undefined
91
- panel: HTMLElement | undefined
92
-
93
- constructor(app: AppOption) {
94
- this.app = app
95
- app.preload && this.preload()
96
- this.dom = undefined
97
- this.panel = undefined
98
- return this
99
- }
100
-
101
- mount(el: HTMLElement | string | undefined, isHide = false) {
102
- let panel: HTMLElement | null
103
- if (el) {
104
- if (typeof el === 'string') {
105
- panel = document.querySelector(el)
106
- } else {
107
- panel = el
108
- }
109
- //这里清空了容器的内容,为了方便,如果还有其他元素需要特别处理,而且也影响元素再复用
110
- panel!.innerHTML = ''
111
- } else {
112
- panel = document.body
113
- }
114
-
115
- if (panel) {
116
- let ifr = <HTMLIFrameElement>document.getElementById(generateId(this.app.name))
117
- if (!ifr) {
118
- ifr = document.createElement('iframe')
119
- ifr.id = generateId(this.app.name)
120
- const url = generateURL(this.app)
121
- ifr.src = url
122
- ifr.classList.add('micro-iframe')
123
- ifr.addEventListener('load', (event) => {
124
- this.onLoad.call(this, event)
125
- })
126
- ifr.addEventListener('error', this.onError)
127
- ifr.addEventListener('unload', this.onUnload)
128
- this.dom = ifr
129
- }
130
- isHide ? (ifr.style.display = 'none') : ifr.style.removeProperty('display')
131
- this.panel = panel
132
- panel.appendChild(ifr)
133
- } else {
134
- throw new Error('el not found')
135
- }
136
- }
137
-
138
- unmount() {
139
- const appDom = document.getElementById(generateId(this.app.name))
140
- if (appDom) {
141
- if (this.app.preload) {
142
- // if (this.preload){
143
- appDom.style.display = 'none'
144
- document.body.appendChild(appDom)
145
- } else {
146
- this.panel?.removeChild(appDom)
147
- }
148
- } else {
149
- throw new Error('app dom not found')
150
- }
151
- }
152
-
153
- /**
154
- * 预加载渲染
155
- * TODO 还差用户切走之后,如何将ifr还原回去,等待下次载入
156
- * @param el 挂载dom对象
157
- */
158
- preloadRender(el: HTMLElement | string | undefined) {
159
- // let appDom: HTMLElement | undefined = this.dom
160
- this.mount(el)
161
-
162
- // const appDom = document.getElementById(generateId(this.app.name))
163
- // if (!appDom) {
164
- //
165
- // this.render(el)
166
- // return
167
- // }
168
- //
169
- // let panel
170
- // if (typeof el === 'string') {
171
- // panel = document.querySelector(el)
172
- // } else {
173
- // panel = el
174
- // }
175
- // appDom!.style.removeProperty('display')
176
- // panel?.appendChild(appDom)
177
- }
178
-
179
- /**
180
- * 预加载app,先放到body,待启动时,挪过来
181
- */
182
- preload() {
183
- this.mount(undefined, true)
184
- }
185
-
186
- changeOptions(options: Partial<AppOption>) {
187
- this.app = {
188
- ...this.app,
189
- ...options,
190
- }
191
- }
192
-
193
- onLoad(_event: Event) {
194
- // console.log('子应用 onload', this.app.name)
195
- // console.log('onLoad',this.app, this.panel, this.dom)
196
- // if(this.dom){
197
- // const headerDom = this.dom.contentWindow.document.querySelector('._hedaui-header')
198
- // headerDom && (headerDom.style.display = 'none')
199
- // }
200
-
201
- //监听message,设置环境变量
202
- // console.log('window', window['__XT_MICRO'])
203
- // window.addEventListener('message', (e) => {
204
- // console.log('1111', this.app.name, window.document)
205
- // if (e.data.cmd === `$xt/micro/${this.app.name}`) {
206
- // // console.log('micro', e.data.data)
207
- // window[CONSTANT.MICRO_APP] = e.data.data
208
- // const headerDom = document.querySelector('._hedaui-header')
209
- // headerDom && (headerDom.style.display = 'none')
210
- // }
211
- // })
212
- _postMicro(this)
213
- }
214
-
215
- onUnload(_event: Event) {}
216
-
217
- onError() {}
218
- }
219
-
220
-
221
-
222
-
223
-
224
- /**
225
- * 父应用给子应用发送消息
226
- * @param app 微应用对象
227
- */
228
- const _postMicro = (app: MicroApp) => {
229
- // console.log(`父应用给子应用「${app.app.name}」发送消息`, app.dom)
230
- app.dom?.contentWindow?.postMessage(
231
- {
232
- cmd: `$xt/micro/${app.app.name}`,
233
- data: {
234
- name: app.app.name,
235
- url: app.app.url,
236
- preload: app.app.preload,
237
- sync: app.app.sync || true
238
- // params: app.params
239
- },
240
- },
241
- '*'
242
- )
243
- }
244
-
245
-
246
-
247
- /**
248
- * 初始化主应用微前端
249
- */
250
- export const mainMicroInit = () => {
251
- // 监听window对象的消息事件
252
- window.addEventListener('message', (e)=>{
253
- // 同步子应用路由到主应用上
254
- if (e.data.cmd === '$xt/micro/sync') {
255
- // 过滤掉微应用的默认参数
256
- const whitelist = [CONSTANT.IS_MICRO, CONSTANT.MICRO_NAME, CONSTANT.MICRO_TOKEN]
257
- const tempUrl = new URL(window.decodeURIComponent(e.data.data.url), e.origin)
258
- for(let key of whitelist){
259
- tempUrl.searchParams.delete(key)
260
- }
261
- console.log('tempUrl', tempUrl.href)
262
- // 调用addOrReplaceUrlParam函数,将e.data.data.name和e.data.data.url作为参数传入
263
- const curUrl = addOrReplaceUrlParam(window.location.href, e.data.data.name, tempUrl.href)
264
- // 使用replaceState方法替换当前页面的URL
265
- window.history.replaceState(null, "", curUrl);
266
- }
267
- })
268
- }
package/src/types.ts DELETED
@@ -1,8 +0,0 @@
1
- export const CONSTANT: Record<string, string> = {
2
- KEY: '$xtm', // 父应用注入子应用实例的key
3
- IS_MICRO: '__XT_MICRO', // 是否在微应用中
4
- MICRO_NAME: '__XT_MICRO_NAME', // 微应用名称
5
- MICRO_TOKEN: '__XT_MICRO_TOKEN', // 微应用token
6
- MICRO_APP: '__XT_MICRO_APP', // 微应用实例
7
- DOM_ID_PREFIX: 'xt-micro-ifr-', // dom id前缀
8
- }
package/src/utils.ts DELETED
@@ -1,94 +0,0 @@
1
- // 获取URL中的查询参数
2
- // 导出一个函数,用于获取查询参数
3
- export function getQueryParameter(name: string, url = window.location.href): string | null {
4
- // 将参数名中的中括号替换为转义字符
5
- name = name.replace(/[\[\]]/g, '\\$&')
6
- // 创建正则表达式,匹配查询参数
7
- var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
8
- results = regex.exec(url)
9
- // 如果没有匹配到查询参数,返回null
10
- if (!results) return null
11
- // 如果没有匹配到参数值,返回空字符串
12
- if (!results[2]) return ''
13
- // 对参数值进行解码,并去除首尾空格
14
- return decodeURIComponent(results[2].replace(/\+/g, ' ')).trim()
15
- }
16
-
17
- // 导出一个函数,用于获取绝对路径
18
- export function getAbsolutePath(url: string|undefined, base: string, hash?: boolean): string | undefined {
19
- try {
20
- // 为空值无需处理
21
- if (url) {
22
- // 需要处理hash的场景
23
- if (hash && url.startsWith("#")) return url;
24
- return new URL(url, base).href;
25
- } else return url;
26
- } catch {
27
- return url;
28
- }
29
- }
30
-
31
- // 导出一个函数,用于生成一个HTMLAnchorElement元素
32
- export function anchorElementGenerator(url: string): HTMLAnchorElement {
33
- // 创建一个a标签元素
34
- const element = window.document.createElement("a");
35
- // 设置a标签的href属性为传入的url
36
- element.href = url;
37
- element.href = element.href; // hack ie
38
- return element;
39
- }
40
-
41
- // 导出一个函数,用于获取锚点元素的查询字符串映射
42
- export function getAnchorElementQueryMap(anchorElement: HTMLAnchorElement): { [key: string]: string } {
43
- // 获取锚点元素的查询字符串
44
- const queryString = anchorElement.search || "";
45
- // 将查询字符串转换为URLSearchParams对象,并使用reduce方法将其转换为键值对映射
46
- return [...new URLSearchParams(queryString).entries()].reduce((p, c) => {
47
- // 将键值对添加到映射中
48
- p[c[0]] = c[1];
49
- // 返回映射
50
- return p;
51
- }, {} as Record<string, string>);
52
- }
53
-
54
-
55
- //防抖函数,支持传过来一个函数,返回一个防抖后的函数
56
- export function debounce<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void {
57
- let timer: ReturnType<typeof setTimeout> | null = null;
58
-
59
- return function (this: ThisParameterType<T>, ...args: Parameters<T>): void {
60
- const context = this;
61
-
62
- if (timer) {
63
- clearTimeout(timer);
64
- }
65
-
66
- timer = setTimeout(() => {
67
- func.apply(context, args);
68
- }, delay);
69
- };
70
- }
71
-
72
- export function addOrReplaceUrlParam(url: string, paramName: string, paramValue: string): string {
73
- // 先分割出 URL 的基础部分和哈希部分
74
- const [baseUrl, hash] = url.split('#');
75
- const urlObj = new URL(baseUrl);
76
- const searchParams = urlObj.searchParams;
77
-
78
- // 如果参数已经存在,则替换其值
79
- if (searchParams.has(paramName)) {
80
- searchParams.set(paramName, paramValue);
81
- } else {
82
- // 如果参数不存在,则添加该参数
83
- searchParams.append(paramName, paramValue);
84
- }
85
- // 如果原 URL 有哈希部分,再把它加回去
86
- if (hash) {
87
- urlObj.hash = hash
88
- }
89
-
90
- urlObj.search = searchParams.toString();
91
- let newUrl = urlObj.toString();
92
-
93
- return newUrl;
94
- }