xiangjsoncraft 2.0.0 → 2.0.1
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/bin/create.js +204 -358
- package/package.json +4 -5
- package/template/config.json +218 -20
- package/template/index.html +37 -28
package/bin/create.js
CHANGED
|
@@ -1,376 +1,222 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { program } from 'commander';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
2
|
import fs from 'fs-extra';
|
|
6
3
|
import path from 'path';
|
|
7
4
|
import { fileURLToPath } from 'url';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
8
6
|
import chalk from 'chalk';
|
|
9
7
|
import ora from 'ora';
|
|
10
|
-
import { execSync } from 'child_process';
|
|
11
8
|
|
|
12
|
-
// 解决
|
|
9
|
+
// 解决 ESModule __dirname 问题
|
|
13
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
11
|
const __dirname = path.dirname(__filename);
|
|
15
12
|
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
//
|
|
19
|
-
const
|
|
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
|
-
};
|
|
13
|
+
// 框架根目录
|
|
14
|
+
const frameworkRoot = path.resolve(__dirname, '..');
|
|
15
|
+
// 模板目录
|
|
16
|
+
const templateDir = path.join(frameworkRoot, 'template');
|
|
29
17
|
|
|
30
|
-
//
|
|
31
|
-
|
|
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(`
|
|
18
|
+
// 欢迎信息
|
|
19
|
+
console.log(chalk.blue(`
|
|
38
20
|
┌─────────────────────────────────┐
|
|
39
|
-
│ XiangJsonCraft
|
|
21
|
+
│ XiangJsonCraft 2.0.1 │
|
|
40
22
|
│ Write JSON, Get a Website │
|
|
41
23
|
└─────────────────────────────────┘
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
24
|
+
`));
|
|
25
|
+
|
|
26
|
+
// 第一步:获取项目名称(从命令行参数)
|
|
27
|
+
const args = process.argv.slice(2);
|
|
28
|
+
let projectName = args[0] || 'xiangjsoncraft-app';
|
|
29
|
+
|
|
30
|
+
// 第二步:确认创建项目
|
|
31
|
+
const confirmAnswers = await inquirer.prompt([
|
|
32
|
+
{
|
|
33
|
+
type: 'confirm',
|
|
34
|
+
name: 'confirmCreate',
|
|
35
|
+
message: `是否要创建项目「${projectName}」?`,
|
|
36
|
+
default: true
|
|
37
|
+
}
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
if (!confirmAnswers.confirmCreate) {
|
|
41
|
+
console.log(chalk.yellow('✅ 项目创建已取消'));
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 第三步:选择模板(仅保留基础模板,确保核心功能)
|
|
46
|
+
const templateAnswers = await inquirer.prompt([
|
|
47
|
+
{
|
|
48
|
+
type: 'list',
|
|
49
|
+
name: 'template',
|
|
50
|
+
message: '请选择项目模板:',
|
|
51
|
+
choices: [
|
|
52
|
+
{ name: '基础模板(快速上手)', value: 'basic' }
|
|
53
|
+
],
|
|
54
|
+
default: 'basic'
|
|
55
|
+
}
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
// 第四步:创建项目
|
|
59
|
+
const spinner = ora('正在创建项目...').start();
|
|
60
|
+
try {
|
|
61
|
+
// 项目目标目录
|
|
62
|
+
const projectDir = path.resolve(process.cwd(), projectName);
|
|
63
|
+
|
|
64
|
+
// 检查目录是否已存在
|
|
65
|
+
if (fs.existsSync(projectDir)) {
|
|
66
|
+
spinner.fail(chalk.red('❌ 项目目录已存在,请删除后重试'));
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 1. 创建项目目录
|
|
71
|
+
fs.ensureDirSync(projectDir);
|
|
72
|
+
|
|
73
|
+
// 2. 生成 package.json(修复本地路径依赖问题)
|
|
74
|
+
const packageJson = {
|
|
75
|
+
"name": projectName,
|
|
76
|
+
"version": "1.0.0",
|
|
77
|
+
"description": "XiangJsonCraft 项目",
|
|
78
|
+
"type": "module",
|
|
79
|
+
"scripts": {
|
|
80
|
+
"start": "npx serve .",
|
|
81
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
82
|
+
},
|
|
83
|
+
"dependencies": {
|
|
84
|
+
// 指向 npm 仓库版本,而非本地路径
|
|
85
|
+
"xiangjsoncraft": "^2.0.1"
|
|
86
|
+
},
|
|
87
|
+
"license": "MIT"
|
|
88
|
+
};
|
|
89
|
+
fs.writeJsonSync(path.join(projectDir, 'package.json'), packageJson, { spaces: 2 });
|
|
90
|
+
|
|
91
|
+
// 3. 生成核心文件(解决空壳问题)
|
|
92
|
+
// 3.1 生成 index.html(核心入口)
|
|
93
|
+
const indexHtml = `<!DOCTYPE html>
|
|
94
|
+
<html lang="zh-CN">
|
|
95
|
+
<head>
|
|
96
|
+
<meta charset="UTF-8">
|
|
97
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
98
|
+
<title>${projectName} - XiangJsonCraft 2.0</title>
|
|
99
|
+
<!-- 引入框架核心 -->
|
|
100
|
+
<script src="./node_modules/xiangjsoncraft/dist/xiangjsoncraft.umd.js"></script>
|
|
101
|
+
</head>
|
|
102
|
+
<body>
|
|
103
|
+
<div id="app"></div>
|
|
104
|
+
<!-- 引入配置文件 -->
|
|
105
|
+
<script type="module">
|
|
106
|
+
import config from './config.json' assert { type: 'json' };
|
|
107
|
+
// 渲染 JSON 配置
|
|
108
|
+
window.XiangJsonCraft.render(config, document.getElementById('app'));
|
|
109
|
+
</script>
|
|
110
|
+
</body>
|
|
111
|
+
</html>`;
|
|
112
|
+
fs.writeFileSync(path.join(projectDir, 'index.html'), indexHtml);
|
|
113
|
+
|
|
114
|
+
// 3.2 生成 config.json(核心配置文件)
|
|
115
|
+
const configJson = {
|
|
116
|
+
"framework": "XiangJsonCraft 2.0.1",
|
|
117
|
+
"styles": {
|
|
118
|
+
"body": {
|
|
119
|
+
"backgroundColor": "#f0f4f8",
|
|
120
|
+
"minHeight": "100vh",
|
|
121
|
+
"margin": "0",
|
|
122
|
+
"padding": "20px",
|
|
123
|
+
"fontFamily": "Arial, sans-serif"
|
|
124
|
+
},
|
|
125
|
+
"#app": {
|
|
126
|
+
"maxWidth": "1200px",
|
|
127
|
+
"margin": "0 auto"
|
|
128
|
+
},
|
|
129
|
+
".app-title": {
|
|
130
|
+
"fontSize": "2rem",
|
|
131
|
+
"color": "#2d3748",
|
|
132
|
+
"textAlign": "center",
|
|
133
|
+
"marginBottom": "40px"
|
|
134
|
+
},
|
|
135
|
+
".app-desc": {
|
|
136
|
+
"fontSize": "1.2rem",
|
|
137
|
+
"color": "#4a5568",
|
|
138
|
+
"textAlign": "center"
|
|
58
139
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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);
|
|
140
|
+
},
|
|
141
|
+
"content": {
|
|
142
|
+
".app-title": {
|
|
143
|
+
"value": "欢迎使用 XiangJsonCraft 2.0.1",
|
|
144
|
+
"isHtml": false
|
|
145
|
+
},
|
|
146
|
+
".app-desc": {
|
|
147
|
+
"value": "零CSS零JS、纯JSON驱动的轻量前端框架",
|
|
148
|
+
"isHtml": false
|
|
80
149
|
}
|
|
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
150
|
}
|
|
373
|
-
}
|
|
151
|
+
};
|
|
152
|
+
fs.writeJsonSync(path.join(projectDir, 'config.json'), configJson, { spaces: 2 });
|
|
153
|
+
|
|
154
|
+
// 3.3 生成 README.md(使用说明)
|
|
155
|
+
const readmeMd = `# ${projectName}
|
|
156
|
+
基于 XiangJsonCraft 2.0.1 的项目
|
|
157
|
+
|
|
158
|
+
## 快速开始
|
|
159
|
+
1. 安装依赖:
|
|
160
|
+
npm install
|
|
161
|
+
|
|
162
|
+
2. 启动开发服务器:
|
|
163
|
+
npm run start
|
|
164
|
+
|
|
165
|
+
3. 自定义项目:
|
|
166
|
+
修改 config.json 文件(所有样式/内容/交互都在这里配置)
|
|
167
|
+
|
|
168
|
+
## 核心特性
|
|
169
|
+
- 纯 JSON 驱动,无需编写 CSS/JS
|
|
170
|
+
- 响应式布局,适配所有设备
|
|
171
|
+
- 实时热更新,修改配置立即生效
|
|
172
|
+
- 零配置部署,直接上传文件即可发布
|
|
173
|
+
`;
|
|
174
|
+
fs.writeFileSync(path.join(projectDir, 'README.md'), readmeMd);
|
|
175
|
+
|
|
176
|
+
spinner.succeed(chalk.green(`✅ 项目「${projectName}」创建成功!`));
|
|
177
|
+
|
|
178
|
+
// 第五步:安装依赖提示
|
|
179
|
+
const installAnswers = await inquirer.prompt([
|
|
180
|
+
{
|
|
181
|
+
type: 'confirm',
|
|
182
|
+
name: 'confirmInstall',
|
|
183
|
+
message: '是否立即安装项目依赖?',
|
|
184
|
+
default: true
|
|
185
|
+
}
|
|
186
|
+
]);
|
|
374
187
|
|
|
375
|
-
|
|
376
|
-
|
|
188
|
+
if (installAnswers.confirmInstall) {
|
|
189
|
+
const installSpinner = ora('正在安装依赖...').start();
|
|
190
|
+
try {
|
|
191
|
+
// 切换到项目目录执行安装
|
|
192
|
+
const { execSync } = await import('child_process');
|
|
193
|
+
execSync('npm install --legacy-peer-deps', {
|
|
194
|
+
cwd: projectDir,
|
|
195
|
+
stdio: 'ignore'
|
|
196
|
+
});
|
|
197
|
+
installSpinner.succeed(chalk.green('✅ 依赖安装成功!'));
|
|
198
|
+
} catch (err) {
|
|
199
|
+
installSpinner.fail(chalk.yellow('⚠️ 依赖安装失败,请手动进入项目目录执行 npm install --legacy-peer-deps'));
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 输出使用指南
|
|
204
|
+
console.log(chalk.cyan(`
|
|
205
|
+
使用指南
|
|
206
|
+
1. 进入项目目录:
|
|
207
|
+
cd ${projectName}
|
|
208
|
+
2. 启动开发服务器:
|
|
209
|
+
npm run start
|
|
210
|
+
3. 自定义项目:
|
|
211
|
+
修改 config.json 文件(所有样式/内容/交互都在这里配置)
|
|
212
|
+
4. 部署上线:
|
|
213
|
+
直接将项目文件上传到服务器即可,无需打包
|
|
214
|
+
|
|
215
|
+
📚 官方文档:https://github.com/dxiangwiki/xiangjsoncraft
|
|
216
|
+
💡 提示:必须使用本地服务器运行,不能直接打开HTML文件!
|
|
217
|
+
`));
|
|
218
|
+
|
|
219
|
+
} catch (err) {
|
|
220
|
+
spinner.fail(chalk.red(`❌ 项目创建失败:${err.message}`));
|
|
221
|
+
process.exit(1);
|
|
222
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xiangjsoncraft",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "零CSS零JS、纯JSON驱动的轻量前端框架 | Write JSON, Get a Website",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
8
|
-
"xiangjsoncraft": "./bin/create.js"
|
|
7
|
+
"xiangjsoncraft": "./bin/create.js",
|
|
8
|
+
"create-xiangjsoncraft": "./bin/create.js"
|
|
9
9
|
},
|
|
10
10
|
"main": "./dist/xiangjsoncraft.umd.js",
|
|
11
11
|
"module": "./src/renderJson.js",
|
|
@@ -39,8 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@rollup/plugin-terser": "^0.4.4",
|
|
42
|
-
"rollup": "^4.9.6"
|
|
43
|
-
"undefined": "^undefined"
|
|
42
|
+
"rollup": "^4.9.6"
|
|
44
43
|
},
|
|
45
44
|
"scripts": {
|
|
46
45
|
"build": "npx rollup -c rollup.config.js",
|
package/template/config.json
CHANGED
|
@@ -1,36 +1,234 @@
|
|
|
1
1
|
{
|
|
2
2
|
"styles": {
|
|
3
3
|
"*": {
|
|
4
|
-
"margin": 0,
|
|
5
|
-
"padding": 0,
|
|
4
|
+
"margin": "0",
|
|
5
|
+
"padding": "0",
|
|
6
6
|
"boxSizing": "border-box",
|
|
7
|
-
"fontFamily": "Segoe UI, Roboto,
|
|
7
|
+
"fontFamily": "'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif"
|
|
8
8
|
},
|
|
9
9
|
"body": {
|
|
10
10
|
"backgroundColor": "#f0f4f8",
|
|
11
11
|
"color": "#334e68",
|
|
12
12
|
"lineHeight": "1.6",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
13
|
+
"transition": "backgroundColor 0.5s ease",
|
|
14
|
+
"minHeight": "100vh"
|
|
15
15
|
},
|
|
16
|
-
".container": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
16
|
+
".welcome-container": {
|
|
17
|
+
"maxWidth": "1200px",
|
|
18
|
+
"margin": "0 auto",
|
|
19
|
+
"padding": "20px"
|
|
20
20
|
},
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
21
|
+
".welcome-header": {
|
|
22
|
+
"textAlign": "center",
|
|
23
|
+
"padding": "60px 20px",
|
|
24
|
+
"marginBottom": "40px",
|
|
25
|
+
"borderRadius": "12px",
|
|
26
|
+
"background": "linear-gradient(135deg, #4299e1, #63b3ed)",
|
|
27
|
+
"color": "white",
|
|
28
|
+
"boxShadow": "0 10px 25px -5px rgba(66, 153, 225, 0.3)",
|
|
29
|
+
"transition": "transform 0.5s ease, boxShadow 0.5s ease"
|
|
30
|
+
},
|
|
31
|
+
".welcome-header:hover": {
|
|
32
|
+
"transform": "translateY(-5px)",
|
|
33
|
+
"boxShadow": "0 15px 30px -8px rgba(66, 153, 225, 0.4)"
|
|
34
|
+
},
|
|
35
|
+
".logo-container": {
|
|
36
|
+
"marginBottom": "30px"
|
|
37
|
+
},
|
|
38
|
+
".logo": {
|
|
39
|
+
"width": "120px",
|
|
40
|
+
"height": "120px",
|
|
41
|
+
"margin": "0 auto",
|
|
42
|
+
"backgroundColor": "white",
|
|
43
|
+
"borderRadius": "50%",
|
|
44
|
+
"display": "flex",
|
|
45
|
+
"alignItems": "center",
|
|
46
|
+
"justifyContent": "center",
|
|
47
|
+
"fontSize": "48px",
|
|
48
|
+
"color": "#4299e1",
|
|
49
|
+
"boxShadow": "0 4px 12px rgba(0, 0, 0, 0.1)"
|
|
50
|
+
},
|
|
51
|
+
".logo::after": {
|
|
52
|
+
"content": "'J'",
|
|
53
|
+
"fontWeight": "bold"
|
|
54
|
+
},
|
|
55
|
+
".main-title": {
|
|
56
|
+
"fontSize": "2.5rem",
|
|
57
|
+
"marginBottom": "15px",
|
|
58
|
+
"textShadow": "0 2px 4px rgba(0, 0, 0, 0.1)"
|
|
59
|
+
},
|
|
60
|
+
"@media (maxWidth: 768px)": {
|
|
61
|
+
".main-title": {
|
|
62
|
+
"fontSize": "2rem"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
".subtitle": {
|
|
66
|
+
"fontSize": "1.1rem",
|
|
67
|
+
"opacity": "0.9",
|
|
68
|
+
"maxWidth": "600px",
|
|
69
|
+
"margin": "0 auto"
|
|
70
|
+
},
|
|
71
|
+
".features-section": {
|
|
72
|
+
"display": "grid",
|
|
73
|
+
"gridTemplateColumns": "repeat(auto-fit, minmax(300px, 1fr))",
|
|
74
|
+
"gap": "30px",
|
|
75
|
+
"marginBottom": "60px"
|
|
76
|
+
},
|
|
77
|
+
".feature-card": {
|
|
78
|
+
"backgroundColor": "white",
|
|
79
|
+
"borderRadius": "12px",
|
|
80
|
+
"padding": "30px",
|
|
81
|
+
"boxShadow": "0 4px 12px rgba(0, 0, 0, 0.05)",
|
|
82
|
+
"transition": "transform 0.3s ease, boxShadow 0.3s ease"
|
|
83
|
+
},
|
|
84
|
+
".feature-card:hover": {
|
|
85
|
+
"transform": "translateY(-8px)",
|
|
86
|
+
"boxShadow": "0 12px 20px rgba(0, 0, 0, 0.08)"
|
|
87
|
+
},
|
|
88
|
+
".feature-icon": {
|
|
89
|
+
"width": "60px",
|
|
90
|
+
"height": "60px",
|
|
91
|
+
"borderRadius": "12px",
|
|
92
|
+
"backgroundColor": "#ebf8ff",
|
|
93
|
+
"color": "#4299e1",
|
|
94
|
+
"display": "flex",
|
|
95
|
+
"alignItems": "center",
|
|
96
|
+
"justifyContent": "center",
|
|
97
|
+
"fontSize": "24px",
|
|
98
|
+
"marginBottom": "20px"
|
|
99
|
+
},
|
|
100
|
+
".feature-title": {
|
|
101
|
+
"fontSize": "1.3rem",
|
|
102
|
+
"marginBottom": "15px",
|
|
103
|
+
"color": "#2d3748"
|
|
104
|
+
},
|
|
105
|
+
".feature-description": {
|
|
106
|
+
"color": "#718096",
|
|
107
|
+
"lineHeight": "1.7"
|
|
108
|
+
},
|
|
109
|
+
".action-section": {
|
|
110
|
+
"textAlign": "center",
|
|
111
|
+
"marginBottom": "80px"
|
|
112
|
+
},
|
|
113
|
+
".primary-button": {
|
|
114
|
+
"backgroundColor": "#4299e1",
|
|
115
|
+
"color": "white",
|
|
116
|
+
"border": "none",
|
|
117
|
+
"borderRadius": "8px",
|
|
118
|
+
"padding": "14px 32px",
|
|
119
|
+
"fontSize": "1rem",
|
|
120
|
+
"fontWeight": "600",
|
|
121
|
+
"cursor": "pointer",
|
|
122
|
+
"transition": "all 0.3s ease",
|
|
123
|
+
"boxShadow": "0 4px 6px rgba(66, 153, 225, 0.2)"
|
|
124
|
+
},
|
|
125
|
+
".primary-button:hover": {
|
|
126
|
+
"backgroundColor": "#3182ce",
|
|
127
|
+
"transform": "translateY(-2px)",
|
|
128
|
+
"boxShadow": "0 6px 10px rgba(66, 153, 225, 0.3)"
|
|
129
|
+
},
|
|
130
|
+
".additional-info": {
|
|
131
|
+
"marginTop": "15px",
|
|
132
|
+
"color": "#718096",
|
|
133
|
+
"fontSize": "0.95rem"
|
|
134
|
+
},
|
|
135
|
+
".page-footer": {
|
|
136
|
+
"textAlign": "center",
|
|
137
|
+
"paddingTop": "30px",
|
|
138
|
+
"borderTop": "1px solid #e2e8f0",
|
|
139
|
+
"color": "#718096"
|
|
140
|
+
},
|
|
141
|
+
".copyright": {
|
|
142
|
+
"marginBottom": "15px",
|
|
143
|
+
"fontSize": "0.9rem"
|
|
144
|
+
},
|
|
145
|
+
".social-links": {
|
|
146
|
+
"display": "flex",
|
|
147
|
+
"justifyContent": "center",
|
|
148
|
+
"gap": "15px"
|
|
149
|
+
},
|
|
150
|
+
".social-icon": {
|
|
151
|
+
"color": "#718096",
|
|
152
|
+
"fontSize": "1.2rem",
|
|
153
|
+
"transition": "color 0.3s ease"
|
|
154
|
+
},
|
|
155
|
+
".social-icon:hover": {
|
|
156
|
+
"color": "#4299e1"
|
|
157
|
+
},
|
|
158
|
+
"body:not(.loaded) .welcome-header": {
|
|
159
|
+
"opacity": "0",
|
|
160
|
+
"transform": "translateY(20px)"
|
|
161
|
+
},
|
|
162
|
+
"body.loaded .welcome-header": {
|
|
163
|
+
"opacity": "1",
|
|
164
|
+
"transform": "translateY(0)",
|
|
165
|
+
"transition": "opacity 0.8s ease, transform 0.8s ease"
|
|
166
|
+
},
|
|
167
|
+
"body:not(.loaded) .feature-card": {
|
|
168
|
+
"opacity": "0",
|
|
169
|
+
"transform": "scale(0.95)"
|
|
170
|
+
},
|
|
171
|
+
"body.loaded .feature-card": {
|
|
172
|
+
"opacity": "1",
|
|
173
|
+
"transform": "scale(1)",
|
|
174
|
+
"transition": "opacity 0.6s ease, transform 0.6s ease"
|
|
175
|
+
},
|
|
176
|
+
"body.loaded .feature-card:nth-child(1)": {
|
|
177
|
+
"transitionDelay": "0.2s"
|
|
178
|
+
},
|
|
179
|
+
"body.loaded .feature-card:nth-child(2)": {
|
|
180
|
+
"transitionDelay": "0.4s"
|
|
181
|
+
},
|
|
182
|
+
"body.loaded .feature-card:nth-child(3)": {
|
|
183
|
+
"transitionDelay": "0.6s"
|
|
24
184
|
}
|
|
25
185
|
},
|
|
26
186
|
"content": {
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
187
|
+
".main-title": "Welcome to xiangjsoncraft",
|
|
188
|
+
".subtitle": "Create beautiful web pages with simple JSON configuration",
|
|
189
|
+
".primary-button": "Get Started",
|
|
190
|
+
".additional-info": "Join thousands of developers using our JSON configuration system",
|
|
191
|
+
".copyright": "© 2025 Dong Xiang. All rights reserved."
|
|
192
|
+
},
|
|
193
|
+
"features": {
|
|
194
|
+
"selectorPrefix": "#feature",
|
|
195
|
+
"items": [
|
|
196
|
+
{
|
|
197
|
+
"iconClass": "fas fa-code",
|
|
198
|
+
"title": "Simple Configuration",
|
|
199
|
+
"description": "Define your entire page style and content with easy-to-understand JSON"
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"iconClass": "fas fa-paint-brush",
|
|
203
|
+
"title": "Beautiful Designs",
|
|
204
|
+
"description": "Create stunning interfaces without writing complex CSS code"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"iconClass": "fas fa-mobile-alt",
|
|
208
|
+
"title": "Responsive by Default",
|
|
209
|
+
"description": "Your pages will look great on all devices with built-in responsiveness"
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
"icons": {
|
|
214
|
+
"selector": ".social-links",
|
|
215
|
+
"items": [
|
|
216
|
+
{
|
|
217
|
+
"class": "fab fa-github",
|
|
218
|
+
"url": "#"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"class": "fab fa-twitter",
|
|
222
|
+
"url": "#"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"class": "fab fa-linkedin",
|
|
226
|
+
"url": "#"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
"class": "fab fa-instagram",
|
|
230
|
+
"url": "#"
|
|
231
|
+
}
|
|
232
|
+
]
|
|
35
233
|
}
|
|
36
234
|
}
|
package/template/index.html
CHANGED
|
@@ -1,43 +1,52 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="en">
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
-
<title>
|
|
8
|
-
|
|
9
|
-
<style id="
|
|
10
|
-
<link rel="icon"
|
|
11
|
-
href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='90' font-size='90'>🟢</text></svg>">
|
|
7
|
+
<title>Welcome Page</title>
|
|
8
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
9
|
+
<style id="dynamic-styles"></style>
|
|
12
10
|
</head>
|
|
13
11
|
|
|
14
12
|
<body>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
</
|
|
13
|
+
<div class="welcome-container">
|
|
14
|
+
<header class="welcome-header">
|
|
15
|
+
<div class="logo-container">
|
|
16
|
+
<div class="logo"></div>
|
|
17
|
+
</div>
|
|
18
|
+
<h1 class="main-title"></h1>
|
|
19
|
+
<p class="subtitle"></p>
|
|
20
|
+
</header>
|
|
21
|
+
|
|
22
|
+
<main class="features-section">
|
|
23
|
+
<div class="feature-card" id="feature-1"></div>
|
|
24
|
+
<div class="feature-card" id="feature-2"></div>
|
|
25
|
+
<div class="feature-card" id="feature-3"></div>
|
|
26
|
+
</main>
|
|
27
|
+
|
|
28
|
+
<section class="action-section">
|
|
29
|
+
<a href="https://www.npmjs.com/package/xiangjsoncraft">
|
|
30
|
+
<button class="primary-button"></button>
|
|
31
|
+
</a>
|
|
32
|
+
<p class="additional-info"></p>
|
|
33
|
+
</section>
|
|
34
|
+
|
|
35
|
+
<footer class="page-footer">
|
|
36
|
+
<p class="copyright"></p>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class="social-links">
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
</footer>
|
|
23
44
|
</div>
|
|
24
45
|
|
|
25
|
-
<!-- 引入框架核心逻辑 -->
|
|
26
46
|
<script type="module">
|
|
27
|
-
|
|
28
|
-
import { renderJsonStyles } from './node_modules/xiangjsoncraft/src/renderJson.js';
|
|
47
|
+
import { renderJsonStyles } from './renderJson.js';
|
|
29
48
|
// 页面加载完成后渲染
|
|
30
|
-
|
|
31
|
-
renderJsonStyles();
|
|
32
|
-
});
|
|
33
|
-
</script>
|
|
34
|
-
|
|
35
|
-
<!-- 兼容非模块化环境(备用) -->
|
|
36
|
-
<script nomodule src="./node_modules/xiangjsoncraft/dist/xiangjsoncraft.umd.js"></script>
|
|
37
|
-
<script nomodule>
|
|
38
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
39
|
-
XiangJsonCraft.renderJsonStyles();
|
|
40
|
-
});
|
|
49
|
+
window.addEventListener('DOMContentLoaded', renderJsonStyles);
|
|
41
50
|
</script>
|
|
42
51
|
</body>
|
|
43
52
|
|