pug-site-core 1.0.13 → 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/index.js +33 -33
- package/lib/devServer.js +35 -61
- package/lib/generate.js +167 -225
- package/lib/paths.js +21 -13
- package/lib/utils.js +17 -3
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -18,37 +18,37 @@ export const pugSiteCore = {
|
|
|
18
18
|
translateLanguageData,
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
let curCmd = process.env.npm_lifecycle_event;
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
23
|
+
try {
|
|
24
|
+
switch (curCmd) {
|
|
25
|
+
case "getFun":
|
|
26
|
+
await generateGetDataFn();
|
|
27
|
+
break;
|
|
28
|
+
case "getData":
|
|
29
|
+
await generateGetDataFn();
|
|
30
|
+
const args = process.argv.slice(2);
|
|
31
|
+
await fetchDataToJsonFile(args);
|
|
32
|
+
break;
|
|
33
|
+
case "dev":
|
|
34
|
+
startDevServer();
|
|
35
|
+
break;
|
|
36
|
+
case "compileFn":
|
|
37
|
+
await compilePagesPugToFn();
|
|
38
|
+
break;
|
|
39
|
+
case "buildFn":
|
|
40
|
+
await buildFn();
|
|
41
|
+
break;
|
|
42
|
+
case "buildStatic":
|
|
43
|
+
await buildStatic();
|
|
44
|
+
break;
|
|
45
|
+
case "lang":
|
|
46
|
+
await translateLanguageData();
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
console.log(`未知的命令: ${curCmd}`);
|
|
50
|
+
}
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error(`执行命令 ${curCmd} 时发生错误:`, error);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
package/lib/devServer.js
CHANGED
|
@@ -5,10 +5,10 @@ import fse from "fs-extra";
|
|
|
5
5
|
import _ from "lodash";
|
|
6
6
|
import {
|
|
7
7
|
getCompilePugFilter,
|
|
8
|
-
pagesPathFilter,
|
|
9
8
|
getIdleProt,
|
|
10
9
|
matchESI,
|
|
11
10
|
pathSymbol,
|
|
11
|
+
getJsonData,
|
|
12
12
|
} from "./utils.js";
|
|
13
13
|
import http from "http";
|
|
14
14
|
import WebSocket, { WebSocketServer } from "ws";
|
|
@@ -73,59 +73,46 @@ function setupRoutes(app, wss) {
|
|
|
73
73
|
device = "mobile";
|
|
74
74
|
}
|
|
75
75
|
let language = config.languageList[0];
|
|
76
|
-
let lastPath =
|
|
76
|
+
let lastPath = req.path;
|
|
77
77
|
let data;
|
|
78
78
|
let jsonDataPath;
|
|
79
79
|
let pugPath;
|
|
80
|
-
let findPageInfoObj = await matchFileMapTable(lastPath, language, device);
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
// 构建完整的URL对象
|
|
82
|
+
const protocol = req.protocol;
|
|
83
|
+
const host = req.get("host");
|
|
84
|
+
const fullUrl = `${protocol}://${host}${req.originalUrl}`;
|
|
85
|
+
const urlObj = new URL(fullUrl);
|
|
86
|
+
let pageInfoObj = await matchRouter(urlObj, language, device);
|
|
87
|
+
if (!pageInfoObj) {
|
|
84
88
|
if (lastPath.endsWith(".html")) {
|
|
85
89
|
lastPath = lastPath.slice(0, -5);
|
|
86
90
|
} else {
|
|
87
91
|
lastPath = lastPath + "/index";
|
|
88
92
|
}
|
|
89
|
-
jsonDataPath =
|
|
90
|
-
paths.resolveRoot("jsonData", language, lastPath) + ".json";
|
|
93
|
+
jsonDataPath = paths.resolveRoot("jsonData", language, lastPath) + ".json";
|
|
91
94
|
if (fse.pathExistsSync(jsonDataPath)) {
|
|
92
95
|
data = await fse.readJSON(jsonDataPath);
|
|
93
96
|
} else {
|
|
94
97
|
console.log(jsonDataPath, "不存在此json文件页面data数据将为null");
|
|
95
98
|
jsonDataPath = null;
|
|
96
99
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
lastPath = pagesPathFilter(data._template[0]).replace(".pug", "");
|
|
101
|
-
}
|
|
102
|
-
pugPath =
|
|
103
|
-
paths.resolveRoot(pagsTemplatePath, element, lastPath) + ".pug";
|
|
104
|
-
if (fse.pathExistsSync(pugPath)) {
|
|
105
|
-
break;
|
|
106
|
-
}
|
|
100
|
+
|
|
101
|
+
if (data) {
|
|
102
|
+
lastPath = data._template.replace(".pug", "");
|
|
107
103
|
}
|
|
104
|
+
pugPath = paths.resolveRoot(pagsTemplatePath, lastPath) + ".pug";
|
|
108
105
|
} else {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
pagsTemplatePath,
|
|
113
|
-
element,
|
|
114
|
-
findPageInfoObj.pugPath
|
|
115
|
-
);
|
|
116
|
-
if (fse.pathExistsSync(pugPath)) {
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
data = findPageInfoObj.data;
|
|
121
|
-
jsonDataPath = findPageInfoObj.getDataFn;
|
|
106
|
+
pugPath = paths.resolveRoot(pagsTemplatePath, pageInfoObj.pugPath) + ".pug";
|
|
107
|
+
data = pageInfoObj.data;
|
|
108
|
+
jsonDataPath = "自定义路由数据";
|
|
122
109
|
}
|
|
123
110
|
if (fse.pathExistsSync(pugPath)) {
|
|
124
111
|
console.log(
|
|
125
|
-
`请求路径:${req.path} 模版路径:${pugPath} 数据JSON
|
|
112
|
+
`请求路径:${req.path} 模版路径:${pugPath} 数据JSON文件路径:${jsonDataPath}`
|
|
126
113
|
);
|
|
127
114
|
let commonData = {};
|
|
128
|
-
if (config.
|
|
115
|
+
if (config.changeUpdateCommon) {
|
|
129
116
|
commonData = await (
|
|
130
117
|
await import(paths.getData)
|
|
131
118
|
)["get_common_data"](language);
|
|
@@ -172,37 +159,24 @@ function setupRoutes(app, wss) {
|
|
|
172
159
|
});
|
|
173
160
|
}
|
|
174
161
|
|
|
175
|
-
async function
|
|
176
|
-
let
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
let data = await getData[obj.getDataFn](language);
|
|
191
|
-
if (Array.isArray(data)) {
|
|
192
|
-
let name = obj.outPutPath.split("/").pop().replace(/\..*$/, "");
|
|
193
|
-
const regex = /^\[.+\]$/;
|
|
194
|
-
if (regex.test(name)) {
|
|
195
|
-
let property = name.slice(1, -1);
|
|
196
|
-
data = data.find((item) => {
|
|
197
|
-
let str = String(item[property]);
|
|
198
|
-
return reqPath.includes(str);
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
}
|
|
162
|
+
async function matchRouter(url, language, device) {
|
|
163
|
+
let router = (await import(paths.router)).router;
|
|
164
|
+
let getR2Data = async (jsonPath) => {
|
|
165
|
+
jsonPath = paths.join(language, jsonPath);
|
|
166
|
+
let data = await getJsonData(jsonPath);
|
|
167
|
+
return data;
|
|
168
|
+
};
|
|
169
|
+
let params = { url, language, device, getR2Data };
|
|
170
|
+
|
|
171
|
+
for (let index = 0; index < router.length; index++) {
|
|
172
|
+
const obj = router[index];
|
|
173
|
+
if (obj.matchFn.call(params)) {
|
|
174
|
+
let data = obj.getData.call(params);
|
|
175
|
+
let pugPath = obj.getPagesFnName.call(params);
|
|
176
|
+
pugPath = pugPath.split("_").join(pathSymbol);
|
|
202
177
|
return {
|
|
203
|
-
pugPath
|
|
178
|
+
pugPath,
|
|
204
179
|
data,
|
|
205
|
-
getDataFn: obj.getDataFn,
|
|
206
180
|
};
|
|
207
181
|
}
|
|
208
182
|
}
|
package/lib/generate.js
CHANGED
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
getCompilePugFilter,
|
|
6
6
|
pathIsSame,
|
|
7
7
|
sleep,
|
|
8
|
-
pagesPathFilter,
|
|
9
8
|
pathSymbol,
|
|
10
9
|
obfuscateJavaScript,
|
|
11
10
|
} from "./utils.js";
|
|
@@ -134,238 +133,189 @@ export async function generateGetDataFn() {
|
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
/**
|
|
137
|
-
*
|
|
138
|
-
* @param {
|
|
136
|
+
* 将数据获取并写入JSON文件
|
|
137
|
+
* @param {Object[]} args - 过滤参数数组 f=func1,func2 c=jp,en
|
|
138
|
+
* @returns {Promise<void>}
|
|
139
139
|
*/
|
|
140
140
|
export async function fetchDataToJsonFile(args) {
|
|
141
141
|
try {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (value) {
|
|
150
|
-
if (key === "f") {
|
|
151
|
-
filterFun = value.split(",");
|
|
142
|
+
// 解析过滤参数,使用对象解构使代码更清晰
|
|
143
|
+
const { filterFun, filterLang } = args.reduce(
|
|
144
|
+
(acc, item) => {
|
|
145
|
+
const [key, value] = item.split("=");
|
|
146
|
+
if (value) {
|
|
147
|
+
if (key === "f") acc.filterFun = value.split(",");
|
|
148
|
+
if (key === "c") acc.filterLang = value.split(",");
|
|
152
149
|
}
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
return acc;
|
|
151
|
+
},
|
|
152
|
+
{ filterFun: [], filterLang: [] }
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
let isFillFun = (funName) => {
|
|
156
|
+
if (filterFun.length) {
|
|
157
|
+
return filterFun.includes(funName);
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
let saveJsonData = async (filePath, data) => {
|
|
163
|
+
let finalPath = paths.resolveRoot("jsonData", filePath);
|
|
164
|
+
await fse.remove(finalPath);
|
|
165
|
+
await fse.outputJson(finalPath, data);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
let checkData = (data, language, funName) => {
|
|
169
|
+
if (data === null || typeof data !== "object") {
|
|
170
|
+
return Promise.reject(
|
|
171
|
+
new Error(`${language} ${funName} 期望返回数组、对象类型返回: ${data}`)
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
if (Array.isArray(data)) {
|
|
175
|
+
if (data.length === 0) {
|
|
176
|
+
return Promise.reject(new Error(`${language} ${funName} 数据为空数组`));
|
|
155
177
|
}
|
|
178
|
+
data.forEach((item, index) => {
|
|
179
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) {
|
|
180
|
+
return Promise.reject(
|
|
181
|
+
new Error(
|
|
182
|
+
`${language} ${funName} 返回的数据不为对象数组类型返回: ${item} 下标为${index}`
|
|
183
|
+
)
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
156
187
|
}
|
|
157
|
-
|
|
188
|
+
return Promise.resolve();
|
|
189
|
+
};
|
|
158
190
|
|
|
159
191
|
// 如果没有过滤条件,清空输出目录
|
|
160
192
|
if (!filterFun.length && !filterLang.length) {
|
|
161
|
-
await fse.remove(
|
|
193
|
+
await fse.remove(paths.resolveRoot("jsonData"));
|
|
162
194
|
}
|
|
163
195
|
|
|
164
196
|
const getData = await import(paths.getData);
|
|
165
|
-
|
|
166
|
-
let pagesPugFilePathArr = await getPagesPugFilePathArr(true);
|
|
167
|
-
let filterFinishArr = arrPagesPugFilePathArr.filter(
|
|
168
|
-
(item) => !pagesPugFilePathArr.includes(item)
|
|
169
|
-
);
|
|
170
|
-
const { languageList, fileMapTable, fetchDataLangLimit } = config;
|
|
171
|
-
let starTime = Date.now();
|
|
197
|
+
const pugFilePathList = await getPagesPugFilePathArr();
|
|
172
198
|
|
|
173
|
-
|
|
174
|
-
languageList,
|
|
175
|
-
fetchDataLangLimit,
|
|
176
|
-
async (language) => {
|
|
177
|
-
// 语言过滤
|
|
178
|
-
if (filterLang.length && !filterLang.includes(language)) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
199
|
+
const { languageList, customBuildData, fetchDataLangLimit } = config;
|
|
181
200
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
201
|
+
await async.eachLimit(languageList, fetchDataLangLimit, async (language) => {
|
|
202
|
+
// 语言过滤检查
|
|
203
|
+
if (filterLang.length && !filterLang.includes(language)) return;
|
|
186
204
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
console.log(language, commonFuncName, "开始写入json文件");
|
|
192
|
-
await fse.outputJSON(
|
|
193
|
-
paths.resolveRoot("jsonData", language, "_common.json"),
|
|
194
|
-
commonData
|
|
195
|
-
);
|
|
196
|
-
}
|
|
205
|
+
// 清空指定语言的数据目录
|
|
206
|
+
if (filterLang.includes(language) && !filterFun.length) {
|
|
207
|
+
await fse.remove(paths.resolveRoot("jsonData", language));
|
|
208
|
+
}
|
|
197
209
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
obj.languageList &&
|
|
209
|
-
obj.languageList.length > 0 &&
|
|
210
|
-
!obj.languageList.includes(language)
|
|
211
|
-
) {
|
|
212
|
-
return Promise.resolve();
|
|
213
|
-
}
|
|
214
|
-
let dataFn = getData[obj.getDataFn];
|
|
215
|
-
if (!dataFn || typeof dataFn !== "function") {
|
|
216
|
-
return Promise.reject(dataFn + "获取数据函数不存在!");
|
|
217
|
-
}
|
|
210
|
+
// 处理公共数据
|
|
211
|
+
const commonFuncName = "get_common_data";
|
|
212
|
+
if (isFillFun(commonFuncName)) {
|
|
213
|
+
const commonData = await getData[commonFuncName](language);
|
|
214
|
+
console.log(language, commonFuncName, "开始写入json文件");
|
|
215
|
+
await fse.outputJSON(
|
|
216
|
+
paths.resolveRoot("jsonData", language, "_common.json"),
|
|
217
|
+
commonData
|
|
218
|
+
);
|
|
219
|
+
}
|
|
218
220
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
// 处理自定义数据
|
|
222
|
+
if (customBuildData?.length) {
|
|
223
|
+
await async.each(customBuildData, async (obj) => {
|
|
224
|
+
if (
|
|
225
|
+
obj.includeLang &&
|
|
226
|
+
obj.includeLang.length > 0 &&
|
|
227
|
+
!obj.includeLang.includes(language)
|
|
228
|
+
) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
let dataFn = getData[obj.getDataFn];
|
|
232
|
+
if (!dataFn || typeof dataFn !== "function") {
|
|
233
|
+
return Promise.reject(new Error(obj.getDataFn + "获取数据函数不存在"));
|
|
234
|
+
}
|
|
222
235
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
fileName === ""
|
|
245
|
-
) {
|
|
246
|
-
return Promise.reject(
|
|
247
|
-
dataFn +
|
|
248
|
-
"获取的数据中期望以" +
|
|
249
|
-
property +
|
|
250
|
-
`命名但是${index}下标中对象属性不存在`
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
jsonFilePath = paths.resolveRoot(
|
|
254
|
-
"jsonData",
|
|
255
|
-
language,
|
|
256
|
-
outPutPath.replace(name, fileName)
|
|
257
|
-
);
|
|
258
|
-
await fse.remove(jsonFilePath);
|
|
259
|
-
await fse.outputJson(jsonFilePath, dataItem);
|
|
260
|
-
}
|
|
261
|
-
} else {
|
|
262
|
-
jsonFilePath = paths.resolveRoot(
|
|
263
|
-
"jsonData",
|
|
264
|
-
language,
|
|
265
|
-
outPutPath
|
|
236
|
+
if (filterFun.length && !filterFun.includes(funName)) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
let data = await dataFn(language);
|
|
241
|
+
await checkData(data, language, obj.getDataFn);
|
|
242
|
+
console.log(language, obj.getDataFn, "开始写入json文件");
|
|
243
|
+
let outPutPath = obj.outPutPath.split("/").join(pathSymbol);
|
|
244
|
+
if (Array.isArray(data)) {
|
|
245
|
+
let name = outPutPath.split(pathSymbol).pop().replace(/\..*$/, "");
|
|
246
|
+
const regex = /^\[.+\]$/;
|
|
247
|
+
if (regex.test(name)) {
|
|
248
|
+
let property = name.slice(1, -1);
|
|
249
|
+
for (let index = 0; index < data.length; index++) {
|
|
250
|
+
const dataItem = data[index];
|
|
251
|
+
let fileName = dataItem[property];
|
|
252
|
+
if (!fileName) {
|
|
253
|
+
return Promise.reject(
|
|
254
|
+
new Error(
|
|
255
|
+
`${language} ${obj.getDataFn} 获取的数据中期望以${property}属性命名文件但是${index}下标中对象属性不存在或者为空字符串`
|
|
256
|
+
)
|
|
266
257
|
);
|
|
267
|
-
await fse.remove(jsonFilePath);
|
|
268
|
-
await fse.outputJson(jsonFilePath, data);
|
|
269
258
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
language,
|
|
274
|
-
outPutPath
|
|
259
|
+
await saveJsonData(
|
|
260
|
+
paths.join(language, outPutPath.replace(name, fileName)),
|
|
261
|
+
dataItem
|
|
275
262
|
);
|
|
276
|
-
await fse.remove(jsonFilePath);
|
|
277
|
-
await fse.outputJson(jsonFilePath, data);
|
|
278
263
|
}
|
|
264
|
+
} else {
|
|
265
|
+
await saveJsonData(paths.join(language, outPutPath), data);
|
|
279
266
|
}
|
|
280
|
-
})
|
|
281
|
-
|
|
267
|
+
} else if (typeof data === "object") {
|
|
268
|
+
await saveJsonData(paths.join(language, outPutPath), data);
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
282
272
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
fileName.split(pathSymbol).join("_").slice(0, -4) +
|
|
287
|
-
"_data";
|
|
273
|
+
await async.each(pugFilePathList, async (fileName) => {
|
|
274
|
+
let funName =
|
|
275
|
+
"get_" + fileName.split(pathSymbol).join("_").slice(0, -4) + "_data";
|
|
288
276
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
funName + "返回的数据不为对象数组得到类型" + type + "[]"
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
let lastJsonFilePath;
|
|
308
|
-
if (item.page_name && item.page_name.length > 0) {
|
|
309
|
-
lastJsonFilePath = paths.resolveRoot(
|
|
310
|
-
"jsonData",
|
|
311
|
-
language,
|
|
312
|
-
...jsonFilePath.slice(0, -1),
|
|
313
|
-
item.page_name
|
|
314
|
-
);
|
|
315
|
-
} else {
|
|
316
|
-
lastJsonFilePath =
|
|
317
|
-
paths.resolveRoot("jsonData", language, ...jsonFilePath) +
|
|
318
|
-
"_" +
|
|
319
|
-
++index +
|
|
320
|
-
".json";
|
|
321
|
-
}
|
|
322
|
-
let templateArr = filterFinishArr.filter(
|
|
323
|
-
(item) => pagesPathFilter(item) === fileName
|
|
324
|
-
);
|
|
325
|
-
if (
|
|
326
|
-
fse.pathExistsSync(
|
|
327
|
-
paths.resolveRoot(paths.template.pages, fileName)
|
|
328
|
-
)
|
|
329
|
-
) {
|
|
330
|
-
templateArr.unshift(fileName);
|
|
331
|
-
}
|
|
332
|
-
item._template = templateArr;
|
|
333
|
-
await fse.remove(lastJsonFilePath);
|
|
334
|
-
await fse.outputJson(lastJsonFilePath, item);
|
|
335
|
-
});
|
|
336
|
-
} else if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
337
|
-
console.log(language, funName, "开始写入json文件");
|
|
338
|
-
if (data.page_name && data.page_name.length > 0) {
|
|
339
|
-
jsonFilePath = paths.resolveRoot(
|
|
340
|
-
"jsonData",
|
|
277
|
+
let jsonFilePath = fileName.slice(0, -4).split(pathSymbol);
|
|
278
|
+
if (!getData[funName] || typeof getData[funName] !== "function") {
|
|
279
|
+
return Promise.reject(new Error(`${funName} 获取数据函数不存在`));
|
|
280
|
+
}
|
|
281
|
+
if (filterFun.length && !filterFun.includes(funName)) {
|
|
282
|
+
return Promise;
|
|
283
|
+
}
|
|
284
|
+
let data = await getData[funName](language);
|
|
285
|
+
await checkData(data, language, funName);
|
|
286
|
+
console.log(language, funName, "开始写入json文件");
|
|
287
|
+
if (Array.isArray(data)) {
|
|
288
|
+
await async.eachOfLimit(data, 64, async (item, index) => {
|
|
289
|
+
let lastJsonFilePath;
|
|
290
|
+
if (item.page_name) {
|
|
291
|
+
lastJsonFilePath = paths.join(
|
|
341
292
|
language,
|
|
342
293
|
...jsonFilePath.slice(0, -1),
|
|
343
|
-
|
|
294
|
+
item.page_name
|
|
344
295
|
);
|
|
345
296
|
} else {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
".json";
|
|
297
|
+
console.warn("下标:", index, "无page_name属性,使用index作为文件名");
|
|
298
|
+
lastJsonFilePath =
|
|
299
|
+
paths.join(language, ...jsonFilePath) + "_" + ++index + ".json";
|
|
349
300
|
}
|
|
350
|
-
|
|
351
|
-
|
|
301
|
+
item._template = fileName;
|
|
302
|
+
await saveJsonData(lastJsonFilePath, item);
|
|
303
|
+
});
|
|
304
|
+
} else {
|
|
305
|
+
if (data.page_name) {
|
|
306
|
+
jsonFilePath = paths.join(
|
|
307
|
+
language,
|
|
308
|
+
...jsonFilePath.slice(0, -1),
|
|
309
|
+
data.page_name
|
|
352
310
|
);
|
|
353
|
-
if (
|
|
354
|
-
fse.pathExistsSync(
|
|
355
|
-
paths.resolveRoot(paths.template.pages, fileName)
|
|
356
|
-
)
|
|
357
|
-
) {
|
|
358
|
-
templateArr.unshift(fileName);
|
|
359
|
-
}
|
|
360
|
-
data._template = templateArr;
|
|
361
|
-
await fse.remove(jsonFilePath);
|
|
362
|
-
await fse.outputJson(jsonFilePath, data);
|
|
363
311
|
} else {
|
|
364
|
-
|
|
312
|
+
jsonFilePath = paths.join(language, ...jsonFilePath) + ".json";
|
|
365
313
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
314
|
+
data._template = fileName;
|
|
315
|
+
await saveJsonData(jsonFilePath, data);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
});
|
|
369
319
|
} catch (error) {
|
|
370
320
|
console.error("获取数据失败:", error);
|
|
371
321
|
throw error;
|
|
@@ -376,8 +326,7 @@ export async function buildFn() {
|
|
|
376
326
|
const jsonDataPath = paths.resolveRoot("jsonData");
|
|
377
327
|
if (!fse.pathExistsSync(jsonDataPath)) {
|
|
378
328
|
return Promise.reject(
|
|
379
|
-
jsonDataPath
|
|
380
|
-
"目录不存在请先执行npm run getData生成数据!"
|
|
329
|
+
new Error(jsonDataPath + "目录不存在请先执行npm run getData生成数据!")
|
|
381
330
|
);
|
|
382
331
|
}
|
|
383
332
|
console.log("开始打包...");
|
|
@@ -393,7 +342,7 @@ export async function buildFn() {
|
|
|
393
342
|
|
|
394
343
|
const routerPath = paths.resolveRoot("router.js");
|
|
395
344
|
if (!fse.pathExistsSync(routerPath)) {
|
|
396
|
-
return Promise.reject("router.js
|
|
345
|
+
return Promise.reject(new Error("router.js文件不存在"));
|
|
397
346
|
}
|
|
398
347
|
|
|
399
348
|
await fse.copy(routerPath, paths.resolveRoot(outputPath, "page/router.js"));
|
|
@@ -412,7 +361,7 @@ export async function buildFn() {
|
|
|
412
361
|
// filter: (src, dest) => {
|
|
413
362
|
// // 排除_common.json 文件
|
|
414
363
|
// return !src.endsWith("_common.json");
|
|
415
|
-
// }
|
|
364
|
+
// },
|
|
416
365
|
// });
|
|
417
366
|
|
|
418
367
|
await fse.copy(
|
|
@@ -426,9 +375,7 @@ export async function buildFn() {
|
|
|
426
375
|
}
|
|
427
376
|
if (config.buildStaticDirArr && config.buildStaticDirArr.length > 0) {
|
|
428
377
|
return !!config.buildStaticDirArr.find((item) => {
|
|
429
|
-
return src.startsWith(
|
|
430
|
-
paths.resolveRoot(paths.template.static, item)
|
|
431
|
-
);
|
|
378
|
+
return src.startsWith(paths.resolveRoot(paths.template.static, item));
|
|
432
379
|
});
|
|
433
380
|
}
|
|
434
381
|
return true;
|
|
@@ -458,7 +405,7 @@ export async function buildStatic() {
|
|
|
458
405
|
|
|
459
406
|
if (!fse.pathExistsSync(jsonDataPath)) {
|
|
460
407
|
return Promise.reject(
|
|
461
|
-
jsonDataPath + "目录不存在请先执行npm run getData生成数据!"
|
|
408
|
+
new Error(jsonDataPath + "目录不存在请先执行npm run getData生成数据!")
|
|
462
409
|
);
|
|
463
410
|
}
|
|
464
411
|
console.log("开始打包...");
|
|
@@ -479,9 +426,7 @@ export async function buildStatic() {
|
|
|
479
426
|
}
|
|
480
427
|
if (config.buildStaticDirArr && config.buildStaticDirArr.length > 0) {
|
|
481
428
|
return !!config.buildStaticDirArr.find((item) => {
|
|
482
|
-
return src.startsWith(
|
|
483
|
-
paths.resolveRoot(paths.template.static, item)
|
|
484
|
-
);
|
|
429
|
+
return src.startsWith(paths.resolveRoot(paths.template.static, item));
|
|
485
430
|
});
|
|
486
431
|
}
|
|
487
432
|
return true;
|
|
@@ -536,24 +481,21 @@ export async function buildStatic() {
|
|
|
536
481
|
obj.pugPath.split("/").join(pathSymbol)
|
|
537
482
|
);
|
|
538
483
|
if (!fse.pathExistsSync(pugPath)) {
|
|
539
|
-
return Promise.reject(pugPath + "
|
|
484
|
+
return Promise.reject(new Error(pugPath + "模版路径不存在"));
|
|
540
485
|
}
|
|
541
486
|
let dataFn = getData[obj.getDataFn];
|
|
542
487
|
if (!dataFn || typeof dataFn !== "function") {
|
|
543
|
-
return Promise.reject(
|
|
488
|
+
return Promise.reject(new Error(obj.getDataFn + "获取数据函数不存在"));
|
|
544
489
|
}
|
|
545
490
|
let data = await dataFn(lang);
|
|
546
491
|
if (!data) {
|
|
547
|
-
return Promise.reject(dataFn + "获取的数据为null!");
|
|
492
|
+
return Promise.reject(new Error(dataFn + "获取的数据为null!"));
|
|
548
493
|
}
|
|
549
494
|
let outPutPath = obj.outPutPath.split("/").join(pathSymbol);
|
|
550
495
|
let htmlPath;
|
|
551
496
|
let html;
|
|
552
497
|
if (Array.isArray(data)) {
|
|
553
|
-
let name = outPutPath
|
|
554
|
-
.split(pathSymbol)
|
|
555
|
-
.pop()
|
|
556
|
-
.replace(/\..*$/, "");
|
|
498
|
+
let name = outPutPath.split(pathSymbol).pop().replace(/\..*$/, "");
|
|
557
499
|
const regex = /^\[.+\]$/;
|
|
558
500
|
if (regex.test(name)) {
|
|
559
501
|
let property = name.slice(1, -1);
|
|
@@ -566,10 +508,12 @@ export async function buildStatic() {
|
|
|
566
508
|
fileName === ""
|
|
567
509
|
) {
|
|
568
510
|
return Promise.reject(
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
511
|
+
new Error(
|
|
512
|
+
dataFn +
|
|
513
|
+
"获取的数据中期望以" +
|
|
514
|
+
property +
|
|
515
|
+
`命名但是${index}下标中对象${property}属性为:${fileName}`
|
|
516
|
+
)
|
|
573
517
|
);
|
|
574
518
|
}
|
|
575
519
|
htmlPath = paths.resolveRoot.join(
|
|
@@ -639,9 +583,7 @@ export async function buildStatic() {
|
|
|
639
583
|
})
|
|
640
584
|
).filter((fileName) => fileName.endsWith(".json"));
|
|
641
585
|
await async.eachLimit(pagesAllJsonFileName, 64, async (jsonFileName) => {
|
|
642
|
-
let data = await fse.readJSON(
|
|
643
|
-
paths.resolveRoot(langDataPath, jsonFileName)
|
|
644
|
-
);
|
|
586
|
+
let data = await fse.readJSON(paths.resolveRoot(langDataPath, jsonFileName));
|
|
645
587
|
let pugTemplateArr = data._template;
|
|
646
588
|
if (!pugTemplateArr) {
|
|
647
589
|
return;
|
package/lib/paths.js
CHANGED
|
@@ -5,19 +5,27 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
5
5
|
const __dirname = path.dirname(__filename);
|
|
6
6
|
const projectRoot = process.cwd();
|
|
7
7
|
|
|
8
|
+
// 定义基础路径
|
|
9
|
+
const templateRoot = path.join(projectRoot, "template");
|
|
10
|
+
|
|
11
|
+
// 辅助函数,用于生成文件URL
|
|
12
|
+
const fileUrl = (filePath) =>
|
|
13
|
+
pathToFileURL(path.resolve(projectRoot, filePath)).href;
|
|
14
|
+
|
|
8
15
|
export const paths = {
|
|
9
16
|
// 项目根目录相关
|
|
10
17
|
projectRoot,
|
|
11
18
|
lib: __dirname,
|
|
12
|
-
config:
|
|
13
|
-
getData:
|
|
14
|
-
pagesPugFn:
|
|
15
|
-
|
|
19
|
+
config: fileUrl("config.js"),
|
|
20
|
+
getData: fileUrl("getData.js"),
|
|
21
|
+
pagesPugFn: fileUrl("pagesPugFn/index.js"),
|
|
22
|
+
router: fileUrl("router.js"),
|
|
23
|
+
|
|
16
24
|
// 模板相关路径
|
|
17
25
|
template: {
|
|
18
|
-
root:
|
|
19
|
-
pages: path.join(
|
|
20
|
-
static: path.join(
|
|
26
|
+
root: templateRoot,
|
|
27
|
+
pages: path.join(templateRoot, "pages"),
|
|
28
|
+
static: path.join(templateRoot, "static"),
|
|
21
29
|
},
|
|
22
30
|
|
|
23
31
|
// 公共资源
|
|
@@ -27,12 +35,12 @@ export const paths = {
|
|
|
27
35
|
pugRuntime: path.join(__dirname, "pugRuntime.js"),
|
|
28
36
|
|
|
29
37
|
// 工具函数
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
join: (...args) => path.join(...args.map(String)),
|
|
39
|
+
|
|
40
|
+
resolveRoot: (...args) =>
|
|
41
|
+
args[0].startsWith(projectRoot)
|
|
42
|
+
? path.join(...args)
|
|
43
|
+
: path.join(projectRoot, ...args),
|
|
36
44
|
};
|
|
37
45
|
|
|
38
46
|
export default paths;
|
package/lib/utils.js
CHANGED
|
@@ -17,7 +17,7 @@ export const pathSymbol = process.platform.startsWith("win") ? "\\" : "/";
|
|
|
17
17
|
export async function getPagesPugFilePathArr(isFilter) {
|
|
18
18
|
let pagesPugFilePathArr = (
|
|
19
19
|
await fse.readdir(paths.template.pages, {
|
|
20
|
-
recursive: true
|
|
20
|
+
recursive: true,
|
|
21
21
|
})
|
|
22
22
|
).filter((fileName) => fileName.endsWith(".pug"));
|
|
23
23
|
|
|
@@ -262,8 +262,8 @@ export async function obfuscateJavaScript(
|
|
|
262
262
|
unused: true,
|
|
263
263
|
if_return: true,
|
|
264
264
|
join_vars: true,
|
|
265
|
-
drop_console: true
|
|
266
|
-
}
|
|
265
|
+
drop_console: true,
|
|
266
|
+
},
|
|
267
267
|
};
|
|
268
268
|
|
|
269
269
|
// 合并配置选项
|
|
@@ -369,3 +369,17 @@ export async function obfuscateJavaScript(
|
|
|
369
369
|
throw error;
|
|
370
370
|
}
|
|
371
371
|
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* 获取JSON数据
|
|
375
|
+
* @param {string} jsonDataPath - 基于jsonData目录的JSON数据路径
|
|
376
|
+
* @returns {Promise<any>} 返回JSON数据
|
|
377
|
+
*/
|
|
378
|
+
export async function getJsonData(jsonDataPath) {
|
|
379
|
+
let filePath = paths.resolveRoot("jsonData", jsonDataPath);
|
|
380
|
+
if (!fse.pathExistsSync(filePath)) {
|
|
381
|
+
return Promise.reject(new Error(`${filePath}的json数据不存在`));
|
|
382
|
+
}
|
|
383
|
+
let jsonData = await fse.readJSON(filePath);
|
|
384
|
+
return jsonData;
|
|
385
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pug-site-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"axios": "^1.7.7"
|
|
38
38
|
},
|
|
39
39
|
"license": "ISC",
|
|
40
|
-
"description": "
|
|
40
|
+
"description": "剔除不必要代码、添加router自定义路由并且开发环境也支持、添加自定义数据",
|
|
41
41
|
"files": [
|
|
42
42
|
"lib/",
|
|
43
43
|
"index.js"
|