152 lines
4.0 KiB
JavaScript
152 lines
4.0 KiB
JavaScript
const getCacheKey = () => {
|
||
// 基于import map文件的路径,而不是当前模块的URL
|
||
const url = new URL('./imports.json', window.location.href);
|
||
const basePath = url.pathname.replace('/imports.json', '');
|
||
return `importMap_${btoa(basePath).replace(/[+/=]/g, '_')}`;
|
||
};
|
||
const getCurrentScriptData = () => {
|
||
try {
|
||
const script = document.getElementById('importmap');
|
||
if (script) {
|
||
return {
|
||
run: script.dataset.run !== 'false',
|
||
// 可以获取其他data属性
|
||
element: script,
|
||
};
|
||
}
|
||
} catch (error) {
|
||
console.warn('Error finding script with id "importmap":', error);
|
||
}
|
||
|
||
return { run: true, element: null };
|
||
};
|
||
// 从localStorage获取缓存
|
||
const getCachedImportMap = () => {
|
||
try {
|
||
const cacheKey = getCacheKey();
|
||
const cached = localStorage.getItem(cacheKey);
|
||
if (cached) {
|
||
const { data, timestamp } = JSON.parse(cached);
|
||
|
||
// 检查缓存是否过期(1天 = 24 * 60 * 60 * 1000 毫秒)
|
||
const oneDay = 24 * 60 * 60 * 1000;
|
||
const isExpired = Date.now() - timestamp > oneDay;
|
||
if (isExpired) {
|
||
localStorage.removeItem(cacheKey);
|
||
return null;
|
||
}
|
||
return { data, timestamp };
|
||
}
|
||
} catch (error) {
|
||
console.warn('Error reading cache:', error);
|
||
}
|
||
return null;
|
||
};
|
||
|
||
// 保存到localStorage
|
||
const setCachedImportMap = (data) => {
|
||
try {
|
||
const cacheKey = getCacheKey();
|
||
const cacheData = {
|
||
data,
|
||
timestamp: Date.now(),
|
||
url: import.meta.url,
|
||
};
|
||
localStorage.setItem(cacheKey, JSON.stringify(cacheData));
|
||
console.log('Import map cached to localStorage');
|
||
} catch (error) {
|
||
console.warn('Error saving cache:', error);
|
||
}
|
||
};
|
||
|
||
// 创建import map脚本元素
|
||
const createImportMapScript = (data) => {
|
||
const script = document.createElement('script');
|
||
script.type = 'importmap';
|
||
script.textContent = JSON.stringify(data);
|
||
document.head.appendChild(script);
|
||
};
|
||
|
||
const loadErrorDefualt = () => {
|
||
const baseImportMap = {
|
||
imports: {
|
||
main: './index.js',
|
||
},
|
||
};
|
||
|
||
createImportMapScript(baseImportMap);
|
||
console.log('Loaded default import map (not cached due to error)');
|
||
};
|
||
|
||
const loadImportMap = async () => {
|
||
try {
|
||
// 首先尝试从缓存加载
|
||
const cached = getCachedImportMap();
|
||
if (cached) {
|
||
createImportMapScript(cached.data);
|
||
// 后台更新缓存(可选:如果想要每次都检查更新的话)
|
||
// 注释掉下面这行可以完全依赖缓存,直到手动清除
|
||
// updateCacheInBackground();
|
||
|
||
return;
|
||
}
|
||
const response = await fetch('./imports.json');
|
||
if (!response.ok) {
|
||
throw new Error(`HTTP error! status: ${response.status}`);
|
||
}
|
||
const data = await response.json();
|
||
|
||
// 创建import map并缓存
|
||
createImportMapScript(data);
|
||
setCachedImportMap(data);
|
||
} catch (error) {
|
||
// 错误情况下不缓存,直接使用默认配置
|
||
loadErrorDefualt();
|
||
console.error('Error loading import map:', error);
|
||
}
|
||
};
|
||
|
||
// 后台更新缓存(可选功能)
|
||
export const updateCacheInBackground = async () => {
|
||
try {
|
||
const response = await fetch('./imports.json');
|
||
if (response.ok) {
|
||
const data = await response.json();
|
||
setCachedImportMap(data);
|
||
console.log('Cache updated in background');
|
||
}
|
||
} catch (error) {
|
||
console.warn('Background cache update failed:', error);
|
||
}
|
||
};
|
||
|
||
const runMain = async () => {
|
||
const sourceCode = `
|
||
import { render } from 'main';
|
||
render();`;
|
||
try {
|
||
const script = document.createElement('script');
|
||
script.type = 'module';
|
||
script.textContent = sourceCode;
|
||
document.body.appendChild(script);
|
||
} catch (error) {
|
||
console.error('Error executing source code:', error);
|
||
}
|
||
};
|
||
|
||
const main = async () => {
|
||
const { run, element } = getCurrentScriptData();
|
||
if (!run) {
|
||
console.log('Script execution is disabled by data-run attribute');
|
||
return;
|
||
}
|
||
try {
|
||
await loadImportMap();
|
||
} catch (error) {
|
||
console.error('Error loading import map:', error);
|
||
}
|
||
await runMain();
|
||
};
|
||
|
||
main();
|