forked from tarashia/PokeFarmQoL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.js
130 lines (114 loc) · 4.13 KB
/
build.js
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
/*
This build file performs the following operations:
- Adds the appropriate userscript header (src/resources/header[-test].txt)
- Concatenates all files in src/scripts
- Replaces all resource placeholders "<% path %>" with the specified file's content
(compiles and minimizes content like LESS/jsonc first)
- Lints & saves result in the main user.js file
*/
import fs from 'fs';
import path from 'path';
import less from 'less';
import jsonc from 'jsonc';
import postcss from 'postcss';
import cssnano from 'cssnano';
import htmlMinify from 'html-minifier';
import replaceAsync from 'string-replace-async';
import { ESLint } from 'eslint';
// Unfortunately, order is important for some of these files,
// so instead of just going over the whole directory, define
// all scripts to be included, and their order, here
// Library-type scripts (only static content) should go first
// <PAGES> is where all files in scripts/pages will be added, alphabetically
const scriptFiles = [
// Static classes
'helpers.js',
'globals.js',
'localStorageManager.js',
'resources.js',
// Non-static classes
'userSettingsHandle.js',
'userSettings.js',
'userPokedex.js',
'pagesManager.js',
'qolHub.js',
'pfqol.js',
'<PAGES>',
// Script entry point
'scriptEntry.js'
];
runBuild();
async function runBuild() {
const outputPath = 'Poke-Farm-QoL.user.js';
var initContent = await fs.promises.readFile('src/resources/header.txt', 'utf8');
await fs.promises.writeFile(outputPath, initContent);
console.log('Initialized '+outputPath);
for(let i=0; i<scriptFiles.length; i++) {
if(scriptFiles[i]=='<PAGES>') {
await concatFiles('src/scripts/pages',outputPath);
}
else {
await addFileContent('src/scripts/'+scriptFiles[i],outputPath);
}
}
console.log('Linting...');
// https://eslint.org/docs/latest/developer-guide/nodejs-api
const eslint = new ESLint({ fix: true });
const results = await eslint.lintFiles([outputPath]);
const formatter = await eslint.loadFormatter("stylish");
console.log(formatter.format(results));
console.log('Done!');
}
async function addFileContent(inputPath, outputPath) {
var content = await fs.promises.readFile(inputPath, 'utf8');
console.log('Processing '+inputPath);
content = await loadResources(content);
fs.promises.appendFile(outputPath, '\n'+content+'\n');
}
// Based on https://stackoverflow.com/a/53960687
async function concatFiles(directory, outputPath) {
const files = await fs.promises.readdir(directory);
for(var i=0;i<files.length;i++) {
const filePath = path.join(directory, files[i]);
await addFileContent(filePath, outputPath);
}
}
// Replace "<% path %>" tokens with specified file content
// Based on https://stackoverflow.com/a/34498610
async function loadResources(content) {
return replaceAsync(content, /"?<%([^"<>%]+)%>"?/g, async function(match, replacePath) {
replacePath = replacePath.trim();
const replaceContent = fs.readFileSync(replacePath, 'utf8');
// https://stackoverflow.com/a/4695156
const fileExt = replacePath.split('.').pop();
console.log(' Adding '+replacePath);
switch (fileExt) {
case 'html':
return processContent(replaceContent);
case 'less':
case 'css':
return await processStyle(replaceContent);
case 'json':
case 'jsonc':
return processObject(replaceContent);
default:
return match;
}
});
}
// Pre-process HTML content
export function processContent(content) {
return htmlMinify.minify(content, {
collapseWhitespace: true
});
}
// Pre-process style content
export async function processStyle(content) {
const css = await less.render(content);
const nano = await postcss([cssnano()]).process(css.css, {from: undefined});
return nano.css;
}
// Pre-process object content to remove comments
export function processObject (content) {
return jsonc.uglify(jsonc.stripComments(content));
}