Files
2023-08-01 13:49:46 +02:00

68 lines
4.2 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const crypto = require('crypto')
const zopfli = require('node-zopfli')
const brotli = require('iltorb')
const mkdirp = require('mkdirp')
const postcss = require('postcss')
const chalk = require('chalk')
const log = console.log
const plugins = [
require('postcss-import'),
require('autoprefixer'),
require('css-mqpacker')(),
require('postcss-unique-selectors')(),
require('postcss-merge-selectors')(),
require('postcss-minify-selectors')(),
require('postcss-merge-longhand')(),
require('postcss-merge-idents')(),
require('postcss-convert-values')(),
require('postcss-colormin')(),
require('postcss-discard-unused')(),
require('postcss-minify-font-values'),
require('postcss-discard-duplicates')(),
require('postcss-discard-empty')(),
require('postcss-ordered-values')(),
require('cssnano')({preset: 'default'}),
require('postcss-csso'),
]
// compute the files paths (remove directories in the process)
const get_css_Files = config => new Promise((resolve, reject) => fs.readdir(path.join(config.basepath, config.css_path), (err, files) => err ? reject(err) : resolve(files.map(file => path.join(config.basepath, config.css_path, file)).filter(file => fs.statSync(file).isFile()).filter(file => path.extname(file) === '.css'))))
// read file contents
const read_css_files = (config, files) => Promise.all(files.map(file => new Promise((resolve, reject) => fs.readFile(file, 'utf-8', (err, css) => err ? reject(err) : resolve({file, css, destination: path.join(config.basepath, config.dist_path, file.replace(config.basepath, ''))})))))
// process files
const process_css_files = (config, files) => Promise.all(files.map(file => postcss(plugins).process(file.css, {from: file.file})))
// write files
const write_css_files = (config, files, result) => {
return new Promise(async (resolve, reject) => {
try {
// create directories if not present
await Promise.all(files.map(file => new Promise((res, rej) => mkdirp(path.dirname(file.destination), err => err ? rej(err) : res()))))
// write uncompressed files
await Promise.all(files.map((file, idx) => new Promise((res, rej) => fs.writeFile(file.destination, result[idx].css, err => err ? rej(err) : res()))))
// write zopfli compressed files
await Promise.all(files.map((file, idx) => new Promise((res, rej) => zopfli.gzip(new Buffer(result[idx].css), (error, output) => fs.writeFile(file.destination + '.gz', output, err => (err || error) ? rej(err || error) : res())))))
// write brotli compressed files
await Promise.all(files.map((file, idx) => new Promise((res, rej) => brotli.compress(new Buffer(result[idx].css), (error, output) => fs.writeFile(file.destination + '.br', output, err => (err || error) ? rej(err || error) : res())))))
resolve()
} catch (err) {
reject(err)
}
})
}
// compute result
const compute_result = (config, content, processed) => content.map((file, idx) => Object.assign({include: '/' + file.destination.replace(path.join(config.basepath, config.dist_path), ''), name: path.basename(file.file).replace(path.join(config.basepath, config.css_path), ''), file: file.destination, original: file.file, contents: processed[idx].css, html: '<link rel="stylesheet" href="' + '/' + config.css_path + file.destination.replace(path.join(config.basepath, config.dist_path, config.css_path), '').replace('.css', '') + '.' + crypto.createHash('md5').update(processed[idx].css).digest('hex').substr(0, 6) + '.css"/>', hashed_include: '/' + crypto.createHash('md5').update(processed[idx].css).digest('hex').substr(0, 6) + '.' + file.destination.replace(path.join(config.basepath, config.dist_path), ''), hash: crypto.createHash('md5').update(processed[idx].css).digest('hex')}))
module.exports = async (config, results) => {
log(' ', chalk.green('>>'), 'Loading css files')
const files = await get_css_Files(config)
log(' ', chalk.green('>>'), 'Reading css files')
const content = await read_css_files(config, files)
log(' ', chalk.green('>>'), 'Processing css files')
const processed = await process_css_files(config, content)
log(' ', chalk.green('>>'), 'Writing css files')
await write_css_files(config, content, processed)
return compute_result(config, content, processed)
}