68 lines
4.2 KiB
JavaScript
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)
|
|
} |