Skip to content

Commit

Permalink
feat: 优化了module script的执行方式
Browse files Browse the repository at this point in the history
  • Loading branch information
bailicangdu committed Oct 20, 2021
1 parent 86f2d94 commit 90a9612
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 27 deletions.
13 changes: 11 additions & 2 deletions examples/children/react16/src/index.js
Expand Up @@ -100,5 +100,14 @@ if (window.__MICRO_APP_ENVIRONMENT__) {

// const dynamicScript1 = document.createElement('script')
// dynamicScript1.setAttribute('type', 'module')
// dynamicScript1.textContent = 'console.warn("inline module")'
// document.head.appendChild(dynamicScript1)
// // dynamicScript1.textContent = 'console.warn("inline module")'
// dynamicScript1.setAttribute('src', 'http://127.0.0.1:8080/test.js')
// dynamicScript1.onload = () => {
// console.log('动态module加载完成了')
// }
// document.body.appendChild(dynamicScript1)

console.log('__micro_app_environment__', window.__micro_app_environment__)
console.log('__micro_app_name__', window.__micro_app_name__)
console.log('__full_public_path__', window.__full_public_path__)
console.log('baseurl', window.baseurl)
15 changes: 14 additions & 1 deletion examples/main-react16/src/global.jsx
Expand Up @@ -37,7 +37,20 @@ microApp.start({
// console.log('vue2插件', url, options)
return code
}
}],
},
{
loader (code) {
code = `
window.__micro_app_environment__ = window.__MICRO_APP_ENVIRONMENT__
window.__micro_app_name__ = window.__MICRO_APP_NAME__
window.__full_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
window.baseurl = window.__MICRO_APP_BASE_ROUTE__
;${code}
`
return code
}
}
],
modules: {
react16: [{
scopeProperties: ['3', '4'],
Expand Down
10 changes: 8 additions & 2 deletions examples/main-react16/src/pages/vite/vite.js
Expand Up @@ -12,6 +12,12 @@ const antIcon = <LoadingOutlined style={{ fontSize: 30 }} spin />
function vite () {
const [data, changeData] = useState({from: '来自基座的初始化数据'})
const [showLoading, hideLoading] = useState(true)

function handleMounted () {
hideLoading(false)
console.log('生命周期: vite 渲染完成了')
}

return (
<div>
{/* <div className='btn-con'>
Expand All @@ -32,9 +38,9 @@ function vite () {
// url={`http://127.0.0.1:8080/micro-app/vite/`}
data={data}
// onBeforemount={() => hideLoading(false)}
onMounted={() => hideLoading(false)}
onMounted={handleMounted}
// destory
inline
// inline
disableSandbox
>
</micro-app>
Expand Down
4 changes: 2 additions & 2 deletions src/libs/utils.ts
Expand Up @@ -170,8 +170,8 @@ export function isSupportModuleScript (): boolean {
}

// Create a random symbol string
export function createNonceStr (): string {
return Math.random().toString(36).substr(2, 15)
export function createNonceSrc (): string {
return 'inline-' + Math.random().toString(36).substr(2, 15)
}

// Array deduplication
Expand Down
51 changes: 31 additions & 20 deletions src/source/scripts.ts
Expand Up @@ -9,7 +9,7 @@ import { fetchSource } from './fetch'
import {
CompletionPath,
promiseStream,
createNonceStr,
createNonceSrc,
pureCreateElement,
defer,
logError,
Expand All @@ -21,6 +21,8 @@ import {
import microApp from '../micro_app'
import globalEnv from '../libs/global_env'

type moduleCallBack = Func & { moduleCount?: number }

// Global scripts, reuse across apps
export const globalScripts = new Map<string, string>()

Expand Down Expand Up @@ -69,7 +71,7 @@ export function extractScriptElement (
return { url: src, info }
}
} else if (script.textContent) { // inline script
const nonceStr: string = createNonceStr()
const nonceStr: string = createNonceSrc()
const info = {
code: script.textContent,
isExternal: false,
Expand Down Expand Up @@ -158,12 +160,12 @@ export function fetchScriptSuccess (
* Execute js in the mount lifecycle
* @param scriptList script list
* @param app app
* @param callback callback for umd mode
* @param initedHook callback for umd mode
*/
export function execScripts (
scriptList: Map<string, sourceScriptInfo>,
app: AppInterface,
callback: Func,
initedHook: moduleCallBack,
): void {
const scriptListEntries: Array<[string, sourceScriptInfo]> = Array.from(scriptList.entries())
const deferScriptPromise: Array<Promise<string>|string> = []
Expand All @@ -177,6 +179,8 @@ export function execScripts (
deferScriptPromise.push(info.code)
}
deferScriptInfo.push([url, info])

if (info.module) initedHook.moduleCount = initedHook.moduleCount ? ++initedHook.moduleCount : 1
} else {
runScript(url, info.code, app, info.module, false)
}
Expand All @@ -187,15 +191,15 @@ export function execScripts (
Promise.all(deferScriptPromise).then((res: string[]) => {
res.forEach((code, index) => {
const [url, info] = deferScriptInfo[index]
runScript(url, info.code = info.code || code, app, info.module, false, callback)
runScript(url, info.code = info.code || code, app, info.module, false, initedHook)
})
callback(true)
initedHook(typeof initedHook.moduleCount === 'undefined')
}).catch((err) => {
logError(err)
callback(true)
initedHook(true)
})
} else {
callback(true)
initedHook(true)
}
}

Expand All @@ -206,15 +210,15 @@ export function execScripts (
* @param app app
* @param module type='module' of script
* @param isDynamic dynamically created script
* @param callback callback from execScripts for first exec
* @param callback callback of module script
*/
export function runScript (
url: string,
code: string,
app: AppInterface,
module: boolean,
isDynamic: boolean,
callback?: Func,
callback?: moduleCallBack,
): any {
try {
code = bindScope(url, code, app, module)
Expand Down Expand Up @@ -245,18 +249,20 @@ export function runDynamicRemoteScript (
app: AppInterface,
originScript: HTMLScriptElement,
): HTMLScriptElement | Comment {
const dispatchScriptOnLoadEvent = () => dispatchOnLoadEvent(originScript)

if (app.source.scripts.has(url)) {
const existInfo: sourceScriptInfo = app.source.scripts.get(url)!
defer(() => dispatchOnLoadEvent(originScript))
return runScript(url, existInfo.code, app, info.module, true)
if (!info.module) defer(dispatchScriptOnLoadEvent)
return runScript(url, existInfo.code, app, info.module, true, dispatchScriptOnLoadEvent)
}

if (globalScripts.has(url)) {
const code = globalScripts.get(url)!
info.code = code
app.source.scripts.set(url, info)
defer(() => dispatchOnLoadEvent(originScript))
return runScript(url, code, app, info.module, true)
if (!info.module) defer(dispatchScriptOnLoadEvent)
return runScript(url, code, app, info.module, true, dispatchScriptOnLoadEvent)
}

let replaceElement: Comment | HTMLScriptElement
Expand All @@ -273,14 +279,14 @@ export function runDynamicRemoteScript (
try {
code = bindScope(url, code, app, info.module)
if (app.inline || info.module) {
setInlinScriptContent(url, code, info.module, replaceElement as HTMLScriptElement)
setInlinScriptContent(url, code, info.module, replaceElement as HTMLScriptElement, dispatchScriptOnLoadEvent)
} else {
Function(code)()
}
} catch (e) {
console.error('[micro-app from runDynamicScript]', e, url)
}
dispatchOnLoadEvent(originScript)
if (!info.module) dispatchOnLoadEvent(originScript)
}).catch((err) => {
logError(err)
dispatchOnErrorEvent(originScript)
Expand All @@ -295,22 +301,27 @@ export function runDynamicRemoteScript (
* @param code js code
* @param module type='module' of script
* @param scriptElement target script element
* @param callback callback from execScripts for first exec
* @param callback callback of module script
*/
function setInlinScriptContent (
url: string,
code: string,
module: boolean,
scriptElement: HTMLScriptElement,
callback?: Func,
callback?: moduleCallBack,
): void {
if (module) {
// module script is async, transform it to a blob for subsequent operations
const blob = new Blob([code], { type: 'text/javascript;charset=utf-8' })
scriptElement.src = URL.createObjectURL(blob)
scriptElement.setAttribute('type', 'module')
scriptElement.setAttribute('originSrc', url)
callback && (scriptElement.onload = callback)
if (!url.startsWith('inline-')) {
scriptElement.setAttribute('originSrc', url)
}
if (callback) {
callback.moduleCount && callback.moduleCount--
scriptElement.onload = callback.bind(scriptElement, callback.moduleCount === 0)
}
} else {
scriptElement.textContent = code
}
Expand Down

0 comments on commit 90a9612

Please sign in to comment.