feat(loader): rename global load to __apigo_load and add self-cleanup

This commit is contained in:
AI Engineer 2026-06-04 21:04:30 +08:00
parent 70ebb40e4f
commit 042ebe61e3
2 changed files with 53 additions and 46 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@apigo.cc/loader",
"version": "1.0.3",
"version": "1.0.4",
"type": "module",
"main": "dist/loader.js",
"module": "dist/loader.js",

View File

@ -17,65 +17,72 @@ const DEFAULT_VERSIONS = {
const Loader = {
load: (...pkgs) => {
if (typeof document === 'undefined') return;
try {
if (typeof document === 'undefined') return;
const currentScript = document.currentScript;
const currentUrl = currentScript ? currentScript.src : '';
// 1. 默认模板 (jsDelivr)
let tpl = 'https://cdn.jsdelivr.net/npm/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
const currentScript = document.currentScript;
const currentUrl = currentScript ? currentScript.src : '';
// 1. 默认模板 (jsDelivr)
let tpl = 'https://cdn.jsdelivr.net/npm/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
// 2. 根据当前 loader.js 来源自动适配镜像
if (currentUrl) {
if (currentUrl.includes('esm.sh')) {
tpl = 'https://esm.sh/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('unpkg.com')) {
tpl = 'https://unpkg.com/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('unpkg.zhimg.com')) {
tpl = 'https://unpkg.zhimg.com/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('npm.elemecdn.com')) {
tpl = 'https://npm.elemecdn.com/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('jsdelivr.net')) {
tpl = 'https://cdn.jsdelivr.net/npm/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
// 2. 根据当前 loader.js 来源自动适配镜像
if (currentUrl) {
if (currentUrl.includes('esm.sh')) {
tpl = 'https://esm.sh/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('unpkg.com')) {
tpl = 'https://unpkg.com/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('unpkg.zhimg.com')) {
tpl = 'https://unpkg.zhimg.com/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('npm.elemecdn.com')) {
tpl = 'https://npm.elemecdn.com/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
} else if (currentUrl.includes('jsdelivr.net')) {
tpl = 'https://cdn.jsdelivr.net/npm/@apigo.cc/{project}@{tag}/dist/{project}.min.js';
}
}
}
const importMap = { imports: {} };
const importMap = { imports: {} };
pkgs.forEach(pkg => {
// 支持格式 'name' 或 'name:version' 或 'name:path' (如 'bootstrap:http://localhost:5173/src/index.js')
const colonIdx = pkg.indexOf(':');
const name = colonIdx === -1 ? pkg : pkg.slice(0, colonIdx);
let version = colonIdx === -1 ? '' : pkg.slice(colonIdx + 1);
pkgs.forEach(pkg => {
// 支持格式 'name' 或 'name:version' 或 'name:path' (如 'bootstrap:http://localhost:5173/src/index.js')
const colonIdx = pkg.indexOf(':');
const name = colonIdx === -1 ? pkg : pkg.slice(0, colonIdx);
let version = colonIdx === -1 ? '' : pkg.slice(colonIdx + 1);
const key = name.toLowerCase();
const fullKey = `@apigo.cc/${key}`;
const key = name.toLowerCase();
const fullKey = `@apigo.cc/${key}`;
let url = '';
// 如果 version 包含 http://, https://, ./, ../, / 说明是自定义路径,直接作为调试或重定向地址
if (version && (/^(https?:|\.|\/)/.test(version))) {
url = version;
let url = '';
// 如果 version 包含 http://, https://, ./, ../, / 说明是自定义路径,直接作为调试或重定向地址
if (version && (/^(https?:|\.|\/)/.test(version))) {
url = version;
} else {
version = version || DEFAULT_VERSIONS[key] || 'latest';
url = tpl.replace(/{project}/g, key).replace(/{tag}/g, version);
}
importMap.imports[fullKey] = url;
});
const script = document.createElement('script');
script.type = 'importmap';
script.textContent = JSON.stringify(importMap);
if (currentScript) {
currentScript.parentNode.insertBefore(script, currentScript);
} else {
version = version || DEFAULT_VERSIONS[key] || 'latest';
url = tpl.replace(/{project}/g, key).replace(/{tag}/g, version);
document.head.appendChild(script);
}
} finally {
// 运行后自动删除,防止全局污染
if (typeof globalThis !== 'undefined' && globalThis.__apigo_load) {
delete globalThis.__apigo_load;
}
importMap.imports[fullKey] = url;
});
const script = document.createElement('script');
script.type = 'importmap';
script.textContent = JSON.stringify(importMap);
if (currentScript) {
currentScript.parentNode.insertBefore(script, currentScript);
} else {
document.head.appendChild(script);
}
}
};
// 挂载到全局
globalThis.Loader = Loader;
globalThis.__apigo_load = Loader.load;
export { Loader };
export default Loader;