You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.5 KiB
130 lines
3.5 KiB
const fs = require('fs-extra');
|
|
const { join } = require('path');
|
|
|
|
const minify = require('minify');
|
|
const sass = require('sass');
|
|
const chalk = require('chalk');
|
|
|
|
const { performance } = require('perf_hooks');
|
|
|
|
const sassExtension = '.sass';
|
|
|
|
const config = require(join(process.cwd(), 'builder.config.js'));
|
|
|
|
/**
|
|
* Compiles files in a directory to a given directory
|
|
* @param {string} dir - The input directory
|
|
* @param {string} outDir - The output directory
|
|
* @param {string} fileExtension - The file extension
|
|
* @returns
|
|
*/
|
|
const builder = (dir, outDir, fileExtension) =>
|
|
dirChecker(outDir, () =>
|
|
fs.readdir(dir, (err, files) => {
|
|
if (err) throw new Error(err);
|
|
|
|
// Filter out other files
|
|
files = files.filter((file) => file.endsWith(fileExtension));
|
|
|
|
// Minify the files & write them to the build directory
|
|
files.forEach((file) => {
|
|
const t0 = performance.now();
|
|
|
|
compile(join(dir, file), fileExtension, (data) => {
|
|
const withPaths = replacePaths(data);
|
|
|
|
if (fileExtension === 'sass') {
|
|
file = file.replace(sassExtension, '.min.css');
|
|
}
|
|
|
|
fs.writeFile(join(outDir, file), withPaths, (err) => {
|
|
if (err) throw new Error(err);
|
|
|
|
const t1 = performance.now();
|
|
|
|
console.log(`${chalk.gray(file)} ${Math.round(t1 - t0)}ms`);
|
|
});
|
|
});
|
|
});
|
|
})
|
|
);
|
|
|
|
/**
|
|
* Compiles a string of data.
|
|
* @param {string} data
|
|
* @param {'sass' | 'js' | 'html'} type
|
|
* @param {(data) => void} callback
|
|
*/
|
|
const compile = (file, type, callback) => {
|
|
switch (type) {
|
|
case 'sass':
|
|
sass.render({ file, outputStyle: 'compressed' }, (err, data) =>
|
|
callback(data.css.toString())
|
|
);
|
|
|
|
return;
|
|
default:
|
|
return minify(file).then(callback).catch((err) => console.log('Error compiling file ' + file + ':' + err))
|
|
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Compiles a file
|
|
* @param {string} file - The input file
|
|
*/
|
|
const fileBuilder = (file, output) =>
|
|
fs.readFile(file, { encoding: 'utf-8' }, (err, data) => {
|
|
if (err) throw new Error(err);
|
|
|
|
const t0 = performance.now();
|
|
|
|
const withPaths = replacePaths(data);
|
|
|
|
fs.writeFile(output, withPaths, (err) => {
|
|
if (err) throw new Error(err);
|
|
|
|
const t1 = performance.now();
|
|
|
|
const path = file.split('/');
|
|
const fileName = path[path.length - 1];
|
|
|
|
console.log(`${chalk.gray(fileName)} ${Math.round(t1 - t0)}ms`);
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Replaces all specified paths in builder.config.js with their definitions
|
|
* @param {string} data - The data that needs its paths replaced
|
|
* @returns
|
|
*/
|
|
const replacePaths = (data) => {
|
|
if (config.paths) {
|
|
Object.keys(config.paths).forEach((key) => {
|
|
data = data.replace(new RegExp(key, 'g'), '/' + config.paths[key]);
|
|
});
|
|
|
|
data = data.replace(sassExtension, '.min.css');
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Checks if a directory exists and creates it if it doesn't.
|
|
* @param {string} dir - The directory to check
|
|
* @param {() => void} callback - The callback function
|
|
*/
|
|
const dirChecker = (dir, callback) => {
|
|
if (!fs.existsSync(dir)) {
|
|
fs.mkdir(dir, { recursive: true }, () => callback());
|
|
} else {
|
|
callback();
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
builder,
|
|
fileBuilder,
|
|
};
|