2017-09-13 07:52:34 +02:00

185 lines
3.6 KiB
JavaScript
Vendored

let fs = require('fs');
let md5 = require('md5');
let chokidar = require('chokidar');
let mkdirp = require('mkdirp');
let options = require('./Options');
let uglify = require('uglify-js');
let UglifyCss = require('clean-css');
class File {
/**
* Create a new File instance.
*
* @param {string} file
*/
constructor(file) {
this.file = file;
this.fileType = path.extname(file);
}
/**
* Static constructor.
*
* @param {string} file
*/
static find(file) {
return new File(file);
}
/**
* Make all nested directories in the current file path.
*/
makeDirectories() {
mkdirp.sync(this.parsePath().base);
return this;
}
/**
* Minify the file, if it is CSS or JS.
*/
minify() {
if (this.fileType === '.js') {
this.write(uglify.minify(this.file, options.uglify).code);
}
if (this.fileType === '.css') {
this.write(
new UglifyCss(options.cleanCss).minify(this.read()).styles
);
}
}
/**
* Determine if the given file exists.
*
* @param {string} file
*/
static exists(file) {
return fs.existsSync(file);
}
/**
* Read the file.
*/
read() {
return fs.readFileSync(this.file, {
encoding: 'utf-8'
});
}
/**
* Write the given contents to the file.
*
* @param {string} body
*/
write(body) {
if (typeof body === 'object') {
body = JSON.stringify(body, null, 2);
}
fs.writeFileSync(this.file, body);
return this;
}
/**
* Delete/Unlink the current file.
*/
delete() {
if (fs.existsSync(this.file)) {
fs.unlinkSync(this.file);
}
}
/**
* Watch the current file for changes.
*
* @param {Function} callback
*/
watch(callback) {
return chokidar.watch(
this.path(), { persistent: true }
).on('change', () => callback(this));
}
/**
* Fetch the full path to the file.
*
* @return {string}
*/
path() {
return path.resolve(this.file);
}
/**
* Version the current file.
*/
version() {
let contents = this.read();
let versionedPath = this.versionedPath(md5(contents));
return new File(versionedPath).write(contents);
}
/**
* Fetch a full, versioned path to the file.
*
* @param {string} hash
*/
versionedPath(hash) {
if (! hash) hash = md5(this.read());
return this.parsePath().hashedPath.replace('[hash]', hash);
}
/**
* Parse the file path into segments.
*/
parsePath() {
let outputSegments = path.parse(this.file);
return {
path: this.file,
pathWithoutExt: path.join(outputSegments.dir, `${outputSegments.name}`),
hashedPath: path.join(outputSegments.dir, `${outputSegments.name}.[hash]${outputSegments.ext}`),
base: outputSegments.dir,
file: outputSegments.base,
hashedFile: `${outputSegments.name}.[hash]${outputSegments.ext}`,
name: outputSegments.name,
isFile: !! outputSegments.ext,
isDir: ! outputSegments.ext,
ext: outputSegments.ext
};
}
/**
* Rename the file.
*
* @param {string} to
*/
rename(to) {
fs.renameSync(this.file, to);
this.file = to;
return this;
}
}
module.exports = File;