185 lines
3.6 KiB
JavaScript
Vendored
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;
|