interface File {
type: 'js'|'css';
url: string;
}
type libKey = 'mtstatSdk'|'elementUI'|'weChatJSSDK';
const libMap: Record<libKey, {
files: File[];
loaded: boolean;
}> = {
jsName: {
files: [{
type: 'js',
url: 'xxx.js',
}],
loaded: false,
},
elementUI: {
files: [{
type: 'js',
url: '//cdn.staticfile.org/element-ui/2.15.1/index.min.js',
}, {
type: 'css',
url: '//cdn.staticfile.org/element-ui/2.15.1/theme-chalk/index.min.css',
}],
loaded: false,
},
weChatJSSDK: {
files: [{
type: 'js',
url: 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js',
}],
loaded: false,
},
};
function loadJsFile(file: File): Promise<void> {
return new Promise((resolve, reject) => {
try {
const script = document.createElement('script');
script.src = file.url;
script.onload = () => {
resolve();
};
setTimeout(() => {
reject(new Error(`Failed to load file: ${file.url}`));
}, 3000);
document.body.appendChild(script);
} catch (e) {
reject();
}
});
}
function loadCssFile(file: File): Promise<void> {
return new Promise((resolve, reject) => {
try {
const link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.href = file.url;
link.onload = () => {
resolve();
};
document.body.appendChild(link);
} catch (e) {
reject();
}
});
}
// eslint-disable-next-line import/prefer-default-export
export async function ensure(libKey: libKey): Promise<void> {
const lib = libMap[libKey];
if (!lib) {
throw new Error(`Invalid libKey: ${libKey}`);
}
if (lib.loaded === true) return;
await Promise.all(
lib.files.map(file => {
if (file.type === 'js') {
return loadJsFile(file);
}
if (file.type === 'css') {
return loadCssFile(file);
}
return Promise.resolve();
}),
).then(() => {
lib.loaded = true;
});
}