vv-template-html 0.0.1-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ {
2
+ "liveServer.settings.port": 5501
3
+ }
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # vv-template-html
2
+
3
+ 轻量级的 HTML 模板加载与渲染库(TemplateHTML)。
4
+
5
+ ## 特性
6
+ - 全局单例:TemplateHTML
7
+ - 按需加载并缓存模板(.html)
8
+ - 简单的渲染 API:getTemplate / render
9
+ - 支持多种 baseUrl 格式
10
+ - 提供 TypeScript 类型定义
11
+
12
+ ## 安装与构建
13
+ 开发依赖使用 esbuild 打包:
14
+ ```bash
15
+ npm install
16
+ npm run build # 会调用 esbuild.config.js,生成 template-html.min.js
17
+ ```
18
+
19
+ ## 快速开始
20
+ 在页面中引入构建产物:
21
+ ```html
22
+ <script src="template-html.min.js"></script>
23
+ <script>
24
+ (async function(){
25
+ console.log(TemplateHTML.VERSION);
26
+ TemplateHTML.baseUrl = '/template/'; // 可选
27
+ await TemplateHTML.render('main', document.body);
28
+ })();
29
+ </script>
30
+ ```
31
+
32
+ ## API 概览
33
+ - TemplateHTML.VERSION: string(只读)
34
+ - TemplateHTML.baseUrl: string(可读写,支持多种格式)
35
+ - TemplateHTML.templates: { [key: string]: HTMLElement }(只读缓存)
36
+ - TemplateHTML.getTemplate(templateName: string): Promise<HTMLElement>
37
+ - TemplateHTML.render(templateName: string, element: HTMLElement): Promise<void>
38
+
39
+ 自定义错误类:TemplateHTMLError(继承自 Error)
40
+
41
+ ## baseUrl 支持格式
42
+ - file:// 协议路径
43
+ - 以 `/`、`./`、`../` 开头的相对路径(会基于 location.origin 解析)
44
+ - http:// 或 https:// 完整 URL
45
+
46
+ 设置示例:
47
+ ```js
48
+ TemplateHTML.baseUrl = 'file:///C:/templates/';
49
+ TemplateHTML.baseUrl = '/template/';
50
+ TemplateHTML.baseUrl = 'https://cdn.example.com/templates/';
51
+ ```
52
+
53
+ ## 错误处理
54
+ - 无效模板名、无法加载、模板空等情况会抛出 TemplateHTMLError,请在调用处捕获处理。
55
+
56
+ ## TypeScript
57
+ 项目包含类型定义文件 `template-html.d.ts`,在 TypeScript 项目中可直接使用全局 TemplateHTML 和 TemplateHTMLError 类型。
58
+
59
+ ## 贡献与许可
60
+ - 作者:IFTC
61
+ - 许可证:MIT
62
+
63
+ 欢迎提交 issue 或 PR 以改进功能或修复 Bug。
@@ -0,0 +1,32 @@
1
+ const esbuild = require('esbuild');
2
+ const mangleCache = {};
3
+ esbuild.build({
4
+ entryPoints: ['index.js'],
5
+ bundle: true,
6
+ outfile: 'template-html.min.js',
7
+ minify: true,
8
+ minifyWhitespace: true,
9
+ minifyIdentifiers: true,
10
+ minifySyntax: true,
11
+ treeShaking: true,
12
+ format: 'esm',
13
+ sourcemap: true,
14
+ platform: 'browser',
15
+ target: ["chrome58", "firefox57", "safari11", "edge16"],
16
+ drop: ['console', 'debugger'],
17
+ define: {
18
+ VERSION: JSON.stringify(require('./package.json').version)
19
+ },
20
+ charset: 'utf8',
21
+ ignoreAnnotations: true,
22
+ mangleProps: /^_/,
23
+ mangleCache: mangleCache,
24
+ target: ['chrome58', 'firefox57', 'safari11', 'edge16'],
25
+ }).then(result => {
26
+ console.log("缓存压缩结果:", mangleCache);
27
+ console.log('Build completed successfully.');
28
+ }).catch(e => {
29
+ console.error('Error during build.');
30
+ console.error(e);
31
+ process.exit(1);
32
+ });
package/index.html ADDED
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Document</title>
8
+ <script src="template-html.min.js"></script>
9
+ </head>
10
+
11
+ <body>
12
+ <script>
13
+ (async function () {
14
+ console.log(TemplateHTML.VERSION);
15
+ const main = await TemplateHTML.getTemplate('main');
16
+ console.log(main);
17
+ TemplateHTML.render("main", document.body);
18
+ })();
19
+ </script>
20
+ </body>
21
+
22
+ </html>
package/index.js ADDED
@@ -0,0 +1,85 @@
1
+ globalThis.TemplateHTML = (function () {
2
+ class TemplateHTMLError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "TemplateHTMLError";
6
+ }
7
+ }
8
+ const obj = {};
9
+ const templates = {};
10
+ let baseUrl = location.origin + "/template/";
11
+ Object.defineProperties(obj, {
12
+ VERSION: {
13
+ value: VERSION,
14
+ writable: false,
15
+ enumerable: true,
16
+ configurable: false,
17
+ },
18
+ baseUrl: {
19
+ get: function () {
20
+ return baseUrl;
21
+ },
22
+ set: function (value) {
23
+ if (value.startsWith("file://")) {
24
+ baseUrl = value;
25
+ } else if (value.startsWith("/") || value.startsWith("./") || value.startsWith("../")) {
26
+ baseUrl = new URL(value, location.origin).href;
27
+ } else if (value.startsWith("http://") || value.startsWith("https://")) {
28
+ baseUrl = value;
29
+ } else {
30
+ throw new TemplateHTMLError("Invalid baseUrl format");
31
+ }
32
+ },
33
+ enumerable: true,
34
+ configurable: false,
35
+ },
36
+ templates: {
37
+ get: function () {
38
+ return templates;
39
+ },
40
+ set: function (value) {
41
+ throw new TemplateHTMLError("templates cannot be set");
42
+ },
43
+ enumerable: true,
44
+ configurable: false,
45
+ },
46
+ getTemplate: {
47
+ value: async function (templateName) {
48
+ if (!templateName) {
49
+ throw new TemplateHTMLError("Template name is required");
50
+ }
51
+ if (templates[templateName]) {
52
+ return templates[templateName];
53
+ }
54
+ try {
55
+ const r = await fetch(baseUrl + templateName + ".html");
56
+ if (!r.ok) {
57
+ throw new TemplateHTMLError("cannot load template");
58
+ }
59
+ const parser = new DOMParser();
60
+ const template = await r.text();
61
+ const doc = parser.parseFromString(template, "text/html");
62
+ if (!doc.body.children[0]) {
63
+ throw new TemplateHTMLError("template is empty");
64
+ }
65
+ templates[templateName] = doc.body.children[0];
66
+ return templates[templateName];
67
+ } catch (e) {
68
+ throw new TemplateHTMLError("cannot load template. " + e.message);
69
+ }
70
+ },
71
+ enumerable: true,
72
+ configurable: false,
73
+ },
74
+ render: {
75
+ value: async function (templateName, element) {
76
+ const template = await TemplateHTML.getTemplate(templateName);
77
+ element.appendChild(template.cloneNode(true));
78
+ },
79
+ enumerable: true,
80
+ configurable: false,
81
+ writable: false,
82
+ }
83
+ });
84
+ return obj;
85
+ })();
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "vv-template-html",
3
+ "version": "0.0.1-beta",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "build": "node esbuild.config.js"
7
+ },
8
+ "keywords": [
9
+ "IFTC",
10
+ "HTML",
11
+ "TemplateHTML"
12
+ ],
13
+ "author": "IFTC",
14
+ "license": "MIT",
15
+ "description": "A lightweight HTML template engine for JavaScript",
16
+ "devDependencies": {
17
+ "esbuild": "0.27.2"
18
+ }
19
+ }
@@ -0,0 +1,3 @@
1
+ <div id="app">
2
+ <h1>Hello, TemplateHTML!</h1>
3
+ </div>
@@ -0,0 +1,57 @@
1
+ /**
2
+ * 类型定义文件 - 为 TemplateHTML 库提供类型支持
3
+ */
4
+ declare global {
5
+ /**
6
+ * TemplateHTML 库的主要命名空间对象
7
+ */
8
+ const TemplateHTML: {
9
+ /**
10
+ * 当前库的版本号
11
+ */
12
+ readonly VERSION: string;
13
+
14
+ /**
15
+ * 基础URL,用于模板加载的根路径
16
+ * 支持以下格式:
17
+ * - file:// 协议
18
+ * - 以 /, ./, ../ 开头的相对路径
19
+ * - http:// 或 https:// 协议
20
+ */
21
+ baseUrl: string;
22
+
23
+ /**
24
+ * 已加载的模板缓存
25
+ */
26
+ readonly templates: { [key: string]: HTMLElement };
27
+
28
+ /**
29
+ * 获取指定名称的模板
30
+ * @param templateName 模板名称
31
+ * @returns 返回模板的 HTMLElement
32
+ */
33
+ getTemplate(templateName: string): Promise<HTMLElement>;
34
+
35
+ /**
36
+ * 渲染指定名称的模板到指定元素
37
+ * @param templateName 模板名称
38
+ * @param element 要渲染到的目标元素
39
+ */
40
+ render(templateName: string, element: HTMLElement): Promise<void>;
41
+ };
42
+
43
+ /**
44
+ * TemplateHTML 自定义错误类
45
+ */
46
+ class TemplateHTMLError extends Error {
47
+ constructor(message: string);
48
+ name: "TemplateHTMLError";
49
+ }
50
+ }
51
+
52
+ export {};
53
+
54
+ /**
55
+ * VERSION 常量需要在全局作用域中定义
56
+ */
57
+ declare const VERSION: string;
@@ -0,0 +1,2 @@
1
+ globalThis.TemplateHTML=(function(){class r extends Error{constructor(t){super(t),this.name="TemplateHTMLError"}}let o={},n={},a=location.origin+"/template/";return Object.defineProperties(o,{VERSION:{value:"0.0.1-beta",writable:!1,enumerable:!0,configurable:!1},baseUrl:{get:function(){return a},set:function(e){if(e.startsWith("file://"))a=e;else if(e.startsWith("/")||e.startsWith("./")||e.startsWith("../"))a=new URL(e,location.origin).href;else if(e.startsWith("http://")||e.startsWith("https://"))a=e;else throw new r("Invalid baseUrl format")},enumerable:!0,configurable:!1},templates:{get:function(){return n},set:function(e){throw new r("templates cannot be set")},enumerable:!0,configurable:!1},getTemplate:{value:async function(e){if(!e)throw new r("Template name is required");if(n[e])return n[e];try{let t=await fetch(a+e+".html");if(!t.ok)throw new r("cannot load template");let s=new DOMParser,l=await t.text(),i=s.parseFromString(l,"text/html");if(!i.body.children[0])throw new r("template is empty");return n[e]=i.body.children[0],n[e]}catch(t){throw new r("cannot load template. "+t.message)}},enumerable:!0,configurable:!1},render:{value:async function(e,t){let s=await TemplateHTML.getTemplate(e);t.appendChild(s.cloneNode(!0))},enumerable:!0,configurable:!1,writable:!1}}),o})();
2
+ //# sourceMappingURL=template-html.min.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["index.js"],
4
+ "sourcesContent": ["globalThis.TemplateHTML = (function () {\r\n class TemplateHTMLError extends Error {\r\n constructor(message) {\r\n super(message);\r\n this.name = \"TemplateHTMLError\";\r\n }\r\n }\r\n const obj = {};\r\n const templates = {};\r\n let baseUrl = location.origin + \"/template/\";\r\n Object.defineProperties(obj, {\r\n VERSION: {\r\n value: VERSION,\r\n writable: false,\r\n enumerable: true,\r\n configurable: false,\r\n },\r\n baseUrl: {\r\n get: function () {\r\n return baseUrl;\r\n },\r\n set: function (value) {\r\n if (value.startsWith(\"file://\")) {\r\n baseUrl = value;\r\n } else if (value.startsWith(\"/\") || value.startsWith(\"./\") || value.startsWith(\"../\")) {\r\n baseUrl = new URL(value, location.origin).href;\r\n } else if (value.startsWith(\"http://\") || value.startsWith(\"https://\")) {\r\n baseUrl = value;\r\n } else {\r\n throw new TemplateHTMLError(\"Invalid baseUrl format\");\r\n }\r\n },\r\n enumerable: true,\r\n configurable: false,\r\n },\r\n templates: {\r\n get: function () {\r\n return templates;\r\n },\r\n set: function (value) {\r\n throw new TemplateHTMLError(\"templates cannot be set\");\r\n },\r\n enumerable: true,\r\n configurable: false,\r\n },\r\n getTemplate: {\r\n value: async function (templateName) {\r\n if (!templateName) {\r\n throw new TemplateHTMLError(\"Template name is required\");\r\n }\r\n if (templates[templateName]) {\r\n return templates[templateName];\r\n }\r\n try {\r\n const r = await fetch(baseUrl + templateName + \".html\");\r\n if (!r.ok) {\r\n throw new TemplateHTMLError(\"cannot load template\");\r\n }\r\n const parser = new DOMParser();\r\n const template = await r.text();\r\n const doc = parser.parseFromString(template, \"text/html\");\r\n if (!doc.body.children[0]) {\r\n throw new TemplateHTMLError(\"template is empty\");\r\n }\r\n templates[templateName] = doc.body.children[0];\r\n return templates[templateName];\r\n } catch (e) {\r\n throw new TemplateHTMLError(\"cannot load template. \" + e.message);\r\n }\r\n },\r\n enumerable: true,\r\n configurable: false,\r\n },\r\n render: {\r\n value: async function (templateName, element) {\r\n const template = await TemplateHTML.getTemplate(templateName);\r\n element.appendChild(template.cloneNode(true));\r\n },\r\n enumerable: true,\r\n configurable: false,\r\n writable: false,\r\n }\r\n });\r\n return obj;\r\n})();"],
5
+ "mappings": "AAAA,WAAW,cAAgB,UAAY,CACnC,MAAMA,UAA0B,KAAM,CAClC,YAAYC,EAAS,CACjB,MAAMA,CAAO,EACb,KAAK,KAAO,mBAChB,CACJ,CACA,IAAMC,EAAM,CAAC,EACPC,EAAY,CAAC,EACfC,EAAU,SAAS,OAAS,aAChC,cAAO,iBAAiBF,EAAK,CACzB,QAAS,CACL,MAAO,aACP,SAAU,GACV,WAAY,GACZ,aAAc,EAClB,EACA,QAAS,CACL,IAAK,UAAY,CACb,OAAOE,CACX,EACA,IAAK,SAAUC,EAAO,CAClB,GAAIA,EAAM,WAAW,SAAS,EAC1BD,EAAUC,UACHA,EAAM,WAAW,GAAG,GAAKA,EAAM,WAAW,IAAI,GAAKA,EAAM,WAAW,KAAK,EAChFD,EAAU,IAAI,IAAIC,EAAO,SAAS,MAAM,EAAE,aACnCA,EAAM,WAAW,SAAS,GAAKA,EAAM,WAAW,UAAU,EACjED,EAAUC,MAEV,OAAM,IAAIL,EAAkB,wBAAwB,CAE5D,EACA,WAAY,GACZ,aAAc,EAClB,EACA,UAAW,CACP,IAAK,UAAY,CACb,OAAOG,CACX,EACA,IAAK,SAAUE,EAAO,CAClB,MAAM,IAAIL,EAAkB,yBAAyB,CACzD,EACA,WAAY,GACZ,aAAc,EAClB,EACA,YAAa,CACT,MAAO,eAAgBM,EAAc,CACjC,GAAI,CAACA,EACD,MAAM,IAAIN,EAAkB,2BAA2B,EAE3D,GAAIG,EAAUG,CAAY,EACtB,OAAOH,EAAUG,CAAY,EAEjC,GAAI,CACA,IAAMC,EAAI,MAAM,MAAMH,EAAUE,EAAe,OAAO,EACtD,GAAI,CAACC,EAAE,GACH,MAAM,IAAIP,EAAkB,sBAAsB,EAEtD,IAAMQ,EAAS,IAAI,UACbC,EAAW,MAAMF,EAAE,KAAK,EACxBG,EAAMF,EAAO,gBAAgBC,EAAU,WAAW,EACxD,GAAI,CAACC,EAAI,KAAK,SAAS,CAAC,EACpB,MAAM,IAAIV,EAAkB,mBAAmB,EAEnD,OAAAG,EAAUG,CAAY,EAAII,EAAI,KAAK,SAAS,CAAC,EACtCP,EAAUG,CAAY,CACjC,OAASK,EAAG,CACR,MAAM,IAAIX,EAAkB,yBAA2BW,EAAE,OAAO,CACpE,CACJ,EACA,WAAY,GACZ,aAAc,EAClB,EACA,OAAQ,CACJ,MAAO,eAAgBL,EAAcM,EAAS,CAC1C,IAAMH,EAAW,MAAM,aAAa,YAAYH,CAAY,EAC5DM,EAAQ,YAAYH,EAAS,UAAU,EAAI,CAAC,CAChD,EACA,WAAY,GACZ,aAAc,GACd,SAAU,EACd,CACJ,CAAC,EACMP,CACX,GAAG",
6
+ "names": ["TemplateHTMLError", "message", "obj", "templates", "baseUrl", "value", "templateName", "r", "parser", "template", "doc", "e", "element"]
7
+ }