@flun/html-template 4.0.10
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.
- package/.env +9 -0
- package/LICENSE +15 -0
- package/build.js +3 -0
- package/compile.js +349 -0
- package/copy-files.js +200 -0
- package/customize/account.js +726 -0
- package/customize/data.json +484 -0
- package/customize/functions.js +48 -0
- package/customize/hotReloadInjector.js +25 -0
- package/customize/routes.js +141 -0
- package/customize/users.json +44 -0
- package/customize/variables.js +70 -0
- package/dev-server.js +344 -0
- package/dev.js +4 -0
- package/f-CHANGELOG.md +4 -0
- package/f-README.md +485 -0
- package/index.d.ts +133 -0
- package/index.js +4 -0
- package/package.json +77 -0
- package/restoreDefaults.js +8 -0
- package/services/templateService.js +962 -0
- package/static/about.css +118 -0
- package/static/auth.js +27 -0
- package/static/constants.css +138 -0
- package/static/img/dark.png +0 -0
- package/static/img/favicon.ico +0 -0
- package/static/img/light.png +0 -0
- package/static/img/top.png +0 -0
- package/static/index.css +86 -0
- package/static/mouseOrTouch.js +156 -0
- package/static/public.css +288 -0
- package/static/script.css +318 -0
- package/static/script.js +392 -0
- package/static/styling.css +874 -0
- package/static/styling.js +933 -0
- package/static/themeImg.css +10 -0
- package/static/themeImg.js +19 -0
- package/static/themeModule.js +222 -0
- package/static/topImg.css +19 -0
- package/static/topImg.js +21 -0
- package/static/utils/browser13.js +270 -0
- package/static/utils/closebrackets.js +166 -0
- package/static/utils/css-lint.js +308 -0
- package/static/utils/custom-css-hint.js +876 -0
- package/static/utils/foldgutter.js +141 -0
- package/static/utils/match-highlighter.js +70 -0
- package/templates/about.html +236 -0
- package/templates/account/2fa.html +184 -0
- package/templates/account/forgot-password.html +226 -0
- package/templates/account/login.html +230 -0
- package/templates/account/profile.html +977 -0
- package/templates/account/register.html +224 -0
- package/templates/account/reset-password.html +205 -0
- package/templates/account/verify-email.html +163 -0
- package/templates/base.html +71 -0
- package/templates/footer-content.html +5 -0
- package/templates/index.html +140 -0
- package/templates/script.html +209 -0
- package/templates/test-include.html +11 -0
package/f-README.md
ADDED
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
# HTML模板工具包
|
|
2
|
+
|
|
3
|
+
### 本包基于 ESM 模块系统编写->拥抱未来趋势
|
|
4
|
+
|
|
5
|
+
- **推荐方式**:使用 `import` / `export` 语法,静态分析更友好,工具链兼容性最佳;
|
|
6
|
+
- **兼容方式**:Node.js ≥ 23.5.0 原生支持 `require(esm)`;22.12+ 需开启 `--experimental-require-module` 标志;
|
|
7
|
+
- **重要**:本文档所有示例均采用 **ESM 标准**,请确保你的项目 `package.json` 中已设置 `"type": "module"`,或将脚本后缀改为 `.mjs`;
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 架构概览
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
graph TB
|
|
15
|
+
subgraph 输入源
|
|
16
|
+
U[用户扩展]
|
|
17
|
+
T[模板文件]
|
|
18
|
+
S[静态资源]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
subgraph 核心引擎
|
|
22
|
+
E[模板引擎]
|
|
23
|
+
F[继承系统]
|
|
24
|
+
G[区块替换]
|
|
25
|
+
H[变量处理]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
subgraph 开发环境
|
|
29
|
+
A[开发服务器]
|
|
30
|
+
B[实时渲染]
|
|
31
|
+
C[热重载]
|
|
32
|
+
D[静态服务]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
subgraph 生产环境
|
|
36
|
+
P[编译系统]
|
|
37
|
+
Q[依赖分析]
|
|
38
|
+
R[资源打包]
|
|
39
|
+
O[输出文件]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
U --> E
|
|
43
|
+
T --> E
|
|
44
|
+
S --> D
|
|
45
|
+
S --> R
|
|
46
|
+
|
|
47
|
+
E --> B
|
|
48
|
+
E --> P
|
|
49
|
+
|
|
50
|
+
B --> A
|
|
51
|
+
D --> A
|
|
52
|
+
C --> A
|
|
53
|
+
|
|
54
|
+
Q --> P
|
|
55
|
+
P --> R
|
|
56
|
+
R --> O
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 安装
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
# 初始化项目(如果尚未初始化)
|
|
63
|
+
npm init -y
|
|
64
|
+
|
|
65
|
+
# 在 package.json 中添加 "type": "module"
|
|
66
|
+
npm pkg set type=module
|
|
67
|
+
|
|
68
|
+
# 本地安装(推荐)
|
|
69
|
+
npm i @flun/html-template # 简写
|
|
70
|
+
# 或
|
|
71
|
+
# 全局安装
|
|
72
|
+
npm i -g @flun/html-template # 简写
|
|
73
|
+
|
|
74
|
+
# flun其它npm家族安装包:
|
|
75
|
+
npm i @flun/env # .env 文件的环境变量调用
|
|
76
|
+
npm i @flun/mailer # 邮件发送
|
|
77
|
+
npm i @flun/windows # Window服务安装和管理
|
|
78
|
+
npm i @flun/webauthn-server # 身份验证服务后端处理
|
|
79
|
+
npm i @flun/webauthn-browser # 身份验证前端处理
|
|
80
|
+
# 所有家族包在支持 .d.ts 提示环境下,鼠标焦点包名都有丰富的导出和使用示例提示,再也不必到处翻找使用文档;建议在VScode环境下使用;
|
|
81
|
+
```
|
|
82
|
+
> **重要提示**:初次使用最好在空项目中执行安装,安装过程会自动复制 ESM 示例和必要文件到根目录
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 快速开始
|
|
87
|
+
|
|
88
|
+
### 方式一:通过npm脚本(推荐)
|
|
89
|
+
|
|
90
|
+
在您的 `package.json` 中添加以下脚本:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"scripts": {
|
|
95
|
+
"dev": "node dev.js",
|
|
96
|
+
"build": "node build.js",
|
|
97
|
+
"restoreDefaults": "node restoreDefaults.js"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**dev.js(ESM)**
|
|
103
|
+
```javascript
|
|
104
|
+
import { startDevServer } from '@flun/html-template';
|
|
105
|
+
startDevServer({ port: 7296, hotReload: true });
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**build.js(ESM)**
|
|
109
|
+
```javascript
|
|
110
|
+
import { compile } from '@flun/html-template';
|
|
111
|
+
compile({ outputDir: 'dist' });
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**restoreDefaults.js(ESM)**
|
|
115
|
+
```javascript
|
|
116
|
+
import { initProject } from '@flun/html-template';
|
|
117
|
+
initProject({ mode: 'overwrite', verbose: true });
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
然后使用:
|
|
121
|
+
```sh
|
|
122
|
+
# 启动开发服务器(实时预览和热重载,默认不启用登录)
|
|
123
|
+
npm run dev
|
|
124
|
+
|
|
125
|
+
# 启动开发服务器并启用登录系统
|
|
126
|
+
npm run dev -- --account
|
|
127
|
+
|
|
128
|
+
# 编译模板(生成最终HTML文件)
|
|
129
|
+
npm run build
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 方式二:直接运行文件
|
|
133
|
+
```sh
|
|
134
|
+
# 启动开发服务器
|
|
135
|
+
node dev.js
|
|
136
|
+
|
|
137
|
+
# 启动开发服务器并启用登录系统
|
|
138
|
+
node dev.js --account
|
|
139
|
+
|
|
140
|
+
# 编译模板
|
|
141
|
+
node build.js
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 配置选项
|
|
147
|
+
|
|
148
|
+
### 自定义端口
|
|
149
|
+
- **命令行参数**:`node dev.js --port 8080` 或 `node dev.js -p 8080`
|
|
150
|
+
- **环境变量**:`PORT=8080 node dev.js`
|
|
151
|
+
- **编程方式**:
|
|
152
|
+
```javascript
|
|
153
|
+
import { startDevServer } from '@flun/html-template';
|
|
154
|
+
startDevServer({ port: 8080 });
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### 热重载控制
|
|
158
|
+
- **启用**(默认):`node dev.js` 或 `node dev.js --hot-reload`
|
|
159
|
+
- **禁用**:`node dev.js --no-hot-reload`
|
|
160
|
+
- **编程方式**:
|
|
161
|
+
```javascript
|
|
162
|
+
import { startDevServer } from '@flun/html-template';
|
|
163
|
+
startDevServer({ port: 7296, hotReload: true }); // 启用热重载(默认)
|
|
164
|
+
```
|
|
165
|
+
### 登录系统控制
|
|
166
|
+
- **启用**:`node dev.js --account`
|
|
167
|
+
- **禁用**(默认):`node dev.js --no-account`
|
|
168
|
+
- **编程方式**:
|
|
169
|
+
```javascript
|
|
170
|
+
import { startDevServer } from '@flun/html-template';
|
|
171
|
+
startDevServer({ port: 7296, account: false }); // 禁用登录(默认)
|
|
172
|
+
```
|
|
173
|
+
### 自定义打包目录
|
|
174
|
+
- **编程方式**(默认输出到`dist`目录):
|
|
175
|
+
```javascript
|
|
176
|
+
import { compile } from '@flun/html-template';
|
|
177
|
+
compile({ outputDir: 'dist' }); // 默认参数:目录名 dist;
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 模板标签使用指南
|
|
181
|
+
|
|
182
|
+
### 基础概念
|
|
183
|
+
1. **模板继承**:子模板中必须使用 `[extends base.html]` 声明继承关系(可以指定任意父html)
|
|
184
|
+
2. **区块覆盖**:如果没有引入区块标签,会默认继承基模板内容
|
|
185
|
+
3. **清空内容**:如需将基础模板的标签内容赋值为空,直接在子模板中引入该空标签
|
|
186
|
+
|
|
187
|
+
### 标签快捷输入方式
|
|
188
|
+
**HBuilder用户**:
|
|
189
|
+
1. 输入 `b!` 后按 Enter
|
|
190
|
+
2. 输入标签名,自动创建开闭标签对
|
|
191
|
+
HBuilder自定义代码块配置(HTML和js):
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"custom-tag": {
|
|
195
|
+
"prefix": "b!",
|
|
196
|
+
"body": [
|
|
197
|
+
"[!${1}]",
|
|
198
|
+
"\t$TM_SELECTED_TEXT$2",
|
|
199
|
+
"[~${1}]"
|
|
200
|
+
],
|
|
201
|
+
"description": "自动生成闭标签"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
**VS Code用户**:
|
|
206
|
+
1. 安装 "html-custom-tags" 扩展
|
|
207
|
+
2. 输入 `[!标签名]` 后按空格,自动输出 `[~标签名]`
|
|
208
|
+
***并且其还支持大部分语言语法高亮,标签特殊高亮,标签统计,标签一键全复制等功能***
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
## 项目维护
|
|
212
|
+
|
|
213
|
+
### 更新版本
|
|
214
|
+
```sh
|
|
215
|
+
npm update @flun/html-template
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### 恢复初始示例文件
|
|
219
|
+
```sh
|
|
220
|
+
# 基本命令(跳过已存在目录)
|
|
221
|
+
node ./node_modules/@flun/html-template/copy-files.js
|
|
222
|
+
|
|
223
|
+
# 常用选项:
|
|
224
|
+
node ./node_modules/@flun/html-template/copy-files.js --skip-files --verbose
|
|
225
|
+
```
|
|
226
|
+
**主参数(三选一)**:
|
|
227
|
+
- `--overwrite` - 覆盖已存在的文件和目录
|
|
228
|
+
- `--skip-files` - 跳过所有存在的文件(包括目录中的文件)
|
|
229
|
+
- `--skip-dirs` - 跳过已存在的目录(默认)
|
|
230
|
+
> **可选参数(二选一)**:
|
|
231
|
+
> - `--account` 启用登录模式(会复制 templates/account 和 customize/account.js)
|
|
232
|
+
> - `--no-account` 禁用登录模式,跳过复制上述文件/目录(默认)
|
|
233
|
+
|
|
234
|
+
> **可选参数**:
|
|
235
|
+
> - `--verbose` 详细模式,显示更多信息
|
|
236
|
+
|
|
237
|
+
> **帮助**:
|
|
238
|
+
> - `--help ` - 显示帮助信息
|
|
239
|
+
|
|
240
|
+
#### 编程方式
|
|
241
|
+
```javascript
|
|
242
|
+
import { initProject } from '@flun/html-template';
|
|
243
|
+
|
|
244
|
+
// 恢复初始文件的多种方式
|
|
245
|
+
initProject(); // 使用默认设置(跳过已存在目录)
|
|
246
|
+
initProject({ mode: 'overwrite', verbose: true }); // 覆盖所有包文件并显示详细信息
|
|
247
|
+
initProject({ mode: 'overwrite', verbose: false }); // 覆盖所有包文件并静默输出
|
|
248
|
+
initProject({ mode: 'skip-files', verbose: true }); // 跳过已存在文件并显示详细信息
|
|
249
|
+
initProject({ mode: 'skip-files', verbose: true, account: false }); // 跳过已存在文件,显示详细信息,并跳过恢复登录相关文件
|
|
250
|
+
```
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 工作流程
|
|
254
|
+
|
|
255
|
+
1. **安装包**:自动复制模板文件到项目根目录
|
|
256
|
+
2. **自定义开发**:修改HTML模板文件满足需求
|
|
257
|
+
3. **添加功能**:将自定义逻辑写入 `customize` 目录
|
|
258
|
+
4. **开发调试**:使用 `node dev.js` 运行开发服务器
|
|
259
|
+
5. **编译部署**:使用 `node build.js` 编译模板
|
|
260
|
+
|
|
261
|
+
> **注意**:编译只会打包 `customize`、`static` 目录及文件,和编译模板生成的文件。根据是否有自定义路由,动态创建 `server.js` 入口文件。
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 核心功能
|
|
266
|
+
|
|
267
|
+
### 模板引擎特性
|
|
268
|
+
- **继承机制**:`[extends base.html]` 实现模板层级结构
|
|
269
|
+
- **区块系统**:`[!blockName]` 和 `[~blockName]` 定义可替换内容区块
|
|
270
|
+
- **变量系统**:`{{variable}}` 语法支持动态内容、条件判断和循环处理 (条件判断支持20层嵌套)
|
|
271
|
+
- **包含功能**:`[include header.html]` 实现文件复用
|
|
272
|
+
- **用户函数**:支持自定义函数的注册与调用
|
|
273
|
+
|
|
274
|
+
### 开发服务器功能
|
|
275
|
+
- 自动将URL路径映射到对应模板文件
|
|
276
|
+
- 通过 `/static` 路径提供静态文件服务
|
|
277
|
+
- 模板结构验证与错误提示
|
|
278
|
+
- 用户功能热加载和页面热重载功能
|
|
279
|
+
|
|
280
|
+
### 登录系统支持
|
|
281
|
+
- 登录系统支持密码,2FA,硬件等验证;支持用户名或邮箱登录;
|
|
282
|
+
- 包含文件去重处理
|
|
283
|
+
- 按需生成Express服务入口
|
|
284
|
+
- 智能编译顺序控制
|
|
285
|
+
|
|
286
|
+
### 编译系统优势
|
|
287
|
+
- 分析模板依赖关系
|
|
288
|
+
- 包含文件去重处理
|
|
289
|
+
- 按需生成Express服务入口
|
|
290
|
+
- 智能编译顺序控制
|
|
291
|
+
|
|
292
|
+
## 附加功能
|
|
293
|
+
|
|
294
|
+
### 页面样式在线修改(需启用登录系统)
|
|
295
|
+
- 支持长按元素选择设置其各种属性样式(比如:边距,颜色,字体等等);
|
|
296
|
+
- 支持跳转到编辑器修改整个页面样式文件:
|
|
297
|
+
> - 编辑器功能: 颜色选择 · 编辑 · 自动补全 · 代码折叠 · 预览 · 保存应用· 取消
|
|
298
|
+
|
|
299
|
+
### 自定义拖动元素(默认支持主题图标和返回顶部图标)
|
|
300
|
+
- 登录系统额外支持编辑器和预览容器拖动
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## 模板语法示例
|
|
305
|
+
|
|
306
|
+
### 条件判断
|
|
307
|
+
```html
|
|
308
|
+
{{if user.role === 'admin'}}
|
|
309
|
+
<div>管理员面板</div>
|
|
310
|
+
{{else if user.role === 'editor'}}
|
|
311
|
+
<div>编辑者面板</div>
|
|
312
|
+
{{else}}
|
|
313
|
+
<div>访客面板</div>
|
|
314
|
+
{{endif}}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 循环处理
|
|
318
|
+
```html
|
|
319
|
+
{{for product in products}}
|
|
320
|
+
<div class="product-item">
|
|
321
|
+
<h3>{{product.name}}</h3>
|
|
322
|
+
<p>价格: {{product.price}}</p>
|
|
323
|
+
<p>索引: {{product_index}}/是否是第一个: {{product_isFirst}}/是否是最后一个: {{product_isLast}}</p>
|
|
324
|
+
</div>
|
|
325
|
+
{{empty}}
|
|
326
|
+
<div class="empty-state">暂无产品信息</div>
|
|
327
|
+
{{endfor}}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### 循环控制
|
|
331
|
+
```html
|
|
332
|
+
<!-- for in -->
|
|
333
|
+
{{for item in list}}
|
|
334
|
+
{{if item.hidden}}{{continue}}{{endif}}
|
|
335
|
+
<div>{{item.name}}</div>
|
|
336
|
+
{{if item_index >= 5}}{{break}}{{endif}}
|
|
337
|
+
{{endfor}}
|
|
338
|
+
|
|
339
|
+
<!-- key value -->
|
|
340
|
+
{{for key, value in companyInfo}}
|
|
341
|
+
<p><strong>{{key}}:</strong> {{value}}</p>
|
|
342
|
+
{{endfor}}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### 表达式支持
|
|
346
|
+
- 数学运算:`{{a + b * c}}`
|
|
347
|
+
- 比较运算:`{{value > 10}}`
|
|
348
|
+
- 逻辑运算:`{{a && b || c}}`
|
|
349
|
+
- 三元运算符:`{{condition ? value1 : value2}}`
|
|
350
|
+
- 函数调用:`{{Math.max(a, b)}}`
|
|
351
|
+
- 属性访问:`{{user.profile.name}}`
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 扩展功能开发
|
|
356
|
+
|
|
357
|
+
### 自定义函数
|
|
358
|
+
```javascript
|
|
359
|
+
// 在 customize 目录中的文件 (ESM)
|
|
360
|
+
export default {
|
|
361
|
+
functions: {
|
|
362
|
+
formatCurrency: (amount, currency = '¥') => {
|
|
363
|
+
return `${currency}${amount.toFixed(2)}`;
|
|
364
|
+
},
|
|
365
|
+
getGreeting: (user) => {
|
|
366
|
+
const hour = new Date().getHours();
|
|
367
|
+
if (hour < 12) return `早上好, ${user.name}!`;
|
|
368
|
+
if (hour < 18) return `下午好, ${user.name}!`;
|
|
369
|
+
return `晚上好, ${user.name}!`;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
### 自定义路由
|
|
376
|
+
```javascript
|
|
377
|
+
export default {
|
|
378
|
+
setupRoutes: app => {
|
|
379
|
+
app.get('/api/products', (req, res) => {
|
|
380
|
+
const page = parseInt(req.query.page) || 1;
|
|
381
|
+
const limit = parseInt(req.query.limit) || 10;
|
|
382
|
+
res.json({ products: [], total: 0, page, limit });
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// 自定义中间件
|
|
386
|
+
app.use((req, res, next) => {
|
|
387
|
+
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
|
|
388
|
+
next();
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### 全局变量
|
|
395
|
+
```javascript
|
|
396
|
+
export default {
|
|
397
|
+
variables: {
|
|
398
|
+
siteName: "我的网站",
|
|
399
|
+
copyrightYear: new Date().getFullYear()
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
# 安全机制说明
|
|
405
|
+
|
|
406
|
+
## 我们为您构建了多层安全防护
|
|
407
|
+
|
|
408
|
+
### 🔒 核心安全特性
|
|
409
|
+
|
|
410
|
+
**路径安全**
|
|
411
|
+
- 所有文件访问都限制在项目目录内
|
|
412
|
+
- 防止目录遍历攻击和越权访问
|
|
413
|
+
|
|
414
|
+
**代码执行安全**
|
|
415
|
+
- 表达式在隔离的沙箱环境中运行
|
|
416
|
+
- 禁用危险函数(`require`、`process`、`eval`等)
|
|
417
|
+
- 执行超时保护(1.5秒自动终止)
|
|
418
|
+
|
|
419
|
+
**数据安全**
|
|
420
|
+
- 阻止原型污染攻击(防护`__proto__`、`constructor`等)
|
|
421
|
+
- 自动过滤不安全的关键字
|
|
422
|
+
- 防止无限循环(最多10次迭代)
|
|
423
|
+
|
|
424
|
+
### 🛡️ 自动防护机制
|
|
425
|
+
|
|
426
|
+
**模板处理时自动启用:**
|
|
427
|
+
- 变量访问安全检查
|
|
428
|
+
- 函数调用权限控制
|
|
429
|
+
- 资源使用限制
|
|
430
|
+
- 恶意代码拦截
|
|
431
|
+
|
|
432
|
+
**用户无需额外配置**,所有安全防护在后台自动运行。
|
|
433
|
+
|
|
434
|
+
### 💡 使用建议
|
|
435
|
+
|
|
436
|
+
**安全做法:**
|
|
437
|
+
```html
|
|
438
|
+
<!-- 使用内置安全函数 -->
|
|
439
|
+
<p>{{user.utils.safeFormat(data)}}</p>
|
|
440
|
+
|
|
441
|
+
<!-- 包含可信文件 -->
|
|
442
|
+
[include header.html]
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**避免做法:**
|
|
446
|
+
```html
|
|
447
|
+
<!-- 直接执行用户输入 -->
|
|
448
|
+
<p>{{userInput}}</p>
|
|
449
|
+
|
|
450
|
+
<!-- 动态包含未知文件 -->
|
|
451
|
+
[include {{dynamicPath}}]
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### ⚠️ 重要提醒
|
|
455
|
+
|
|
456
|
+
虽然我们提供了多重安全防护,但您仍需:
|
|
457
|
+
1. 谨慎处理用户输入数据
|
|
458
|
+
2. 验证自定义函数的参数安全性
|
|
459
|
+
3. 定期更新到最新版本
|
|
460
|
+
|
|
461
|
+
> **安全是共同责任** - 我们负责引擎安全,您负责业务逻辑安全。
|
|
462
|
+
|
|
463
|
+
这些防护措施确保您的模板渲染过程安全可靠,让您可以专注于业务开发。
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## 故障排除
|
|
468
|
+
|
|
469
|
+
### 常见问题
|
|
470
|
+
1. **模板不生效**:确保子模板开头有 `[extends base.html]`
|
|
471
|
+
2. **区块不显示**:检查开闭标签名称是否一致
|
|
472
|
+
3. **热重载失效**:确认修改的是模板或静态目录中的文件
|
|
473
|
+
4. **路由不工作**:检查是否正确定义了 `setupRoutes` 导出
|
|
474
|
+
5. **找不到函数**: 1. 检查函数名是否正确,2. 确认文件在 `customize` 目录内,3. 确认使用了 `export const functions = {...}` 语法
|
|
475
|
+
6. **ESM 相关错误**:检查 `package.json` 是否包含 `"type": "module"`,或启动文件是否具有 `.mjs` 扩展名。
|
|
476
|
+
|
|
477
|
+
### 获取帮助
|
|
478
|
+
如果遇到问题,可以:
|
|
479
|
+
1. 运行恢复初始文件脚本
|
|
480
|
+
2. 检查浏览器控制台错误信息
|
|
481
|
+
3. 确认文件路径和名称是否正确
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
此模板工具包提供了从开发到生产的完整解决方案,适合各种规模的Web项目开发。
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import {
|
|
2
|
+
path, fsPromises, CWD, templatesDir, templatesAbsDir, staticDir, customizeDir, accountDir, defaultPort,
|
|
3
|
+
writtenFilesToIgnore, getAvailableTemplates, findEntryFile, validateTemplateFile, renderTemplate, processIncludes,
|
|
4
|
+
setCompilationMode, getIncludedFiles, processVariables, loadUserFeatures, monitorFileWrites
|
|
5
|
+
} from './services/templateService.js';
|
|
6
|
+
import { compileAllTemplates } from './compile.js';
|
|
7
|
+
import { runCopyFiles } from './copy-files.js';
|
|
8
|
+
import { startServer } from './dev-server.js';
|
|
9
|
+
import { injectScript } from './customize/hotReloadInjector.js';
|
|
10
|
+
|
|
11
|
+
// =================================== services/templateService.js ===================================
|
|
12
|
+
/**
|
|
13
|
+
* ```js
|
|
14
|
+
* // 文件导出内容
|
|
15
|
+
*
|
|
16
|
+
* // 模块常量:
|
|
17
|
+
* path; // Node.js 路径处理模块
|
|
18
|
+
* const fsPromises; // Node.js 异步文件系统操作 (fs.promises)
|
|
19
|
+
* const CWD; // 当前工作目录绝对路径
|
|
20
|
+
* const templatesDir; // 模板目录名称 ("templates")
|
|
21
|
+
* const templatesAbsDir; // 模板目录绝对路径
|
|
22
|
+
* const staticDir; // 静态资源目录名称 ("static")
|
|
23
|
+
* const customizeDir; // 用户自定义功能目录名称 ("customize")
|
|
24
|
+
* const accountDir; // 账户目录名称 ("account")
|
|
25
|
+
* const defaultPort; // 默认服务端口 (7296)
|
|
26
|
+
* const writtenFilesToIgnore = []; // 热重载时需忽略的文件路径列表
|
|
27
|
+
*
|
|
28
|
+
* // 函数列表:
|
|
29
|
+
* getAvailableTemplates(); // 获取所有可用模板文件(排除 base.html)
|
|
30
|
+
* findEntryFile(); // 动态识别入口文件('@entry'标记 > 优先级列表 > 首字母排序)
|
|
31
|
+
* validateTemplateFile(); // 验证模板文件标签结构完整性
|
|
32
|
+
* renderTemplate(); // 核心模板渲染(处理 extends 继承与区块合并)
|
|
33
|
+
* processIncludes(); // 递归处理 [include] 包含指令
|
|
34
|
+
* setCompilationMode(); // 设置编译模式并清空依赖记录
|
|
35
|
+
* getIncludedFiles(); // 获取编译过程中记录的所有被包含文件
|
|
36
|
+
* processVariables(); // 模板变量替换、表达式求值与用户函数执行入口
|
|
37
|
+
* loadUserFeatures(); // 从 customize 目录加载用户路由、函数和变量
|
|
38
|
+
* monitorFileWrites(); // 启动文件写入监控(用于热重载排除)
|
|
39
|
+
* ```
|
|
40
|
+
* >查看定义:@see
|
|
41
|
+
* - 常量:{@link path}、{@link fsPromises}、{@link CWD}、{@link templatesDir}、{@link templatesAbsDir}、{@link staticDir}、
|
|
42
|
+
*{@link customizeDir}、{@link accountDir}、{@link defaultPort}、{@link writtenFilesToIgnore}
|
|
43
|
+
* - 函数:{@link getAvailableTemplates}、{@link findEntryFile}、{@link validateTemplateFile}、{@link renderTemplate}、
|
|
44
|
+
*{@link processIncludes}、{@link setCompilationMode}、{@link getIncludedFiles}、{@link processVariables}、
|
|
45
|
+
*{@link loadUserFeatures}、{@link monitorFileWrites}
|
|
46
|
+
*/
|
|
47
|
+
declare module './services/templateService.js' {
|
|
48
|
+
export * from './services/templateService.js';
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// =================================== compile.js ===================================
|
|
52
|
+
/**
|
|
53
|
+
* ```js
|
|
54
|
+
* // 文件导出内容
|
|
55
|
+
* compileAllTemplates(); // 全量模板编译与打包
|
|
56
|
+
* ```
|
|
57
|
+
* >查看定义:@see {@link compileAllTemplates}
|
|
58
|
+
*/
|
|
59
|
+
declare module './compile.js' {
|
|
60
|
+
export * from './compile.js';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// =================================== copy-files.js ===================================
|
|
64
|
+
/**
|
|
65
|
+
* ```js
|
|
66
|
+
* // 文件导出内容
|
|
67
|
+
* runCopyFiles(); // 运行文件复制
|
|
68
|
+
* ```
|
|
69
|
+
* >查看定义:@see {@link runCopyFiles}
|
|
70
|
+
*/
|
|
71
|
+
declare module './copy-files.js' {
|
|
72
|
+
export * from './copy-files.js';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// =================================== dev-server.js ===================================
|
|
76
|
+
/**
|
|
77
|
+
* ```js
|
|
78
|
+
* // 文件导出内容
|
|
79
|
+
* startServer(); // 启动开发服务器
|
|
80
|
+
* ```
|
|
81
|
+
* >查看定义:@see {@link startServer}
|
|
82
|
+
*/
|
|
83
|
+
declare module './dev-server.js' {
|
|
84
|
+
export * from './dev-server.js';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// =================================== customize/hotReloadInjector.js ===================================
|
|
88
|
+
/**
|
|
89
|
+
* ```js
|
|
90
|
+
* // 文件导出内容
|
|
91
|
+
* injectScript(); // 注入热重载脚本
|
|
92
|
+
* ```
|
|
93
|
+
* >查看定义:@see {@link injectScript}
|
|
94
|
+
*/
|
|
95
|
+
declare module './customize/hotReloadInjector.js' {
|
|
96
|
+
export * from './customize/hotReloadInjector.js';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// =================================== 模块导出入口 ===================================
|
|
100
|
+
/**
|
|
101
|
+
* HTML开发服务器模块 主要功能:
|
|
102
|
+
* ```js
|
|
103
|
+
* startDevServer(); // 启动开发服务器
|
|
104
|
+
* initProject(); // 初始化模板文件
|
|
105
|
+
* compile(); // 编译所有模板文件
|
|
106
|
+
* ```
|
|
107
|
+
* ---
|
|
108
|
+
* >查看定义:@see {@link startDevServer}、{@link initProject}、{@link compile}
|
|
109
|
+
* >
|
|
110
|
+
* @example
|
|
111
|
+
* // 启动服务器示例
|
|
112
|
+
* import { startDevServer } from '@flun/html-template';
|
|
113
|
+
* startDevServer({ port: 7296, hotReload: true, account: false }); // 默认参数:开发服务器端口7296,启用热更新,不启用登录系统;
|
|
114
|
+
*
|
|
115
|
+
* // -----------------------------------------------
|
|
116
|
+
* // 恢复包示例文件
|
|
117
|
+
* import { initProject } from '@flun/html-template';
|
|
118
|
+
* initProject({
|
|
119
|
+
* mode: 'skip-dirs', // 模式:跳过已存在的文件(默认)
|
|
120
|
+
* verbose: false, // 禁用控制台详细输出(静默模式)
|
|
121
|
+
* account: false // 禁用登录系统(登录验证系统文件)
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* // -----------------------------------------------
|
|
125
|
+
* // 编译模板示例
|
|
126
|
+
* import { compile } from '@flun/html-template';
|
|
127
|
+
* compile({outputDir: 'my-dist'}); // 可选参数:指定输出目录,默认为'dist'
|
|
128
|
+
*/
|
|
129
|
+
declare module './index.js' {
|
|
130
|
+
export { compileAllTemplates as compile } from './compile.js';
|
|
131
|
+
export { runCopyFiles as initProject } from './copy-files.js';
|
|
132
|
+
export { startServer as startDevServer } from './dev-server.js';
|
|
133
|
+
}
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flun/html-template",
|
|
3
|
+
"version": "4.0.10",
|
|
4
|
+
"description": "一个HTML模板工具包,提供开发服务器和模板编译功能,支持自定义标签和快捷输入,变量定义,包含文件引用,帮助开发者模块化处理HTML。",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "node dev-server.js",
|
|
9
|
+
"build": "node compile.js",
|
|
10
|
+
"postinstall": "node copy-files.js 2>&1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"html",
|
|
14
|
+
"template",
|
|
15
|
+
"server",
|
|
16
|
+
"flun"
|
|
17
|
+
],
|
|
18
|
+
"files": [
|
|
19
|
+
"templates",
|
|
20
|
+
"services",
|
|
21
|
+
"static",
|
|
22
|
+
"customize",
|
|
23
|
+
".env",
|
|
24
|
+
"dev-server.js",
|
|
25
|
+
"dev.js",
|
|
26
|
+
"compile.js",
|
|
27
|
+
"build.js",
|
|
28
|
+
"restoreDefaults.js",
|
|
29
|
+
"index.js",
|
|
30
|
+
"index.d.ts",
|
|
31
|
+
"copy-files.js",
|
|
32
|
+
"f-README.md",
|
|
33
|
+
"f-CHANGELOG.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"type": "module",
|
|
37
|
+
"exports": {
|
|
38
|
+
".": "./index.js"
|
|
39
|
+
},
|
|
40
|
+
"author": "flun <cn@flun.top>",
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/flunGit/html-template.git"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://www.npmjs.com/package/@flun/html-template#readme",
|
|
49
|
+
"bugs": {
|
|
50
|
+
"url": "https://github.com/flunGit/html-template/issues"
|
|
51
|
+
},
|
|
52
|
+
"license": "ISC",
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=22.12.0",
|
|
55
|
+
"npm": ">=10.0.0"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"bcrypt": "^6.0.0",
|
|
59
|
+
"chokidar": "^5.0.0",
|
|
60
|
+
"express": "^5.2.1",
|
|
61
|
+
"express-rate-limit": "^8.3.2",
|
|
62
|
+
"express-session": "^1.19.0",
|
|
63
|
+
"@flun/env": "^3.1.3",
|
|
64
|
+
"@flun/mailer": "^2.1.2",
|
|
65
|
+
"@flun/webauthn-server": "^2.0.5",
|
|
66
|
+
"mysql2": "^3.20.0",
|
|
67
|
+
"otplib": "^13.4.0",
|
|
68
|
+
"qrcode": "^1.5.4",
|
|
69
|
+
"socket.io": "^4.8.3"
|
|
70
|
+
},
|
|
71
|
+
"overrides": {
|
|
72
|
+
"fast-xml-parser": "^5.3.4"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"nodemon": "^3.1.11"
|
|
76
|
+
}
|
|
77
|
+
}
|