1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
import { render } from './renderPage.js';
import { Page, PageDirectory } from './pageDirectory.js';
import fs from 'fs';
import path from 'path';
import { logger } from '../logger.js';
import glob from 'glob';
import { process as processCss } from './processCss.js';
export async function buildPages(): Promise<{ success: boolean, errors: number, pageDirectory: PageDirectory}> {
// Recreate output directory
if (process.env.SKIP_OUTPUT_DIR_CREATION !== 'true') {
try {
if (fs.existsSync(process.env.OUTPUT_DIR)) {
fs.rmSync(process.env.OUTPUT_DIR, { recursive: true });
}
fs.mkdirSync(process.env.OUTPUT_DIR);
} catch (e) {
logger.error(`Failed to create output directory: ${e.message}`);
return { success: false, errors: 0, pageDirectory: null };
}
}
// Load pages
logger.info(`Reading pages from disk...`);
const pageDirectory = new PageDirectory(process.env.PAGES_DIR);
await pageDirectory.init();
let pagesCount = Object.keys(pageDirectory.getPages()).length;
logger.info(`Found ${pagesCount} pages.`);
// Render pages
logger.info(`Rendering pages...`);
let pagesRendered = 0;
let pagesFailed = 0;
for (const page of pageDirectory.getPages()) {
if (await renderPage(page, pageDirectory)) {
pagesRendered++;
} else {
pagesFailed++;
}
}
logger.info(`Rendered ${pagesRendered} of ${pagesCount} pages.`);
//TODO move to util
const ensureParentDirExists = (file: string) => {
const joinedOutputPath = path.join(process.env.OUTPUT_DIR, 'static', file);
const dir = path.dirname(joinedOutputPath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
return joinedOutputPath;
};
// Copy static files
logger.info(`Copying static files...`);
try {
const files = glob.sync(`**/*`, {
cwd: process.env.STATIC_DIR,
nodir: true,
ignore: ['**/*.scss', '**/*.css']
})
for (const file of files) {
const outputPath = ensureParentDirExists(file);
const joinedPath = path.join(process.env.STATIC_DIR, file);
fs.copyFileSync(joinedPath, outputPath);
}
logger.info(`Done.`);
} catch (e) {
logger.error(`Failed to copy static files: ${e.message}`);
}
// Process CSS files
const cssFiles = glob.sync(`**/*.{css,scss}`, {
cwd: process.env.STATIC_DIR,
nodir: true,
});
if (cssFiles.length > 0) {
logger.info(`Processing CSS files...`);
for (const file of cssFiles) {
const outputPath = ensureParentDirExists(file);
const joinedPath = path.join(process.env.STATIC_DIR, file);
let processedCss: string;
try {
processedCss = await processCss(joinedPath);
} catch (e) {
logger.error(`Failed to process CSS file ${joinedPath}`);
logger.error(e.message);
continue;
}
const newOutputPath = outputPath.replace(/\.scss$/, '.css');
fs.writeFileSync(newOutputPath, processedCss);
}
logger.info(`Done.`);
}
return { success: pagesFailed == 0, errors: pagesFailed, pageDirectory: pageDirectory};
}
async function renderPage(page: Page, pageDirectory: PageDirectory): Promise<boolean> {
let html;
try {
html = await render(page, pageDirectory);
} catch (e) {
logger.error(`Failed to render page ${page.originalPath}: ${e.message}`);
return false;
}
try {
const file = page.buildPath;
const dir = path.dirname(file);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
fs.writeFileSync(file, html);
} catch (e) {
logger.error(`Failed to write page ${page.buildPath}: ${e.message}`);
return false;
}
return true;
}
export async function rebuildSinglePage(path: string, pageDirectory: PageDirectory): Promise<boolean> {
const page = await pageDirectory.loadPage(path);
if (!page) {
return false;
}
return await renderPage(page, pageDirectory);
}
|