xiangjsoncraft 1.2.0 → 2.0.0
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/README.md +388 -238
- package/bin/create.js +376 -0
- package/dist/xiangjsoncraft.umd.js +1 -82
- package/package.json +49 -25
- package/rollup.config.js +21 -0
- package/src/renderJson.js +111 -0
- package/template/config.json +36 -0
- package/template/index.html +44 -0
- package/config.json +0 -113
- package/renderJson.js +0 -133
package/bin/create.js
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
import ora from 'ora';
|
|
10
|
+
import { execSync } from 'child_process';
|
|
11
|
+
|
|
12
|
+
// 解决ES模块__dirname问题
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = path.dirname(__filename);
|
|
15
|
+
|
|
16
|
+
// 框架版本
|
|
17
|
+
const FRAMEWORK_VERSION = '2.0.0';
|
|
18
|
+
// 模板目录(强制使用绝对路径,避免路径查找错误)
|
|
19
|
+
const TEMPLATE_DIR = path.resolve(__dirname, '../template');
|
|
20
|
+
|
|
21
|
+
// 美化控制台输出
|
|
22
|
+
const log = {
|
|
23
|
+
success: (msg) => console.log(chalk.green(`✅ ${msg}`)),
|
|
24
|
+
info: (msg) => console.log(chalk.blue(`ℹ️ ${msg}`)),
|
|
25
|
+
warn: (msg) => console.log(chalk.yellow(`⚠️ ${msg}`)),
|
|
26
|
+
error: (msg) => console.log(chalk.red(`❌ ${msg}`)),
|
|
27
|
+
title: (msg) => console.log(chalk.bgCyan.black(` ${msg} `))
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// 初始化命令行程序
|
|
31
|
+
program
|
|
32
|
+
.name('create-xiangjsoncraft')
|
|
33
|
+
.description(`XiangJsonCraft ${FRAMEWORK_VERSION} - 纯JSON驱动的前端框架,一键创建零代码项目`)
|
|
34
|
+
.version(FRAMEWORK_VERSION, '-v, --version', '查看框架版本')
|
|
35
|
+
.argument('[project-name]', '项目名称', 'xiangjsoncraft-app')
|
|
36
|
+
.action(async (projectName) => {
|
|
37
|
+
console.log(chalk.cyan(`
|
|
38
|
+
┌─────────────────────────────────┐
|
|
39
|
+
│ XiangJsonCraft ${FRAMEWORK_VERSION} │
|
|
40
|
+
│ Write JSON, Get a Website │
|
|
41
|
+
└─────────────────────────────────┘
|
|
42
|
+
`));
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
// 1. 用户确认创建项目
|
|
46
|
+
const { confirm } = await inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'confirm',
|
|
49
|
+
name: 'confirm',
|
|
50
|
+
message: `是否要创建项目「${chalk.cyan(projectName)}」?`,
|
|
51
|
+
default: true
|
|
52
|
+
}
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
if (!confirm) {
|
|
56
|
+
log.info('项目创建已取消');
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2. 选择项目模板
|
|
61
|
+
const { templateType } = await inquirer.prompt([
|
|
62
|
+
{
|
|
63
|
+
type: 'list',
|
|
64
|
+
name: 'templateType',
|
|
65
|
+
message: '请选择项目模板:',
|
|
66
|
+
choices: [
|
|
67
|
+
{ name: '基础模板(快速上手)', value: 'basic' },
|
|
68
|
+
{ name: '完整模板(响应式+交互)', value: 'complete' },
|
|
69
|
+
{ name: '空模板(仅核心骨架)', value: 'empty' }
|
|
70
|
+
],
|
|
71
|
+
default: 'basic'
|
|
72
|
+
}
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
// 3. 检查目录是否存在
|
|
76
|
+
const projectPath = path.resolve(process.cwd(), projectName);
|
|
77
|
+
if (fs.existsSync(projectPath)) {
|
|
78
|
+
log.error(`目录「${projectName}」已存在,请更换名称或删除后重试`);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 4. 创建项目核心逻辑
|
|
83
|
+
const spinner = ora(chalk.blue('正在创建项目...')).start();
|
|
84
|
+
|
|
85
|
+
// 4.1 强制创建项目目录(确保目录存在)
|
|
86
|
+
fs.ensureDirSync(projectPath);
|
|
87
|
+
|
|
88
|
+
// 4.2 复制模板文件(处理不同模板的config.json)
|
|
89
|
+
if (fs.existsSync(TEMPLATE_DIR)) {
|
|
90
|
+
const templateFiles = fs.readdirSync(TEMPLATE_DIR);
|
|
91
|
+
templateFiles.forEach(file => {
|
|
92
|
+
const srcPath = path.resolve(TEMPLATE_DIR, file);
|
|
93
|
+
const destPath = path.resolve(projectPath, file);
|
|
94
|
+
|
|
95
|
+
// 根据模板类型生成对应的config.json
|
|
96
|
+
if (file === 'config.json') {
|
|
97
|
+
let configContent = {};
|
|
98
|
+
|
|
99
|
+
// 基础模板配置
|
|
100
|
+
if (templateType === 'basic') {
|
|
101
|
+
configContent = {
|
|
102
|
+
"framework": "XiangJsonCraft 2.0",
|
|
103
|
+
"styles": {
|
|
104
|
+
"*": {
|
|
105
|
+
"margin": 0,
|
|
106
|
+
"padding": 0,
|
|
107
|
+
"boxSizing": "border-box",
|
|
108
|
+
"fontFamily": "Segoe UI, Roboto, 微软雅黑, sans-serif"
|
|
109
|
+
},
|
|
110
|
+
"body": {
|
|
111
|
+
"backgroundColor": "#f0f4f8",
|
|
112
|
+
"color": "#334e68",
|
|
113
|
+
"lineHeight": "1.6",
|
|
114
|
+
"minHeight": "100vh",
|
|
115
|
+
"padding": "2rem 1rem"
|
|
116
|
+
},
|
|
117
|
+
".app-container": {
|
|
118
|
+
"maxWidth": "800px",
|
|
119
|
+
"margin": "0 auto",
|
|
120
|
+
"backgroundColor": "#ffffff",
|
|
121
|
+
"padding": "2rem",
|
|
122
|
+
"borderRadius": "12px",
|
|
123
|
+
"boxShadow": "0 4px 20px rgba(0,0,0,0.05)"
|
|
124
|
+
},
|
|
125
|
+
".app-title": {
|
|
126
|
+
"fontSize": "2rem",
|
|
127
|
+
"color": "#2d3748",
|
|
128
|
+
"textAlign": "center",
|
|
129
|
+
"marginBottom": "1.5rem"
|
|
130
|
+
},
|
|
131
|
+
".app-desc": {
|
|
132
|
+
"fontSize": "1.1rem",
|
|
133
|
+
"marginBottom": "2rem",
|
|
134
|
+
"textAlign": "center"
|
|
135
|
+
},
|
|
136
|
+
".app-btn": {
|
|
137
|
+
"display": "block",
|
|
138
|
+
"width": "200px",
|
|
139
|
+
"height": "48px",
|
|
140
|
+
"lineHeight": "48px",
|
|
141
|
+
"textAlign": "center",
|
|
142
|
+
"backgroundColor": "#4299e1",
|
|
143
|
+
"color": "#ffffff",
|
|
144
|
+
"borderRadius": "8px",
|
|
145
|
+
"margin": "0 auto",
|
|
146
|
+
"textDecoration": "none",
|
|
147
|
+
"cursor": "pointer"
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
"content": {
|
|
151
|
+
".app-title": {
|
|
152
|
+
"value": "XiangJsonCraft 2.0 基础模板",
|
|
153
|
+
"isHtml": false
|
|
154
|
+
},
|
|
155
|
+
".app-desc": {
|
|
156
|
+
"value": "修改 config.json 即可自定义所有样式和内容,无需写任何CSS/JS!",
|
|
157
|
+
"isHtml": false
|
|
158
|
+
},
|
|
159
|
+
".app-btn": {
|
|
160
|
+
"value": "开始使用",
|
|
161
|
+
"isHtml": false
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// 完整模板配置
|
|
167
|
+
else if (templateType === 'complete') {
|
|
168
|
+
configContent = {
|
|
169
|
+
"framework": "XiangJsonCraft 2.0",
|
|
170
|
+
"styles": {
|
|
171
|
+
"*": {
|
|
172
|
+
"margin": 0,
|
|
173
|
+
"padding": 0,
|
|
174
|
+
"boxSizing": "border-box",
|
|
175
|
+
"fontFamily": "Segoe UI, Roboto, 微软雅黑, sans-serif"
|
|
176
|
+
},
|
|
177
|
+
"body": {
|
|
178
|
+
"backgroundColor": "#f0f4f8",
|
|
179
|
+
"color": "#334e68",
|
|
180
|
+
"lineHeight": "1.6",
|
|
181
|
+
"minHeight": "100vh",
|
|
182
|
+
"padding": "2rem 1rem"
|
|
183
|
+
},
|
|
184
|
+
".app-container": {
|
|
185
|
+
"maxWidth": "1200px",
|
|
186
|
+
"margin": "0 auto",
|
|
187
|
+
"backgroundColor": "#ffffff",
|
|
188
|
+
"padding": "2rem",
|
|
189
|
+
"borderRadius": "12px",
|
|
190
|
+
"boxShadow": "0 4px 20px rgba(0,0,0,0.05)",
|
|
191
|
+
"transition": "all 0.3s ease"
|
|
192
|
+
},
|
|
193
|
+
".app-container:hover": {
|
|
194
|
+
"boxShadow": "0 8px 30px rgba(0,0,0,0.1)"
|
|
195
|
+
},
|
|
196
|
+
".app-title": {
|
|
197
|
+
"fontSize": "2.2rem",
|
|
198
|
+
"color": "#2d3748",
|
|
199
|
+
"textAlign": "center",
|
|
200
|
+
"marginBottom": "1.5rem",
|
|
201
|
+
"transition": "color 0.3s ease"
|
|
202
|
+
},
|
|
203
|
+
".app-title:hover": {
|
|
204
|
+
"color": "#4299e1"
|
|
205
|
+
},
|
|
206
|
+
".app-desc": {
|
|
207
|
+
"fontSize": "1.1rem",
|
|
208
|
+
"marginBottom": "2rem",
|
|
209
|
+
"textAlign": "center",
|
|
210
|
+
"maxWidth": "600px",
|
|
211
|
+
"marginLeft": "auto",
|
|
212
|
+
"marginRight": "auto"
|
|
213
|
+
},
|
|
214
|
+
".app-btn-group": {
|
|
215
|
+
"display": "flex",
|
|
216
|
+
"justifyContent": "center",
|
|
217
|
+
"gap": "1rem",
|
|
218
|
+
"flexWrap": "wrap"
|
|
219
|
+
},
|
|
220
|
+
".app-btn": {
|
|
221
|
+
"display": "inline-block",
|
|
222
|
+
"padding": "12px 24px",
|
|
223
|
+
"backgroundColor": "#4299e1",
|
|
224
|
+
"color": "#ffffff",
|
|
225
|
+
"borderRadius": "8px",
|
|
226
|
+
"textDecoration": "none",
|
|
227
|
+
"cursor": "pointer",
|
|
228
|
+
"transition": "all 0.3s ease",
|
|
229
|
+
"border": "none"
|
|
230
|
+
},
|
|
231
|
+
".app-btn:hover": {
|
|
232
|
+
"backgroundColor": "#3182ce",
|
|
233
|
+
"transform": "translateY(-2px)"
|
|
234
|
+
},
|
|
235
|
+
".app-btn:active": {
|
|
236
|
+
"transform": "translateY(0)"
|
|
237
|
+
},
|
|
238
|
+
".app-btn-secondary": {
|
|
239
|
+
"backgroundColor": "#718096",
|
|
240
|
+
"color": "#ffffff"
|
|
241
|
+
},
|
|
242
|
+
".app-btn-secondary:hover": {
|
|
243
|
+
"backgroundColor": "#4a5568"
|
|
244
|
+
},
|
|
245
|
+
// 响应式配置
|
|
246
|
+
"@media (max-width: 768px)": {
|
|
247
|
+
".app-container": {
|
|
248
|
+
"padding": "1rem",
|
|
249
|
+
"margin": "0 0.5rem"
|
|
250
|
+
},
|
|
251
|
+
".app-title": {
|
|
252
|
+
"fontSize": "1.8rem"
|
|
253
|
+
},
|
|
254
|
+
".app-btn-group": {
|
|
255
|
+
"flexDirection": "column",
|
|
256
|
+
"alignItems": "center"
|
|
257
|
+
},
|
|
258
|
+
".app-btn": {
|
|
259
|
+
"width": "100%",
|
|
260
|
+
"maxWidth": "200px"
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
"content": {
|
|
265
|
+
".app-title": {
|
|
266
|
+
"value": "XiangJsonCraft 2.0 完整模板",
|
|
267
|
+
"isHtml": false
|
|
268
|
+
},
|
|
269
|
+
".app-desc": {
|
|
270
|
+
"value": "纯JSON驱动的前端框架,支持响应式布局、交互效果、动态内容,无需写任何CSS/JS代码!",
|
|
271
|
+
"isHtml": false
|
|
272
|
+
},
|
|
273
|
+
".app-btn-primary": {
|
|
274
|
+
"value": "<span onclick=\"alert('你点击了主按钮!')\">主按钮</span>",
|
|
275
|
+
"isHtml": true
|
|
276
|
+
},
|
|
277
|
+
".app-btn-secondary": {
|
|
278
|
+
"value": "<span onclick=\"alert('你点击了次按钮!')\">次按钮</span>",
|
|
279
|
+
"isHtml": true
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
// 空模板配置
|
|
285
|
+
else {
|
|
286
|
+
configContent = {
|
|
287
|
+
"framework": "XiangJsonCraft 2.0",
|
|
288
|
+
"styles": {},
|
|
289
|
+
"content": {}
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// 强制写入config.json(格式化输出)
|
|
294
|
+
fs.writeJsonSync(destPath, configContent, { spaces: 2, flag: 'w' });
|
|
295
|
+
}
|
|
296
|
+
// 其他模板文件直接复制
|
|
297
|
+
else {
|
|
298
|
+
fs.copySync(srcPath, destPath, { overwrite: true });
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
} else {
|
|
302
|
+
throw new Error(`模板目录不存在:${TEMPLATE_DIR}`);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// 5. 强制生成package.json(核心修复:不再判断文件是否存在,直接生成)
|
|
306
|
+
const pkgPath = path.resolve(projectPath, 'package.json');
|
|
307
|
+
const pkgJson = {
|
|
308
|
+
"name": projectName,
|
|
309
|
+
"version": "1.0.0",
|
|
310
|
+
"description": "XiangJsonCraft 2.0 Project - Write JSON, Get a Website",
|
|
311
|
+
"scripts": {
|
|
312
|
+
"start": "npx serve .",
|
|
313
|
+
"dev": "npx serve .",
|
|
314
|
+
"build": "echo 'XiangJsonCraft 无需打包,直接部署即可!'"
|
|
315
|
+
},
|
|
316
|
+
"dependencies": {
|
|
317
|
+
"xiangjsoncraft": "^2.0.0"
|
|
318
|
+
},
|
|
319
|
+
"keywords": ["xiangjsoncraft", "json", "framework", "no-code"],
|
|
320
|
+
"license": "MIT"
|
|
321
|
+
};
|
|
322
|
+
// 强制写入,覆盖任何已存在的文件(确保scripts字段必存在)
|
|
323
|
+
fs.writeJsonSync(pkgPath, pkgJson, { spaces: 2, flag: 'w' });
|
|
324
|
+
|
|
325
|
+
spinner.succeed();
|
|
326
|
+
log.success(`项目「${projectName}」创建成功!`);
|
|
327
|
+
|
|
328
|
+
// 6. 安装项目依赖
|
|
329
|
+
const { installDeps } = await inquirer.prompt([
|
|
330
|
+
{
|
|
331
|
+
type: 'confirm',
|
|
332
|
+
name: 'installDeps',
|
|
333
|
+
message: '是否立即安装项目依赖?',
|
|
334
|
+
default: true
|
|
335
|
+
}
|
|
336
|
+
]);
|
|
337
|
+
|
|
338
|
+
if (installDeps) {
|
|
339
|
+
const installSpinner = ora(chalk.blue('正在安装依赖...')).start();
|
|
340
|
+
try {
|
|
341
|
+
// 兼容Windows系统,添加shell: true
|
|
342
|
+
execSync('npm install', {
|
|
343
|
+
cwd: projectPath,
|
|
344
|
+
stdio: 'ignore',
|
|
345
|
+
shell: true
|
|
346
|
+
});
|
|
347
|
+
installSpinner.succeed();
|
|
348
|
+
log.success('依赖安装完成!');
|
|
349
|
+
} catch (err) {
|
|
350
|
+
installSpinner.fail();
|
|
351
|
+
log.warn('依赖安装失败,请手动进入项目目录执行 npm install --legacy-peer-deps');
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// 7. 显示使用指南
|
|
356
|
+
log.title('使用指南');
|
|
357
|
+
console.log(chalk.cyan('1. 进入项目目录:'));
|
|
358
|
+
console.log(` cd ${chalk.green(projectName)}`);
|
|
359
|
+
console.log(chalk.cyan('2. 启动开发服务器:'));
|
|
360
|
+
console.log(` ${chalk.green('npm run start')}`);
|
|
361
|
+
console.log(chalk.cyan('3. 自定义项目:'));
|
|
362
|
+
console.log(` 修改 ${chalk.green('config.json')} 文件(所有样式/内容/交互都在这里配置)`);
|
|
363
|
+
console.log(chalk.cyan('4. 部署上线:'));
|
|
364
|
+
console.log(` 直接将项目文件上传到服务器即可,无需打包`);
|
|
365
|
+
|
|
366
|
+
console.log('\n' + chalk.gray(`📚 官方文档:https://github.com/dxiangwiki/xiangjsoncraft`));
|
|
367
|
+
console.log(chalk.gray(`💡 提示:必须使用本地服务器运行,不能直接打开HTML文件!`));
|
|
368
|
+
|
|
369
|
+
} catch (error) {
|
|
370
|
+
log.error(`项目创建失败:${error.message}`);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// 解析命令行参数(兼容Windows系统)
|
|
376
|
+
program.parse(process.argv);
|
|
@@ -1,82 +1 @@
|
|
|
1
|
-
|
|
2
|
-
function renderJsonStyles() {
|
|
3
|
-
// 核心原则:本地config.json永远最高优先级,加载失败再用CDN官方配置
|
|
4
|
-
const localConfigUrl = './config.json'; // 本地用户自定义配置
|
|
5
|
-
const cdnConfigUrl = 'https://cdn.jsdelivr.net/npm/xiangjsoncraft@1.1.1/config.json'; // CDN兜底配置
|
|
6
|
-
|
|
7
|
-
// 先尝试加载本地config.json
|
|
8
|
-
fetch(localConfigUrl)
|
|
9
|
-
.then(response => {
|
|
10
|
-
// 本地配置存在(状态码200),则使用本地配置
|
|
11
|
-
if (response.ok) {
|
|
12
|
-
console.log('🔧 检测到本地config.json,优先加载用户自定义配置');
|
|
13
|
-
return response.json();
|
|
14
|
-
}
|
|
15
|
-
// 本地配置不存在/加载失败,切换到CDN兜底配置
|
|
16
|
-
console.log('ℹ️ 本地未检测到config.json,加载CDN官方示例配置');
|
|
17
|
-
return fetch(cdnConfigUrl).then(res => {
|
|
18
|
-
if (!res.ok) throw new Error('CDN官方配置加载失败');
|
|
19
|
-
return res.json();
|
|
20
|
-
});
|
|
21
|
-
})
|
|
22
|
-
.then(config => {
|
|
23
|
-
// 获取或创建样式块,避免重复创建
|
|
24
|
-
const styleBlock = document.getElementById('dynamic-styles') || createStyleBlock();
|
|
25
|
-
if (!styleBlock) return console.error('❌ 样式块创建失败,无法渲染样式');
|
|
26
|
-
|
|
27
|
-
// 生成CSS规则
|
|
28
|
-
let cssRules = '';
|
|
29
|
-
|
|
30
|
-
// 处理所有选择器样式(支持任意CSS选择器、媒体查询)
|
|
31
|
-
if (config.styles && typeof config.styles === 'object' && Object.keys(config.styles).length > 0) {
|
|
32
|
-
// 遍历所有选择器(类、ID、伪类、媒体查询等)
|
|
33
|
-
Object.entries(config.styles).forEach(([selector, styles]) => {
|
|
34
|
-
// 过滤空样式,避免无效CSS
|
|
35
|
-
if (!styles || typeof styles !== 'object') return;
|
|
36
|
-
// 生成该选择器的所有样式属性
|
|
37
|
-
const styleProperties = Object.entries(styles)
|
|
38
|
-
.map(([prop, value]) => {
|
|
39
|
-
// 过滤空属性,驼峰式属性名转换为CSS标准格式
|
|
40
|
-
if (!prop || value === undefined || value === null) return '';
|
|
41
|
-
const cssProp = prop.replaceCamelCase();
|
|
42
|
-
return `${cssProp}: ${value};`;
|
|
43
|
-
})
|
|
44
|
-
.filter(Boolean) // 移除空属性
|
|
45
|
-
.join('\n ');
|
|
46
|
-
|
|
47
|
-
// 仅当有样式属性时,添加到CSS规则
|
|
48
|
-
if (styleProperties) {
|
|
49
|
-
cssRules += `${selector} {\n ${styleProperties}\n}\n\n`;
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// 应用生成的CSS规则到样式块
|
|
55
|
-
if (cssRules) {
|
|
56
|
-
styleBlock.innerHTML = cssRules;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// 处理内容配置(支持纯文本/HTML内容,通过isHtml标识)
|
|
60
|
-
if (config.content && typeof config.content === 'object' && Object.keys(config.content).length > 0) {
|
|
61
|
-
Object.entries(config.content).forEach(([selector, content]) => {
|
|
62
|
-
// 过滤无效选择器和内容
|
|
63
|
-
if (!selector || !content || !content.hasOwnProperty('value')) return;
|
|
64
|
-
const elements = document.querySelectorAll(selector);
|
|
65
|
-
elements.forEach(el => {
|
|
66
|
-
if (!el) return;
|
|
67
|
-
// 支持HTML内容或纯文本,默认纯文本
|
|
68
|
-
if (content.isHtml) {
|
|
69
|
-
el.innerHTML = content.value;
|
|
70
|
-
} else {
|
|
71
|
-
el.textContent = content.value;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
console.log('✅ XiangJsonCraft v1.1.1 渲染成功!');
|
|
78
|
-
})
|
|
79
|
-
.catch(error => {
|
|
80
|
-
console.error('❌ XiangJsonCraft 处理配置时出错:', error.message);
|
|
81
|
-
});
|
|
82
|
-
}exports.renderJsonStyles=renderJsonStyles;}));
|
|
1
|
+
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).XiangJsonCraft={})}(this,function(n){"use strict";function e(){const n=n=>{console.error(chalk?.red(`❌ XiangJsonCraft 2.0 错误: ${n}`)||`❌ XiangJsonCraft 2.0 错误: ${n}`)};fetch("./config.json").then(async n=>{if(!n.ok)throw new Error("配置文件加载失败,请检查config.json是否存在");return n.json()}).then(e=>{if("object"!=typeof e||null===e||Array.isArray(e))return n("config.json 格式错误,必须是标准JSON对象");const t=document.getElementById("xiangjsoncraft-styles")||function(){const n=document.createElement("style");return n.id="xiangjsoncraft-styles",document.head.insertBefore(n,document.head.firstChild),n}(),{styles:r={}}=e;let o="";Object.entries(r).forEach(([n,e])=>{const t=String(n).trim();if(!t||"object"!=typeof e||null===e||Array.isArray(e))return;const r=Object.entries(e).map(([n,e])=>{const t=String(n).trim();if(!t||null==e||""===String(e).trim())return"";return`${t.replaceCamelCase()}: ${String(e).trim()};`}).filter(Boolean).join("\n ");r&&(o+=`${t} {\n ${r}\n}\n\n`)}),o&&(t.innerHTML=o);const{content:i={}}=e;Object.entries(i).forEach(([n,e])=>{const t=String(n).trim();if(!t||"object"!=typeof e||null===e||Array.isArray(e))return;if(!e.hasOwnProperty("value"))return;const r=document.querySelectorAll(t);if(0===r.length)return;const{value:o,isHtml:i=!1}=e,s=String(o).trim();r.forEach(n=>{i?n.innerHTML=s:n.textContent=s})}),console.log(chalk?.green("✅ XiangJsonCraft 2.0 渲染成功!")||"✅ XiangJsonCraft 2.0 渲染成功!"),console.log(chalk?.blue("ℹ️ 修改config.json后刷新页面即可生效")||"ℹ️ 修改config.json后刷新页面即可生效")}).catch(e=>{n(e.message)})}String.prototype.replaceCamelCase=function(n="-"){return this.replace(/[A-Z]/g,e=>`${n}${e.toLowerCase()}`)},"undefined"!=typeof window&&(window.XiangJsonCraft={renderJsonStyles:e,version:"2.0.0"}),n.renderJsonStyles=e});
|
package/package.json
CHANGED
|
@@ -1,33 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xiangjsoncraft",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "零CSS零JS、纯JSON驱动的轻量前端框架 | Write JSON, Get a Website",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-xiangjsoncraft": "./bin/create.js",
|
|
8
|
+
"xiangjsoncraft": "./bin/create.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/xiangjsoncraft.umd.js",
|
|
11
|
+
"module": "./src/renderJson.js",
|
|
8
12
|
"files": [
|
|
13
|
+
"bin",
|
|
9
14
|
"dist",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
15
|
+
"src",
|
|
16
|
+
"template",
|
|
17
|
+
"rollup.config.js",
|
|
18
|
+
"README.md"
|
|
14
19
|
],
|
|
15
|
-
"scripts": {
|
|
16
|
-
"build": "rollup -c",
|
|
17
|
-
"dev": "npx serve ."
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"rollup": "^4.12.0"
|
|
21
|
-
},
|
|
22
20
|
"keywords": [
|
|
23
|
-
"json
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
21
|
+
"json",
|
|
22
|
+
"framework",
|
|
23
|
+
"no-css",
|
|
24
|
+
"no-js",
|
|
25
|
+
"low-code",
|
|
26
|
+
"轻量框架",
|
|
27
|
+
"json驱动",
|
|
28
|
+
"可视化配置",
|
|
29
|
+
"前端零代码"
|
|
29
30
|
],
|
|
30
|
-
"author": "
|
|
31
|
+
"author": "",
|
|
31
32
|
"license": "MIT",
|
|
32
|
-
"
|
|
33
|
-
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"chalk": "^5.3.0",
|
|
35
|
+
"commander": "^12.0.0",
|
|
36
|
+
"fs-extra": "^11.2.0",
|
|
37
|
+
"inquirer": "^9.2.16",
|
|
38
|
+
"ora": "^8.0.1"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@rollup/plugin-terser": "^0.4.4",
|
|
42
|
+
"rollup": "^4.9.6",
|
|
43
|
+
"undefined": "^undefined"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "npx rollup -c rollup.config.js",
|
|
47
|
+
"prepublishOnly": "npm run build"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/dxiangwiki/xiangjsoncraft.git"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/dxiangwiki/xiangjsoncraft",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/dxiangwiki/xiangjsoncraft/issues"
|
|
56
|
+
}
|
|
57
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import terser from '@rollup/plugin-terser'; // 替换原来的 rollup-plugin-terser
|
|
2
|
+
export default {
|
|
3
|
+
input: 'src/renderJson.js',
|
|
4
|
+
output: {
|
|
5
|
+
file: 'dist/xiangjsoncraft.umd.js',
|
|
6
|
+
format: 'umd',
|
|
7
|
+
name: 'XiangJsonCraft',
|
|
8
|
+
compact: true
|
|
9
|
+
},
|
|
10
|
+
plugins: [
|
|
11
|
+
terser({
|
|
12
|
+
compress: {
|
|
13
|
+
drop_console: false,
|
|
14
|
+
pure_funcs: []
|
|
15
|
+
},
|
|
16
|
+
format: {
|
|
17
|
+
comments: false
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
]
|
|
21
|
+
};
|