import-remote-module
Advanced tools
Comparing version 0.0.7 to 1.0.0
299
index.js
@@ -5,149 +5,154 @@ /** | ||
*/ | ||
import React from "react"; | ||
import React from "react"; | ||
const remoteEnterCache = {}; // 远程入口文件缓存 | ||
const catchModules = {}; // 远程模块缓存 | ||
const remoteConfig = {}; // 远程模块入口文件配置 | ||
function loadComponent(scope, module) { | ||
return async () => { | ||
// Initializes the share scope. This fills it with known provided modules from this build and all remotes | ||
await __webpack_init_sharing__("default"); | ||
const container = window[scope]; // or get the container somewhere else | ||
// Initialize the container, it may provide shared modules | ||
await container.init(__webpack_share_scopes__.default); | ||
const factory = await window[scope].get(module); | ||
console.log(7777888, factory) | ||
const Module = factory(); | ||
return Module; | ||
}; | ||
} | ||
const useDynamicScript = (args) => { | ||
const [ready, setReady] = React.useState(false); | ||
const [failed, setFailed] = React.useState(false); | ||
React.useEffect(() => { | ||
if (!args.url) { | ||
return; | ||
} | ||
if(remoteEnterCache[args.url]) { | ||
setReady(true); | ||
return; | ||
} | ||
const element = document.createElement("script"); | ||
element.src = args.url; | ||
element.type = "text/javascript"; | ||
element.async = true; | ||
setReady(false); | ||
setFailed(false); | ||
element.onload = () => { | ||
console.log(`Dynamic Script Loaded: ${args.url}`); | ||
remoteEnterCache[args.url] = true; | ||
setReady(true); | ||
}; | ||
element.onerror = () => { | ||
console.error(`Dynamic Script Error: ${args.url}`); | ||
setReady(false); | ||
setFailed(true); | ||
}; | ||
document.head.appendChild(element); | ||
return () => { | ||
console.log(`Dynamic Script Removed: ${args.url}`); | ||
document.head.removeChild(element); | ||
}; | ||
}, [args.url]); | ||
return { | ||
ready, | ||
failed, | ||
}; | ||
}; | ||
function System(props) { | ||
const {system = {}, ...reset} = props; | ||
const { ready, failed } = useDynamicScript({ | ||
url: system && system.url, | ||
}); | ||
if (!system) { | ||
console.error(`Not system specified`); | ||
return null; | ||
} | ||
if (!ready) { | ||
return null; | ||
} | ||
if (failed) { | ||
console.error(`Failed to load dynamic script: {system.url}`); | ||
return null; | ||
} | ||
let Component = catchModules[`${system.url}${system.scope}${system.module}`]; | ||
if(!Component) { | ||
const module = loadComponent(system.scope, system.module); | ||
Component = React.lazy(module); | ||
catchModules[`${system.url}${system.scope}${system.module}`] = Component; | ||
} | ||
return ( | ||
<React.Suspense fallback=""> | ||
<Component {...reset}/> | ||
</React.Suspense> | ||
); | ||
} | ||
export const setRemoteConfig = (configs) => { | ||
for(let key in configs) { | ||
remoteConfig[key] = configs[key]; | ||
} | ||
} | ||
export const loadJson = (url, type) => { | ||
return new Promise((resolve, reject) => { | ||
fetch(url) | ||
.then(function(response) { | ||
return response[type](); | ||
}) | ||
.then(function(res) { | ||
if(type === 'json') { | ||
resolve(res) | ||
} | ||
else if(type === 'text') { | ||
try{ | ||
const json = eval(res)(); | ||
resolve(json); | ||
} | ||
catch(e) { | ||
resolve({}); | ||
} | ||
} | ||
}); | ||
}) | ||
}; | ||
export default (path, type) => { | ||
if(path.indexOf('/') < 0) { | ||
return; | ||
} | ||
const scope = path.split('/')[0]; | ||
const module = `./${path.replace(scope+'/', '')}`; | ||
return (props) => { | ||
return <System system={{ | ||
scope: scope, | ||
module: module, | ||
url: remoteConfig[scope] | ||
}} {...props}/> | ||
} | ||
}; | ||
const remoteEnterCache = {}; // 远程入口文件缓存 | ||
const catchModules = {}; // 远程模块缓存 | ||
const remoteConfig = {}; // 远程模块入口文件配置 | ||
function loadComponent(scope, module) { | ||
return async () => { | ||
// Initializes the share scope. This fills it with known provided modules from this build and all remotes | ||
await __webpack_init_sharing__("default"); | ||
const container = window[scope]; // or get the container somewhere else | ||
// Initialize the container, it may provide shared modules | ||
await container.init(__webpack_share_scopes__.default); | ||
const factory = await window[scope].get(module); | ||
console.log(7777888, factory) | ||
const Module = factory(); | ||
return Module; | ||
}; | ||
} | ||
const useDynamicScript = (args) => { | ||
const [ready, setReady] = React.useState(false); | ||
const [failed, setFailed] = React.useState(false); | ||
React.useEffect(() => { | ||
if (!args.url) { | ||
return; | ||
} | ||
if(remoteEnterCache[args.url]) { | ||
setReady(true); | ||
return; | ||
} | ||
const element = document.createElement("script"); | ||
element.src = args.url; | ||
element.type = "text/javascript"; | ||
element.async = true; | ||
setReady(false); | ||
setFailed(false); | ||
element.onload = () => { | ||
console.log(`Dynamic Script Loaded: ${args.url}`); | ||
remoteEnterCache[args.url] = true; | ||
setReady(true); | ||
}; | ||
element.onerror = () => { | ||
console.error(`Dynamic Script Error: ${args.url}`); | ||
setReady(false); | ||
setFailed(true); | ||
}; | ||
document.head.appendChild(element); | ||
return () => { | ||
console.log(`Dynamic Script Removed: ${args.url}`); | ||
document.head.removeChild(element); | ||
}; | ||
}, [args.url]); | ||
return { | ||
ready, | ||
failed, | ||
}; | ||
}; | ||
function System(props) { | ||
const {system = {}, ...reset} = props; | ||
const { ready, failed } = useDynamicScript({ | ||
url: system && system.url, | ||
}); | ||
if (!system) { | ||
console.error(`Not system specified`); | ||
return <></>; | ||
} | ||
if (!ready) { | ||
return <></>; | ||
} | ||
if (failed) { | ||
console.error(`Failed to load dynamic script: {system.url}`); | ||
return <></>; | ||
} | ||
let Component = catchModules[`${system.url}${system.scope}${system.module}`]; | ||
if(!Component) { | ||
const module = loadComponent(system.scope, system.module); | ||
Component = React.lazy(module); | ||
catchModules[`${system.url}${system.scope}${system.module}`] = Component; | ||
} | ||
return ( | ||
<React.Suspense fallback=""> | ||
<Component {...reset}/> | ||
</React.Suspense> | ||
); | ||
} | ||
export const setRemoteConfig = (configs) => { | ||
for(let key in configs) { | ||
remoteConfig[key] = configs[key]; | ||
} | ||
} | ||
export const loadJson = (url, type) => { | ||
return new Promise((resolve, reject) => { | ||
fetch(url) | ||
.then(function(response) { | ||
return response[type](); | ||
}) | ||
.then(function(res) { | ||
if(type === 'json') { | ||
resolve(res) | ||
} | ||
else if(type === 'text') { | ||
try{ | ||
let text = res.replace(/export\s+default\s*/, ''); | ||
const json = eval(`(function() { | ||
return ${text} | ||
})`)(); | ||
resolve(json); | ||
} | ||
catch(e) { | ||
resolve({}); | ||
} | ||
} | ||
}); | ||
}) | ||
}; | ||
export default (path, type) => { | ||
if(path.indexOf('/') < 0) { | ||
return; | ||
} | ||
const scope = path.split('/')[0]; | ||
const module = `./${path.replace(scope+'/', '')}`; | ||
return (props) => { | ||
return <System system={{ | ||
scope: scope, | ||
module: module, | ||
url: remoteConfig[scope] | ||
}} {...props}/> | ||
} | ||
}; | ||
{ | ||
"name": "import-remote-module", | ||
"version": "0.0.7", | ||
"version": "1.0.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
5001
131
1