dc09.ru-old/dc09.js

301 lines
7.4 KiB
JavaScript
Raw Normal View History

2022-12-29 16:46:35 +04:00
const fs = require('fs')
const path = require('path')
2022-12-29 16:46:35 +04:00
const cp = require('child_process')
const process = require('process')
/* Debug option */
const debug = false
/* ************ */
const exec = (cmd) => {
if (debug)
console.log(`Exec: ${cmd}`)
return cp.execSync(cmd)
}
const cwd = process.cwd()
2022-12-29 16:46:35 +04:00
const CleanCSS = require('clean-css')
2022-12-30 19:07:12 +04:00
const Handlebars = require('handlebars')
2022-12-29 16:46:35 +04:00
const html = require('html-minifier')
const red = '\033[1;31m'
const green = '\033[1;32m'
const yellow = '\033[1;33m'
const blue = '\033[1;34m'
const purple = '\033[1;35m'
2022-12-29 16:46:35 +04:00
const bold = '\033[1m'
const reset = '\033[0m'
const minjs = 'script.min.js'
const mincss = 'style.min.css'
main()
function main() {
switch (process.argv[2]) {
case 'watch':
fs.watch(cwd, {recursive: true}, (_ev, file) => {
const rel = path.relative(cwd, file)
if (rel.includes('dist/'))
return
print(`Changed: ${file}`, true, '#', yellow)
const dirs = rel.split(path.sep)
const dir = (dirs.length > 1) ? dirs[0] : '.'
buildOne(dir)
})
break
2022-12-29 16:46:35 +04:00
case 'build':
const dir = process.argv[3]
if (dir)
buildOne(dir)
else
buildAll()
break
case 'archive':
archive()
break
case 'clean':
clean()
break
default:
print('Available actions:', true)
printList([
'watch',
2022-12-29 16:46:35 +04:00
'build',
'build <dir>',
'archive',
'clean',
])
break
}
}
function buildAll() {
const dirs = fs.readdirSync('.', {
withFileTypes: true
})
.filter(file => file.isDirectory())
.map(file => file.name)
const pages = [
'.',
...dirs,
]
for (let page of pages)
buildOne(page)
print('Completed', true, 'V', green)
2022-12-29 16:46:35 +04:00
}
function buildOne(dir) {
print(
`${bold}Building:${reset} ${dir}`,
false, '>', purple,
)
2022-12-29 16:46:35 +04:00
const config = `${dir}/webpage.json`
2022-12-30 19:07:12 +04:00
if (!fs.existsSync(config)) {
2022-12-29 16:46:35 +04:00
print(
'Unable to find webpage.json, skipping',
2022-12-29 16:46:35 +04:00
false, '!', yellow,
)
return
}
2022-12-30 19:07:12 +04:00
const files = JSON.parse(fs.readFileSync(config))
fs.mkdirSync(`dist/${dir}`, {
recursive: true
})
print('Minifying JS')
minifyJs(dir, files)
print('Rendering LESS')
renderLess(dir, files)
print('Minifying CSS')
minifyCss(dir, files)
2022-12-30 19:07:12 +04:00
print('Compiling Handlebars HTML')
compileHbHtml(dir, files)
print('Converting paths in HTML')
convertPathsHtml(dir, files)
print('Minifying HTML')
minifyHtml(dir, files)
2022-12-30 15:46:46 +04:00
print('Copying other files')
copyOther(dir, files)
}
function minifyJs(dir, files) {
files.js = files.js || []
if (files.js.length == 0) return;
2022-12-29 16:46:35 +04:00
exec(
'node_modules/.bin/terser --compress --mangle ' +
`-o "dist/${dir}/${minjs}" ` +
files.js.map(js => `"${dir}/${js}"`).join(' ')
2022-12-29 16:46:35 +04:00
)
}
function renderLess(dir, files) {
files.less = files.less || []
if (files.less.length == 0) return;
2022-12-30 19:07:12 +04:00
const rendered = path.resolve(`dist/${dir}/${mincss}`)
exec(
'node_modules/.bin/lessc ' +
files.less.map(less => `"${dir}/${less}"`).join(' ') +
` "${rendered}"`
2022-12-29 16:46:35 +04:00
)
files.css = [
...(files.css || []),
rendered,
]
2022-12-29 16:46:35 +04:00
}
function minifyCss(dir, files) {
files.css = files.css || []
if (files.css.length == 0) return;
const content = new CleanCSS().minify(files.css).styles
fs.writeFileSync(`dist/${dir}/${mincss}`, content)
2022-12-29 16:46:35 +04:00
}
2022-12-30 19:07:12 +04:00
function compileHbHtml(dir, files) {
files.hb = files.hb || []
const compiled = []
for (let file of files.hb) {
const parts = file.split('.')
const base = parts.slice(0, -1).join('.') || ''
const name = path.resolve(`${dir}/${file}`)
const conf = path.resolve(`${dir}/${base}.json`)
const built = path.resolve(`dist/${dir}/${base}.html`)
if (!fs.existsSync(conf)) {
print(
`Unable to find ${conf} \n` +
' for the template, skipping',
false, '!', yellow,
)
continue
}
const ctx = JSON.parse(fs.readFileSync(conf))
const template = Handlebars.compile(
fs.readFileSync(name).toString()
)
fs.writeFileSync(built, template(ctx))
compiled.push(built)
}
files.html = [
...(files.html || []),
...compiled,
]
}
function convertPathsHtml(dir, files) {
2022-12-29 16:46:35 +04:00
const scriptRegex = /(?:<script src=['"]?js\/\w+\.js['"]?><\/script>[\s\r\n]*)+/gm
const converted = []
files.html = files.html || []
for (let file of files.html) {
2022-12-30 19:07:12 +04:00
const isAbs = path.isAbsolute(file)
const name = path.resolve(isAbs ? file : `${dir}/${file}`)
const built = path.resolve(isAbs ? file : `dist/${dir}/${file}`)
const content = fs.readFileSync(name)
.toString()
.replace(
'<script src="https://cdn.jsdelivr.net/npm/less"></script>',
''
)
.replace(
'<link rel="stylesheet/less" type="text/css" href="styles.less" />',
`<link rel="stylesheet" href="${mincss}" />`
)
.replace(
scriptRegex,
`<script src="${minjs}"></script>`
)
fs.writeFileSync(built, content)
converted.push(built)
}
files.html = converted
2022-12-29 16:46:35 +04:00
}
function minifyHtml(dir, files) {
files.html = files.html || []
for (let file of files.html) {
const isAbs = path.isAbsolute(file)
const name = (isAbs ? file : `${dir}/${file}`)
const built = (isAbs ? file : `dist/${dir}/${file}`)
const content = html.minify(
fs.readFileSync(name).toString(),
{
collapseBooleanAttributes: true,
collapseInlineTagWhitespace: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
keepClosingSlash: false,
minifyCSS: true,
minifyJS: true,
}
)
fs.writeFileSync(built, content)
}
2022-12-29 16:46:35 +04:00
}
2022-12-30 15:46:46 +04:00
function copyOther(dir, files) {
files.other = files.other || []
for (let file of files.other) {
const isAbs = path.isAbsolute(file)
const name = (isAbs ? file : `${dir}/${file}`)
const built = (isAbs ? file : `dist/${dir}/${file}`)
fs.cpSync(name, built, {
recursive: true,
errorOnExist: false,
})
}
}
2022-12-29 16:46:35 +04:00
function archive() {
exec('7z a dist.zip dist/*')
}
function clean() {
fs.rmSync('dist/', {
recursive: true,
force: true,
})
fs.rmSync('dist.zip', {
force: true,
})
2022-12-29 16:46:35 +04:00
}
function print(
str,
title = false,
symbol = '*',
color = blue,
) {
console.log(
`${color}[${symbol}]${reset} ` +
`${title ? bold : ""}${str}${reset}`
)
}
function printList(arr) {
for (let item of arr)
console.log(` ${item}`)
}