wirejs-scripts 3.0.9 → 3.0.11
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 +3 -0
- package/bin.js +68 -34
- package/configs/webpack.config.js +11 -213
- package/package.json +4 -3
- package/ssg.js +42 -0
package/README.md
ADDED
package/bin.js
CHANGED
|
@@ -4,11 +4,13 @@ import process from 'process';
|
|
|
4
4
|
import http from 'http';
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import path from 'path';
|
|
7
|
+
import { Worker } from 'worker_threads';
|
|
7
8
|
|
|
8
9
|
import webpack from 'webpack';
|
|
9
10
|
import webpackConfigure from './configs/webpack.config.js';
|
|
10
11
|
import { rimraf } from 'rimraf';
|
|
11
12
|
import esbuild from 'esbuild';
|
|
13
|
+
import { contentType } from 'mime-types';
|
|
12
14
|
|
|
13
15
|
import { JSDOM } from 'jsdom';
|
|
14
16
|
import { useJSDOM } from 'wirejs-dom/v2';
|
|
@@ -115,7 +117,7 @@ async function handleApiResponse(req, res) {
|
|
|
115
117
|
const calls = JSON.parse(body);
|
|
116
118
|
logger.info('handling API request', body);
|
|
117
119
|
|
|
118
|
-
const apiPath = path.join(CWD, 'api', 'index.js');
|
|
120
|
+
const apiPath = path.join(CWD, 'api', 'dist', 'index.js');
|
|
119
121
|
const api = await import(`${apiPath}?cache-id=${new Date().getTime()}`);
|
|
120
122
|
|
|
121
123
|
const responses = [];
|
|
@@ -174,13 +176,7 @@ async function tryStaticPath(req, res) {
|
|
|
174
176
|
if (!fs.existsSync(fullPath)) return false;
|
|
175
177
|
logger.info('static found');
|
|
176
178
|
|
|
177
|
-
|
|
178
|
-
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
179
|
-
} else if (fullPath.endsWith(".js")) {
|
|
180
|
-
res.setHeader('Content-Type', 'text/javascript; charset=utf-8');
|
|
181
|
-
} else {
|
|
182
|
-
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
183
|
-
}
|
|
179
|
+
res.setHeader('Content-Type', contentType(path.extname(fullPath)));
|
|
184
180
|
|
|
185
181
|
try {
|
|
186
182
|
res.end(fs.readFileSync(fullPath));
|
|
@@ -214,6 +210,16 @@ function globMatch(pattern, text) {
|
|
|
214
210
|
return regex.test(text);
|
|
215
211
|
}
|
|
216
212
|
|
|
213
|
+
function toJSPath(path) {
|
|
214
|
+
if (path.endsWith('/')) {
|
|
215
|
+
return path + 'index.js';
|
|
216
|
+
} else if (!path.endsWith('.js')) {
|
|
217
|
+
return path + '.js';
|
|
218
|
+
} else {
|
|
219
|
+
return path;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
217
223
|
/**
|
|
218
224
|
*
|
|
219
225
|
* @param {Context} context
|
|
@@ -221,10 +227,11 @@ function globMatch(pattern, text) {
|
|
|
221
227
|
*/
|
|
222
228
|
function routeSSR(context, forceExt) {
|
|
223
229
|
const SSR_ROOT = path.join(CWD, 'dist', 'ssr');
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
230
|
+
|
|
231
|
+
const asJSPath = forceExt
|
|
232
|
+
? toJSPath(context.location.pathname)
|
|
233
|
+
: context.location.pathname;
|
|
234
|
+
|
|
228
235
|
const allHandlers = fs.readdirSync(SSR_ROOT, { recursive: true })
|
|
229
236
|
.filter(p => p.endsWith('.js'))
|
|
230
237
|
.map(p => `/${p}`)
|
|
@@ -270,7 +277,7 @@ async function trySSRScriptPath(req, res) {
|
|
|
270
277
|
async function trySSRPath(req, res) {
|
|
271
278
|
const context = createContext(req);
|
|
272
279
|
|
|
273
|
-
const asJSPath = context.location.pathname.replace(/\.(\w+)$/, '.js'
|
|
280
|
+
const asJSPath = context.location.pathname.replace(/\.(\w+)$/, '') + '.js';
|
|
274
281
|
const srcPath = routeSSR(context, 'js');
|
|
275
282
|
if (!srcPath) return false;
|
|
276
283
|
|
|
@@ -284,26 +291,32 @@ async function trySSRPath(req, res) {
|
|
|
284
291
|
const module = self.exports;
|
|
285
292
|
if (typeof module.generate === 'function') {
|
|
286
293
|
const doc = await module.generate(context);
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
+
if (typeof doc.outerHTML === 'undefined') {
|
|
295
|
+
res.setHeader('Content-Type', contentType(
|
|
296
|
+
context.location.pathname.split('.').pop()
|
|
297
|
+
));
|
|
298
|
+
res.end(doc);
|
|
299
|
+
} else {
|
|
300
|
+
const doctype = doc.parentNode.doctype?.name || '';
|
|
294
301
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
302
|
+
let hydrationsFound = 0;
|
|
303
|
+
while (globalThis.pendingDehydrations?.length > 0) {
|
|
304
|
+
globalThis.pendingDehydrations.shift()(doc);
|
|
305
|
+
hydrationsFound++;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (hydrationsFound) {
|
|
309
|
+
const script = doc.parentNode.createElement('script');
|
|
310
|
+
script.src = asJSPath;
|
|
311
|
+
doc.parentNode.body.appendChild(script);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
res.setHeader('Content-type', 'text/html; charset=utf-8');
|
|
315
|
+
res.end([
|
|
316
|
+
doctype ? `<!doctype ${doctype}>\n` : '',
|
|
317
|
+
doc.outerHTML
|
|
318
|
+
].join(''));
|
|
299
319
|
}
|
|
300
|
-
|
|
301
|
-
res.setHeader('Content-type', 'text/html; charset=utf-8');
|
|
302
|
-
res.end([
|
|
303
|
-
doctype ? `<!doctype ${doctype}>\n` : '',
|
|
304
|
-
doc.outerHTML
|
|
305
|
-
].join(''));
|
|
306
|
-
|
|
307
320
|
return true;
|
|
308
321
|
} else {
|
|
309
322
|
logger.info('SSR module missing generate function');
|
|
@@ -367,6 +380,25 @@ async function compile(watch = false) {
|
|
|
367
380
|
const stats = await new Promise(async (resolve, reject) => {
|
|
368
381
|
let compiler;
|
|
369
382
|
if (watch) {
|
|
383
|
+
|
|
384
|
+
const apiDir = path.join(CWD, 'api');
|
|
385
|
+
const prebuildApiWatch = await esbuild.context({
|
|
386
|
+
entryPoints: [path.join(CWD, 'api', '**', '*.ts')],
|
|
387
|
+
outdir: path.join(apiDir, 'dist'),
|
|
388
|
+
platform: 'node',
|
|
389
|
+
bundle: true,
|
|
390
|
+
external: ['./node_modules/*'],
|
|
391
|
+
format: 'esm',
|
|
392
|
+
plugins: [{
|
|
393
|
+
name: 'post-build-rebuild-api-client',
|
|
394
|
+
setup(build) {
|
|
395
|
+
build.onEnd(() => prebuildApi(apiDir))
|
|
396
|
+
}
|
|
397
|
+
}]
|
|
398
|
+
});
|
|
399
|
+
await prebuildApiWatch.rebuild();
|
|
400
|
+
prebuildApiWatch.watch();
|
|
401
|
+
|
|
370
402
|
const prebuild = await esbuild.context({
|
|
371
403
|
entryPoints: [`${CWD}/src/**/*.ts`],
|
|
372
404
|
outdir: `${CWD}/pre-dist`,
|
|
@@ -376,6 +408,7 @@ async function compile(watch = false) {
|
|
|
376
408
|
});
|
|
377
409
|
await prebuild.rebuild();
|
|
378
410
|
prebuild.watch();
|
|
411
|
+
|
|
379
412
|
webpack({
|
|
380
413
|
...getWebpackConfig(),
|
|
381
414
|
mode: 'development',
|
|
@@ -390,6 +423,7 @@ async function compile(watch = false) {
|
|
|
390
423
|
server.listen(3000).on('listening', () => {
|
|
391
424
|
console.log('Started listening on http://localhost:3000/')
|
|
392
425
|
});
|
|
426
|
+
|
|
393
427
|
} else {
|
|
394
428
|
logger.log('prebundling JS');
|
|
395
429
|
await esbuild.build({
|
|
@@ -470,13 +504,13 @@ const engine = {
|
|
|
470
504
|
async ['prebuild-api']() {
|
|
471
505
|
logger.log("prebuilding api ...");
|
|
472
506
|
await esbuild.build({
|
|
473
|
-
entryPoints: [
|
|
474
|
-
outdir: CWD,
|
|
507
|
+
entryPoints: [path.join(CWD, '**', '*.ts')],
|
|
508
|
+
outdir: path.join(CWD, 'dist'),
|
|
475
509
|
platform: 'node',
|
|
476
510
|
bundle: false,
|
|
477
511
|
format: 'esm',
|
|
478
512
|
});
|
|
479
|
-
await prebuildApi();
|
|
513
|
+
await prebuildApi(CWD);
|
|
480
514
|
logger.log("api prebuild finished");
|
|
481
515
|
},
|
|
482
516
|
};
|
|
@@ -1,28 +1,14 @@
|
|
|
1
|
-
import { useJSDOM } from 'wirejs-dom/v2';
|
|
2
|
-
import fs from 'fs';
|
|
3
1
|
import path from 'path';
|
|
4
2
|
import glob from 'glob';
|
|
5
3
|
import process from 'process';
|
|
6
4
|
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
|
7
|
-
import
|
|
8
|
-
import { JSDOM } from 'jsdom';
|
|
9
|
-
|
|
5
|
+
import { execSync } from 'child_process';
|
|
10
6
|
|
|
11
7
|
const CWD = process.cwd();
|
|
12
8
|
const SRC = 'pre-dist';
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
highlight: function (code, lang) {
|
|
17
|
-
try {
|
|
18
|
-
const highlighter = require('highlight.js');
|
|
19
|
-
const language = highlighter.getLanguage(lang) ? lang : 'plaintext';
|
|
20
|
-
return highlighter.highlight(code, { language }).value;
|
|
21
|
-
} catch (e) {
|
|
22
|
-
console.log("highlight.js not installed. Skipping syntax highlighting.");
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
});
|
|
10
|
+
const __filename = import.meta.url.replace(/^file:/, '');
|
|
11
|
+
const SELF_DIR = path.dirname(__filename);
|
|
26
12
|
|
|
27
13
|
function distPath({ subpathOut = '', subpathIn = '', extensionOut } = {}) {
|
|
28
14
|
return function ({ context, absoluteFilename }) {
|
|
@@ -37,90 +23,24 @@ function distPath({ subpathOut = '', subpathIn = '', extensionOut } = {}) {
|
|
|
37
23
|
};
|
|
38
24
|
};
|
|
39
25
|
|
|
40
|
-
const layouts = {};
|
|
41
|
-
const CollectLayouts = {
|
|
42
|
-
transformer: (content, path) => {
|
|
43
|
-
// add one to dirname prefix to include separating slash
|
|
44
|
-
const relativePath = path.slice(CWD.length + 1);
|
|
45
|
-
layouts[relativePath] = content.toString();
|
|
46
|
-
return layouts[relativePath];
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const SSG = {
|
|
51
|
-
transformer: async (content, _path) => {
|
|
52
|
-
let _meta = {};
|
|
53
|
-
|
|
54
|
-
let body;
|
|
55
|
-
try {
|
|
56
|
-
body = _path.endsWith('.md') ? marked(content.toString()) : content.toString();
|
|
57
|
-
} catch (err) {
|
|
58
|
-
console.error(`Could not parse page ${_path}`, err);
|
|
59
|
-
throw err;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// apply no layout if the document has already provided the
|
|
63
|
-
// overarching html structure.
|
|
64
|
-
if (!_meta.layout && body && (
|
|
65
|
-
String(body).startsWith('<!doctype html>')
|
|
66
|
-
|| String(body).startsWith('<html'))
|
|
67
|
-
) {
|
|
68
|
-
return body;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const layoutPath = path.join(
|
|
72
|
-
SRC,
|
|
73
|
-
'layouts',
|
|
74
|
-
(_meta.layout || 'default')
|
|
75
|
-
) + '.html';
|
|
76
|
-
|
|
77
|
-
const layout = layouts[layoutPath];
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
return layout;
|
|
81
|
-
} catch (err) {
|
|
82
|
-
console.error(`Could not parse layout ${layoutPath}`, err);
|
|
83
|
-
throw err;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
26
|
const Generated = {
|
|
89
27
|
transformer: async (content, contentPath) => {
|
|
90
|
-
useJSDOM(JSDOM);
|
|
91
|
-
|
|
92
28
|
try {
|
|
93
29
|
if (contentPath.endsWith('.js')) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
while (globalThis.pendingDehydrations?.length > 0) {
|
|
101
|
-
globalThis.pendingDehydrations.shift()(doc);
|
|
102
|
-
hydrationsFound++;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
if (hydrationsFound) {
|
|
106
|
-
const script = doc.parentNode.createElement('script');
|
|
107
|
-
script.src = contentPath.substring((`${CWD}/${SRC}/ssg`).length);
|
|
108
|
-
doc.parentNode.body.appendChild(script);
|
|
30
|
+
// generated in a subprocess to ensure imports are clean, especially
|
|
31
|
+
// when in watch mode.
|
|
32
|
+
const generatedContent = execSync(
|
|
33
|
+
`node ${SELF_DIR}/../ssg.js ${CWD}/${SRC} ${contentPath}`,
|
|
34
|
+
{
|
|
35
|
+
stdio: [ 'pipe', 'pipe', 'pipe' ]
|
|
109
36
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
doctype ? `<!doctype ${doctype}>\n` : '',
|
|
113
|
-
doc.outerHTML
|
|
114
|
-
].join('');
|
|
115
|
-
} else {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
37
|
+
);
|
|
38
|
+
return generatedContent;
|
|
118
39
|
} else {
|
|
119
40
|
return content.toString();
|
|
120
41
|
}
|
|
121
42
|
} catch (err) {
|
|
122
43
|
console.error(`Could not generate page ${contentPath}`, err);
|
|
123
|
-
throw err;
|
|
124
44
|
}
|
|
125
45
|
}
|
|
126
46
|
};
|
|
@@ -177,25 +97,6 @@ export default (env, argv) => {
|
|
|
177
97
|
target: 'web',
|
|
178
98
|
devtool,
|
|
179
99
|
plugins: [
|
|
180
|
-
|
|
181
|
-
// TODO: does it make sense to actually handle static assets
|
|
182
|
-
// first? then layouts? then everything else?
|
|
183
|
-
|
|
184
|
-
// handle layouts first. other things depend on them.
|
|
185
|
-
new CopyWebpackPlugin({
|
|
186
|
-
patterns: [
|
|
187
|
-
{
|
|
188
|
-
from: `./${SRC}/layouts/**/*.html`,
|
|
189
|
-
to: distPath({
|
|
190
|
-
subpathIn: `${SRC}/layouts`,
|
|
191
|
-
subpathOut: 'layouts'
|
|
192
|
-
}),
|
|
193
|
-
transform: CollectLayouts,
|
|
194
|
-
noErrorOnMissing: true,
|
|
195
|
-
},
|
|
196
|
-
]
|
|
197
|
-
}),
|
|
198
|
-
|
|
199
100
|
// now pages, etc.
|
|
200
101
|
new CopyWebpackPlugin({
|
|
201
102
|
patterns: [
|
|
@@ -211,111 +112,8 @@ export default (env, argv) => {
|
|
|
211
112
|
noErrorOnMissing: true,
|
|
212
113
|
priority: 5
|
|
213
114
|
},
|
|
214
|
-
// {
|
|
215
|
-
// from: './src/routes/**/*.md',
|
|
216
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
217
|
-
// transform: SSG,
|
|
218
|
-
// noErrorOnMissing: true,
|
|
219
|
-
// priority: 3,
|
|
220
|
-
// },
|
|
221
|
-
// {
|
|
222
|
-
// from: './src/routes/**/*.html',
|
|
223
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
224
|
-
// transform: SSG,
|
|
225
|
-
// noErrorOnMissing: true,
|
|
226
|
-
// priority: 3,
|
|
227
|
-
// },
|
|
228
|
-
// {
|
|
229
|
-
// from: './src/routes/**/*.xml',
|
|
230
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
231
|
-
// transform: SSG,
|
|
232
|
-
// noErrorOnMissing: true,
|
|
233
|
-
// priority: 3,
|
|
234
|
-
// },
|
|
235
|
-
// {
|
|
236
|
-
// from: './src/routes/**/*.rss',
|
|
237
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
238
|
-
// transform: SSG,
|
|
239
|
-
// noErrorOnMissing: true,
|
|
240
|
-
// priority: 3,
|
|
241
|
-
// },
|
|
242
|
-
// {
|
|
243
|
-
// from: './src/routes/**/*.css',
|
|
244
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
245
|
-
// noErrorOnMissing: true,
|
|
246
|
-
// // trasform: ???
|
|
247
|
-
// priority: 3,
|
|
248
|
-
// },
|
|
249
|
-
// {
|
|
250
|
-
// from: './src/routes/**/*.png',
|
|
251
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
252
|
-
// noErrorOnMissing: true,
|
|
253
|
-
// priority: 3,
|
|
254
|
-
// },
|
|
255
|
-
// {
|
|
256
|
-
// from: './src/routes/**/*.jpg',
|
|
257
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
258
|
-
// noErrorOnMissing: true,
|
|
259
|
-
// priority: 3,
|
|
260
|
-
// },
|
|
261
|
-
// {
|
|
262
|
-
// from: './src/routes/**/*.json',
|
|
263
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
264
|
-
// noErrorOnMissing: true,
|
|
265
|
-
// priority: 3,
|
|
266
|
-
// },
|
|
267
|
-
// {
|
|
268
|
-
// from: './src/routes/**/*.svg',
|
|
269
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
270
|
-
// noErrorOnMissing: true,
|
|
271
|
-
// priority: 3,
|
|
272
|
-
// },
|
|
273
|
-
// {
|
|
274
|
-
// from: './src/routes/**/*.mp3',
|
|
275
|
-
// to: distPath({ subpathIn: 'src/routes' }),
|
|
276
|
-
// noErrorOnMissing: true,
|
|
277
|
-
// priority: 3,
|
|
278
|
-
// },
|
|
279
115
|
],
|
|
280
116
|
}),
|
|
281
117
|
],
|
|
282
|
-
module: {
|
|
283
|
-
rules: [
|
|
284
|
-
{
|
|
285
|
-
test: /\.css$/,
|
|
286
|
-
use: [
|
|
287
|
-
"style-loader",
|
|
288
|
-
// path.resolve(__dirname, '../node_modules/style-loader'),
|
|
289
|
-
{
|
|
290
|
-
loader: "css-loader",
|
|
291
|
-
// loader: path.resolve(__dirname, '../node_modules/css-loader'),
|
|
292
|
-
options: {
|
|
293
|
-
// don't try to require() url assets
|
|
294
|
-
url: false
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
]
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
test: /\.html$/,
|
|
301
|
-
loader: "file-loader",
|
|
302
|
-
// loader: path.resolve(__dirname, '../node_modules/file-loader'),
|
|
303
|
-
options: {
|
|
304
|
-
name: "[name].[ext]",
|
|
305
|
-
}
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
test: /\.mjs$/,
|
|
309
|
-
resolve: {
|
|
310
|
-
fullySpecified: false
|
|
311
|
-
}
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
test: /\.(md|tpl)$/,
|
|
315
|
-
use: "raw-loader",
|
|
316
|
-
// use: path.resolve(__dirname, '../node_modules/raw-loader')
|
|
317
|
-
},
|
|
318
|
-
]
|
|
319
|
-
}
|
|
320
118
|
};
|
|
321
119
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wirejs-scripts",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.11",
|
|
4
4
|
"description": "Basic build and start commands for wirejs apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -28,11 +28,12 @@
|
|
|
28
28
|
"glob": "^7.2.0",
|
|
29
29
|
"jsdom": "^25.0.1",
|
|
30
30
|
"marked": "^2.0.1",
|
|
31
|
+
"mime-types": "^2.1.35",
|
|
31
32
|
"raw-loader": "^4.0.2",
|
|
32
33
|
"rimraf": "^6.0.1",
|
|
33
34
|
"style-loader": "^2.0.0",
|
|
34
35
|
"webpack": "^5.97.1",
|
|
35
36
|
"wirejs-dom": "^1.0.38",
|
|
36
|
-
"wirejs-resources": "^0.1.
|
|
37
|
+
"wirejs-resources": "^0.1.13"
|
|
37
38
|
}
|
|
38
|
-
}
|
|
39
|
+
}
|
package/ssg.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import process from 'process';
|
|
2
|
+
import { JSDOM } from 'jsdom';
|
|
3
|
+
import { useJSDOM } from 'wirejs-dom/v2';
|
|
4
|
+
|
|
5
|
+
const SRC_DIR = process.argv[2];
|
|
6
|
+
|
|
7
|
+
async function build(filename) {
|
|
8
|
+
useJSDOM(JSDOM);
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const module = await import(filename);
|
|
12
|
+
|
|
13
|
+
if (typeof module.generate === 'function') {
|
|
14
|
+
const doc = await module.generate(filename);
|
|
15
|
+
const doctype = doc.parentNode.doctype?.name || '';
|
|
16
|
+
|
|
17
|
+
let hydrationsFound = 0;
|
|
18
|
+
while (globalThis.pendingDehydrations?.length > 0) {
|
|
19
|
+
globalThis.pendingDehydrations.shift()(doc);
|
|
20
|
+
hydrationsFound++;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (hydrationsFound) {
|
|
24
|
+
const script = doc.parentNode.createElement('script');
|
|
25
|
+
script.src = filename.substring((`${SRC_DIR}/ssg`).length);
|
|
26
|
+
doc.parentNode.body.appendChild(script);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return [
|
|
30
|
+
doctype ? `<!doctype ${doctype}>\n` : '',
|
|
31
|
+
doc.outerHTML
|
|
32
|
+
].join('');
|
|
33
|
+
} else {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
} catch (err) {
|
|
37
|
+
console.error(`Could not generate page ${filename}`, err);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
console.log(await build(process.argv[3]));
|