From 0bfa055056788c51dd5edb838ee12b94ae36a403 Mon Sep 17 00:00:00 2001 From: xion Date: Fri, 25 Jul 2025 23:18:48 +0800 Subject: [PATCH] init --- .npmignore | 2 + .npmrc | 3 ++ css/reset.css | 38 ++++++++++++++ import-map.js | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 20 +++++++ 5 files changed, 205 insertions(+) create mode 100644 .npmignore create mode 100644 .npmrc create mode 100644 css/reset.css create mode 100644 import-map.js create mode 100644 package.json diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..3971b81 --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +.npmrc +tests/ \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..0a2c6cd --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN} +//registry.npmjs.org/:_authToken=${NPM_TOKEN} +ignore-workspace-root-check=true \ No newline at end of file diff --git a/css/reset.css b/css/reset.css new file mode 100644 index 0000000..0295f5d --- /dev/null +++ b/css/reset.css @@ -0,0 +1,38 @@ + +/* Base Reset CSS */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} +html { + height: 100%; + overflow: hidden; +} +body { + height: 100%; +} +#root { + height: 100%; + overflow: auto; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +img, picture, video, canvas, svg { + display: block; + max-width: 100%; +} + +input, button, textarea, select { + font: inherit; +} + +p, h1, h2, h3, h4, h5, h6 { + overflow-wrap: break-word; +} \ No newline at end of file diff --git a/import-map.js b/import-map.js new file mode 100644 index 0000000..ceeca2a --- /dev/null +++ b/import-map.js @@ -0,0 +1,142 @@ +// 生成缓存键,基于当前模块的URL +const getCacheKey = () => { + const url = new URL(import.meta.url); + const basePath = url.pathname.replace('/import-map.js', ''); + 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 { render } = await import('main'); + render(); +}; + +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(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..28613de --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "@kevisual/native", + "version": "0.0.1", + "description": "", + "main": "index.js", + "files": [ + "*" + ], + "publishConfig": { + "access": "public" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "abearxiong (https://www.xiongxiao.me)", + "license": "MIT", + "packageManager": "pnpm@10.7.0", + "type": "module" +} \ No newline at end of file