删除attrUpdateMatrix中多余的数据
This commit is contained in:
parent
9f6476673a
commit
42047f650a
|
|
@ -0,0 +1,131 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class CdnLoaderPlugin {
|
||||||
|
constructor(options) {
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
apply(compiler) {
|
||||||
|
compiler.hooks.emit.tapAsync('CdnLoaderPlugin', (compilation, callback) => {
|
||||||
|
// 生成 loadFromCdn.js 内容
|
||||||
|
const cdnLoaderContent = this.generateCdnLoaderContent();
|
||||||
|
|
||||||
|
// 将 loadFromCdn.js 添加到输出文件中
|
||||||
|
compilation.assets['loadFromCdn.js'] = {
|
||||||
|
source: () => cdnLoaderContent,
|
||||||
|
size: () => cdnLoaderContent.length
|
||||||
|
};
|
||||||
|
|
||||||
|
// 修改 HTML 文件
|
||||||
|
Object.keys(compilation.assets).forEach(filename => {
|
||||||
|
if (filename.endsWith('.html')) {
|
||||||
|
const asset = compilation.assets[filename];
|
||||||
|
let content = asset.source();
|
||||||
|
|
||||||
|
// 替换入口脚本的加载方式
|
||||||
|
content = content.replace(
|
||||||
|
/<script.*?src="(.*?)".*?><\/script>/,
|
||||||
|
`<script src="loadFromCdn.js"></script>
|
||||||
|
<script>
|
||||||
|
loadExternals().then(() => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = "$1";
|
||||||
|
document.body.appendChild(script);
|
||||||
|
});
|
||||||
|
</script>`
|
||||||
|
);
|
||||||
|
|
||||||
|
compilation.assets[filename] = {
|
||||||
|
source: () => content,
|
||||||
|
size: () => content.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
generateCdnLoaderContent() {
|
||||||
|
const { from, module, timeout, retry } = this.options;
|
||||||
|
|
||||||
|
const cdnUrls = Object.entries(module).reduce((acc, [name, config]) => {
|
||||||
|
acc[name] = config.direct? [config.js] : Array.isArray(from) ? from.map(url => `${url}/${name}/${config.version}/${config.js}`) : [`${from}/${name}/${config.version}/${config.js}`];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
return `
|
||||||
|
const GLOBAL_CONFIG = {
|
||||||
|
TIMEOUT: ${timeout},
|
||||||
|
MAX_RETRIES: ${retry},
|
||||||
|
onLoadError: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const cdnUrls = ${JSON.stringify(cdnUrls, null, 2)};
|
||||||
|
|
||||||
|
function loadScriptWithTimeout(url, timeout) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = url;
|
||||||
|
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
reject(new Error(\`Loading \${url} timed out\`));
|
||||||
|
}, timeout);
|
||||||
|
|
||||||
|
script.onload = () => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
resolve(script);
|
||||||
|
};
|
||||||
|
|
||||||
|
script.onerror = () => {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
reject(new Error(\`Failed to load \${url}\`));
|
||||||
|
};
|
||||||
|
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadLibraryWithRetry(library, retryCount = 0) {
|
||||||
|
const controllers = cdnUrls[library].map(() => new AbortController());
|
||||||
|
|
||||||
|
try {
|
||||||
|
const loadPromises = cdnUrls[library].map((url, index) => {
|
||||||
|
return loadScriptWithTimeout(url, GLOBAL_CONFIG.TIMEOUT)
|
||||||
|
.then(script => {
|
||||||
|
controllers.forEach((controller, i) => {
|
||||||
|
if (i !== index) controller.abort();
|
||||||
|
});
|
||||||
|
return script;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return await Promise.any(loadPromises);
|
||||||
|
} catch (error) {
|
||||||
|
if (retryCount < GLOBAL_CONFIG.MAX_RETRIES) {
|
||||||
|
console.warn(\`Retry loading \${library}, attempt \${retryCount + 1}\`);
|
||||||
|
return loadLibraryWithRetry(library, retryCount + 1);
|
||||||
|
} else {
|
||||||
|
if (GLOBAL_CONFIG.onLoadError) {
|
||||||
|
GLOBAL_CONFIG.onLoadError(library, error);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadExternals() {
|
||||||
|
const libraries = Object.keys(cdnUrls);
|
||||||
|
return Promise.all(libraries.map(library => loadLibraryWithRetry(library)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认的错误处理函数
|
||||||
|
GLOBAL_CONFIG.onLoadError = (library, error) => {
|
||||||
|
console.error(\`Failed to load \${library} after \${GLOBAL_CONFIG.MAX_RETRIES} retries:\`, error);
|
||||||
|
};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = CdnLoaderPlugin;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
export type CdnConfig = {
|
||||||
|
from: string | string[],
|
||||||
|
module: {
|
||||||
|
[name: string]: ModuleConfig
|
||||||
|
},
|
||||||
|
timeout: number,
|
||||||
|
retry: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ModuleConfig = {
|
||||||
|
scope: string,
|
||||||
|
version: string,
|
||||||
|
js: string,
|
||||||
|
css?: string,
|
||||||
|
// js和css是否直接是链接
|
||||||
|
direct?: boolean,
|
||||||
|
}
|
||||||
|
|
@ -3,13 +3,13 @@ import { EntityDict } from '@project/oak-app-domain';
|
||||||
|
|
||||||
|
|
||||||
const attrUpdateMatrix: AttrUpdateMatrix<EntityDict> = {
|
const attrUpdateMatrix: AttrUpdateMatrix<EntityDict> = {
|
||||||
store: {
|
// store: {
|
||||||
name: {
|
// name: {
|
||||||
filter: {
|
// filter: {
|
||||||
iState: 'offline',
|
// iState: 'offline',
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
}
|
}
|
||||||
|
|
||||||
export default attrUpdateMatrix;
|
export default attrUpdateMatrix;
|
||||||
Loading…
Reference in New Issue