Skip to content

Instantly share code, notes, and snippets.

@Akiyamka
Last active May 27, 2020 09:41
Show Gist options
  • Save Akiyamka/2b4de069fbe7577653aab32bf142cb7b to your computer and use it in GitHub Desktop.
Save Akiyamka/2b4de069fbe7577653aab32bf142cb7b to your computer and use it in GitHub Desktop.
const { mv, ls, mkdir, isFolder } = require('./utils')
class SortOutput {
distPath = null;
constructor(rules) {
this.rules = rules;
this.start = this._start.bind(this)
}
filtrate(arr, condition) {
return arr.filter(f => condition.test(f));
}
async fileList() {
const fileNames = await ls(this.distPath);
return fileNames.map(fileName => `${this.distPath}/${fileName}`);
}
async createFolder(path) {
return mkdir(path);
}
async checkFolderExistence(path) {
return isFolder(path)
}
move(file, folder) {
return mv(file, folder);
}
getFullOutputPath(output) {
return `${this.distPath}/${output}`;
}
async generateMoveTasks() {
const fileList = await this.fileList();
return this.rules.reduce((acc, {test, output}) => {
const folder = this.getFullOutputPath(output);
if (acc[folder] === undefined) acc[folder] = [];
const needMove = this.filtrate(fileList, test);
acc[folder] = acc[folder].concat(needMove)
return acc;
}, {});
}
/**
* @return Promise<{ [targetPath]: filePath[] }>
*/
async _start() {
const moveTasks = await this.generateMoveTasks();
for (const [folder, files] of Object.entries(moveTasks)) {
const folderExist = await this.checkFolderExistence(folder);
if (!folderExist) {
await this.createFolder(folder);
}
files
.filter(file => file !== folder)
.map(file => this.move(file, folder));
}
}
}
/**
* @param {Object} rules
* @param {string} rules.test
* @param {string} rules.output
*/
class SortOutputWebpackPlugin extends SortOutput {
apply(compiler) {
this.distPath = compiler.options.output.path;
if (compiler.hooks) {
compiler.hooks.afterEmit.tapAsync('afterEmit', this.start);
} else {
compiler.plugin('after-emit', this.start);
}
}
}
module.exports = SortOutputWebpackPlugin;
const path = require('path');
const fs = require('fs').promises;
const rimraf = require('rimraf');
const ncp = require('ncp').ncp;
module.exports.ls = fs.readdir;
function rm(dist) {
return new Promise((res, rej) =>
rimraf(dist, { disableGlob: true }, error => error ? rej(error) : res()
));
}
module.exports.rm = rm;
function cpRecursive(from, to) {
const options = {
stopOnErr: true,
clobber: false,
limit: 10,
};
return new Promise((res, rej) => {
ncp(from, to, options, errList => {
if (errList) return rej(errList[0]);
rm(from).then(res).catch(rej);
});
})
}
function cp(from, to, { recursive } = { recursive: false }) {
return recursive ? fs.copyFile(from, to) : cpRecursive(from, to);
}
module.exports.cp = cp;
async function mv(from, to) {
const folder = await isFolder(from);
return cp(from, to + '/' + path.basename(from), { recursive: folder });
}
module.exports.mv = mv;
function mkdir(path) {
return fs.mkdir(path, { recursive: true });
}
module.exports.mkdir = mkdir;
async function isFolder(path) {
try {
const stat = await fs.stat(path);
return stat.isDirectory();
} catch(error) {
return false;
}
}
module.exports.isFolder = isFolder;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment