-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathbuild.js
More file actions
177 lines (149 loc) · 5.5 KB
/
build.js
File metadata and controls
177 lines (149 loc) · 5.5 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
const pug = require('pug');
const fs = require('fs-extra');
const path = require('path');
const uglifyJS = require('uglify-js');
const CleanCSS = require('clean-css');
require('dotenv').config();
// Ensure required environment variables are loaded
function loadSiteConfig() {
const SITE_CONFIG = process.env.SITE_CONFIG;
if (!SITE_CONFIG) {
console.error('Error: Missing required environment variable SITE_CONFIG.');
process.exit(1);
}
return SITE_CONFIG;
}
// Load assets JSON directly
function loadAssets(site) {
try {
// Determine the path to the assets.json file
const assetsPath = site
? path.join(__dirname, `sites/${site}/assets.json`)
: path.join(__dirname, 'assets.json');
// Read and parse the JSON file
const assets = JSON.parse(fs.readFileSync(assetsPath, 'utf-8'));
console.log(`Loaded assets from ${assetsPath}`);
return assets;
} catch (err) {
console.error(`Error loading assets for site: ${site || 'main'}`, err);
process.exit(1);
}
}
// Compile Pug templates to HTML
function compilePugTemplates(siteConfig, siteSubdirectory, assets, siteAssets) {
const viewsDir = path.join(__dirname, 'views');
const outputDir = path.join(__dirname, 'static');
const routes = Object.keys(siteAssets.main.routes);
// Ensure the output directory exists
fs.ensureDirSync(outputDir);
routes.forEach((route) => {
const template = route === '/'
? path.join(viewsDir, 'index.pug')
: path.join(__dirname, siteAssets.main.routes[route].template);
const outputPath = path.join(outputDir, route === 'index' ? 'index.html' : `${route}/index.html`);
try {
const html = pug.renderFile(template, {
siteConfig: siteConfig,
siteSubdirectory: siteSubdirectory,
assets,
env: process.env.NODE_ENV || 'production',
title: siteAssets.main.routes[route].title ?? siteAssets.main.routes['index'].title
});
fs.outputFileSync(outputPath, html);
console.log(`Generated: ${outputPath}`);
} catch (err) {
console.error(`Error rendering ${template} for route ${route}:`, err);
}
});
}
// Compile JavaScript files into a single output file
function compileJavaScript(assetPath, jsFiles) {
let combinedContent = '';
jsFiles.forEach((file) => {
try {
const content = fs.readFileSync(file, 'utf-8');
combinedContent += `\n// File: ${file}\n${content}`;
} catch (err) {
console.error(`Error reading JavaScript file: ${file}`, err);
}
});
try {
const minified = uglifyJS.minify(combinedContent);
if (minified.error) {
console.error('Error during JavaScript minification:', minified.error);
return;
}
fs.outputFileSync(assetPath, minified.code);
console.log(`Compiled and minified JavaScript written to: ${assetPath}`);
} catch (err) {
console.error(`Error writing compiled JavaScript to ${assetPath}:`, err);
}
}
// Compile CSS files into a single output file
function compileCSS(assetPath, cssFiles) {
let combinedContent = '';
cssFiles.forEach((file) => {
try {
const content = fs.readFileSync(file, 'utf-8');
combinedContent += `\n/* File: ${file} */\n${content}`;
} catch (err) {
console.error(`Error reading CSS file: ${file}`, err);
}
});
try {
const minified = new CleanCSS().minify(combinedContent);
if (minified.errors && minified.errors.length > 0) {
console.error('Error during CSS minification:', minified.errors);
return;
}
fs.outputFileSync(assetPath, minified.styles);
console.log(`Compiled and minified CSS written to: ${assetPath}`);
} catch (err) {
console.error(`Error writing compiled CSS to ${assetPath}:`, err);
}
}
// Helper to combine asset lists
function combineAssets(globalAssets, siteAssets) {
return globalAssets.concat(siteAssets || []);
}
// Copy images from source to destination
function copyDirectory(source, destination) {
try {
// Check if the source directory exists
if (!fs.existsSync(source)) {
console.debug(`Skipping copy: Source directory /${source.split('/')[source.split('/').length-1]} does not exist.`);
return;
}
// Use fs-extra to efficiently copy the directory
fs.copySync(source, destination, { overwrite: true });
console.log(`Copied from ${source}`);
} catch (err) {
console.error(`Error copying from ${source} to ${destination}:`, err);
}
}
// Main build process
function build() {
const SITE_CONFIG = loadSiteConfig();
const SITE_SUBDIRECTORY = process.env.SITE_SUBDIRECTORY
const assets = loadAssets();
const siteAssets = loadAssets(SITE_CONFIG)
console.log('Starting build process...');
// Compile Pug templates
compilePugTemplates(SITE_CONFIG, SITE_SUBDIRECTORY, assets, siteAssets);
// Combine and compile JavaScript
const jsOutputPath = `static/js/main.min.js`;
const jsFiles = combineAssets(assets.main.js, siteAssets.main.js);
compileJavaScript(jsOutputPath, jsFiles);
// Combine and compile CSS
const cssOutputPath = `static/css/main.min.css`;
const cssFiles = combineAssets(assets.main.css, siteAssets.main.css);
compileCSS(cssOutputPath, cssFiles);
const sourcePath = path.join(__dirname, `sites/${SITE_CONFIG}`);
const destinationPath = path.join(__dirname, 'static');
copyDirectory(`images`, `${destinationPath}/images`);
copyDirectory(`${sourcePath}/images`, `${destinationPath}/images`);
copyDirectory(`${sourcePath}/css/fonts`, `${destinationPath}/fonts`);
console.log('Build process complete.');
}
// Start the build process
build();