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.
123 lines
3.0 KiB
123 lines
3.0 KiB
const { join } = require('path');
|
|
const fs = require('fs-extra');
|
|
const util = require('util');
|
|
|
|
const minify = require('minify');
|
|
const sass = require('sass');
|
|
const chalk = require('chalk');
|
|
|
|
const sassRender = util.promisify(sass.render);
|
|
|
|
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} outPath - The output directory
|
|
* @param {'sass' | 'js' | 'html' | 'other' | 'file'} fileType - The file type
|
|
* @returns
|
|
*/
|
|
const builder = async (path, outPath, fileType) => {
|
|
const isDirectory = (await fs.lstat(path)).isDirectory();
|
|
|
|
if (isDirectory) {
|
|
if (fileType === 'other') {
|
|
await fs.copy(path, outPath);
|
|
return;
|
|
}
|
|
|
|
let files = await fs.readdir(path);
|
|
|
|
// Filter out other files
|
|
files = files.filter((file) => file.endsWith(fileType));
|
|
|
|
// Minify the files & write them to the build directory
|
|
files.forEach((file) => fileBuilder(join(path, file), outPath, fileType));
|
|
} else {
|
|
fileBuilder(path, outPath, fileType);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Compiles a file
|
|
* @param {string} file - The input files path
|
|
* @param {'sass' | 'js' | 'html' | 'css' | 'file'} fileType - The file type
|
|
*/
|
|
const fileBuilder = async (file, outPath, fileType) => {
|
|
const t0 = performance.now();
|
|
|
|
const compiled = await compile(file, fileType);
|
|
|
|
if (compiled) {
|
|
if (fileType === 'sass') {
|
|
file = file.replace(sassExtension, '.min.css');
|
|
}
|
|
|
|
const path = file.split('/');
|
|
const fileName = path[path.length - 1];
|
|
|
|
const withPaths = replaceFileContents(compiled);
|
|
|
|
await fs.ensureDir(outPath);
|
|
|
|
await fs.writeFile(join(outPath, fileName), withPaths);
|
|
|
|
const t1 = performance.now();
|
|
|
|
console.log(`${chalk.gray(fileName)} ${Math.round(t1 - t0)}ms`);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Compiles a string of data given its type.
|
|
* @param {string} data
|
|
* @param {'sass' | 'js' | 'html' | 'css' | 'file'} fileType
|
|
* @returns {Promise<string>} The compiled data
|
|
*/
|
|
const compile = async (file, fileType) => {
|
|
switch (fileType) {
|
|
case 'sass':
|
|
const data = await sassRender({ file, outputStyle: 'compressed' });
|
|
|
|
return data.css.toString();
|
|
case 'js':
|
|
case 'css':
|
|
case 'html':
|
|
return await minify(file).catch((err) =>
|
|
console.log('Error compiling file ' + file + ':' + err)
|
|
);
|
|
default:
|
|
return await fs.readFile(file, { encoding: 'utf-8' });
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Replaces all specified paths in builder.config.js with their definitions
|
|
* @param {string} data - The data that needs its paths replaced
|
|
* @returns
|
|
*/
|
|
const replaceFileContents = (data) => {
|
|
if (config.paths) {
|
|
Object.keys(config.paths).forEach((key) => {
|
|
data = data.replace(new RegExp(key, 'g'), '/' + config.paths[key]);
|
|
});
|
|
}
|
|
|
|
data = data.replace(new RegExp(sassExtension, 'g'), '.min.css');
|
|
|
|
if (process.env.TARGET_BROWSER != 'chrome') {
|
|
data = data.replace(new RegExp('chrome.', 'g'), 'browser.');
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
module.exports = {
|
|
builder,
|
|
fileBuilder,
|
|
};
|