aboutsummaryrefslogtreecommitdiff
path: root/scripts/build-frontend.js
blob: fee4f4faf7a0946249db4f0b9dbbd9ad092c2e97 (plain)
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
'use strict';

const fs = require('fs');
const glob = require('glob');
const path = require('path');
const util = require('util');
const execSync = require('child_process').execSync;

function getVersion() {
    return execSync('git describe --always --dirty --long --tags').toString();
}

function getConfig() {
    const ini = require('ini');
    const merge = require('merge');
    const camelcaseKeys = require('camelcase-keys');

    function parseIniFile(path) {
        let result = ini.parse(fs.readFileSync(path, 'utf-8')
            .replace(/#.+$/gm, '')
            .replace(/\s+$/gm, ''));
        Object.keys(result).map((key, _) => {
            result[key] = camelcaseKeys(result[key]);
        });
        return result;
    }

    let config = parseIniFile('./config.ini.dist');

    try {
        const localConfig = parseIniFile('./config.ini');
        config = merge.recursive(config, localConfig);
    } catch (e) {
        console.warn('Local config does not exist, ignoring');
    }

    delete config.basic.secret;
    delete config.smtp;
    delete config.database;
    config.service.userRanks = config.service.userRanks.split(/,\s*/);
    config.service.tagCategories = config.service.tagCategories.split(/,\s*/);
    config.meta = {
        version: getVersion(),
        buildDate: new Date().toUTCString(),
    };

    return config;
}

function bundleHtml(config) {
    const minify = require('html-minifier').minify;
    const baseHtml = fs.readFileSync('./static/html/index.htm', 'utf-8');
    glob('static/html/**/*.hbs', {}, (er, files) => {
        let templatesHtml = '';
        for (const file of files) {
            templatesHtml += util.format(
                '<template id=\'%s-template\'>%s</template>',
                path.basename(file, '.hbs').replace('_', '-'),
                fs.readFileSync(file));
        }

        const finalHtml = baseHtml
            .replace(/(<\/head>)/, templatesHtml + '$1')
            .replace(
                /(<title>)(.*)(<\/title>)/,
                util.format('$1%s$3', config.basic.name));

        fs.writeFileSync(
            './public/index.htm',
            minify(
                finalHtml, {
                    removeComments: true,
                    collapseWhitespace: true,
                    conservativeCollapse: true}));
        console.info('Bundled HTML');
    });
}

function bundleCss() {
    const minify = require('csso').minify;
    glob('static/css/**/*.css', {}, (er, files) => {
        let css = '';
        for (const file of files) {
            css += fs.readFileSync(file);
        }
        fs.writeFileSync('./public/bundle.min.css', minify(css));
        console.info('Bundled CSS');
    });
}

function bundleJs() {
    const browserify = require('browserify');
    const uglifyjs = require('uglify-js');
    glob('./static/js/**/*.js', {}, function(er, files) {
        const outputFile = fs.createWriteStream('./public/bundle.min.js');
        browserify().add(files).bundle().pipe(outputFile);
        outputFile.on('finish', function() {
            const result = uglifyjs.minify('./public/bundle.min.js');
            fs.writeFileSync('./public/bundle.min.js', result.code);
            console.info('Bundled JS');
        });
    });
}

function bundleConfig(config) {
    fs.writeFileSync(
        './static/js/.config.autogen.json', JSON.stringify(config));
}

function copyFile(source, target) {
    fs.createReadStream(source).pipe(fs.createWriteStream(target));
}

const config = getConfig();
bundleConfig(config);
bundleHtml(config);
bundleCss();
bundleJs();
copyFile('static/favicon.png', 'public/favicon.png');

© 2015 - 2026 Jakob L. Kreuze