file-looper v1.0.4
FileLooper
FileLooper allows you to easily build a dist (distribution) directory from a src directory of your choosing. Add plugins to run on select files to modify the file contents or name.
Why?
I couldn't really find a nice clean way to build a dist directory in my CI pipelines without hand making some version of it or including a heavy tool. I also found myself looping over the same files over and over again and wanted a way to do everything in one clean loop.
General Overview
When the FileLooper is run it will start by deleting the old dist directory (if one is specified). It will then create a new dist directory, recursively copying the src directory to do so.
Afterwards it will gather a list of every file inside of the new dist directory, look at the list of plugins you have added to your looper, and apply the plugins to each file that meet the conditions you set.
Adding a plugin is as simple as inputting a function into the .addPlugin() method of your FileLooper. A file interface is provided for you in your plugins to easily interact with each file.
Installation
npm install file-looperGetting Started
Both import and require() are supported, so you can use either syntax:
Import:
import FileLooper from 'file-looper';Require():
const { FileLooper } = require('file-looper');Once you've imported / required it, FileLooper is a class, so to create a new one you simply
const looper = new FileLooper('src', 'dist');The constructor currently takes two parameters, as shown above:
srcdirectory (of typestring, relative to your project)distdirectory (optional - of typestring, relative to your project)- If no
distis specified thensrcis modified directly
- If no
FileLooper has two methods: addPlugin and run
Adding a Plugin (.addPlugin())
To add a plugin to your FileLooper, you use the addPlugin method. This method takes two parameters: plugin <function> and options <object> (optional). Here's a simple demo:
import FileLooper from 'file-looper';
const looper = new FileLooper('src', 'dist');
// Pass in the file parameter to interact with the current file in the loop
looper.addPlugin(file => {
minifyHTML(file.dataStr);
file.renameFile = {
extension: '.min.html'
};
}, {
// You can reference this ID in .run() if you want to only run this Plugin
id: 'html-minifier',
// You can reference these categories later if, for example, you only want
// to run Plugins with one (or more) of these categories
categories: ['minify','html'],
// only applies this plugin to .html files
onlyDo: {
extensions: ['html']
}
});As you add in your Plugins, they will all be run in the order you added them (since they are just pushed to an array, you can view this array at .plugins in your FileLooper.
Here are all of the options and configurations available to you in the addPlugin method
plugin <function>This is the function that will be executed when this plugin is run. Here you can modify the contents of the given file, rename it, log anything to the console, whatever you would like to do. This function has one parameter:file <object>Your interface for interacting with the current file in the loop. It has the following properties for you to use:- ReadOnly:
loopNumber <number>By default therun()method only does one loop, but if you specify multiple loops this will keep track of what number loop you are on. It starts incrementing at1.fullPath <string>The absolute path of the current filerelativePath <string>(not implemented yet) The path of the current file relative to your projectfullFileName <string>The file name (with the file extension) of the current filefileName <string>The file name (without the file extension) of the current fileextension <string>The file extension of the current file
- Writeable:
dataStr <string>(optional) The contents, as a string, of the current file. The final result of your manipulation of thisstringwill be written to the given file. By default this will be used forHTMLfiles unless specified with theuseDocattribute.document <JSDOM document>(optional) Only available if the current file is anHTMLfile. This is aJSDOMrepresentation of the current file. The contents of the file was input into aJSDOMObject, and then thedom.window.documentof that object was returned to you here. This provides an interface to more easily query elements and manipulate them.useDoc <boolean>(optional) Set this variable totrueif you would likeFileLooperto ignore thedataStrproperty and use thedocumentproperty (only applicable forHTMLfiles). This is WriteOnly as it contains no data by default.renameFile <object>(optional) An interface provided for renaming the current file. This is WriteOnly as it contains no data by default.fileName <string>(optional) The name you would like to rename the current file to (do not include extension). If not specified, the same filename will be kept.extension <string>(optional) The new extension you would like to give to the current file. You can add the.before hand or not, your choice.
- ReadOnly:
options <object>(optional) This allows you to add anidand / orcategoriesto your Plugin so you can select which Plugins you'd like to run in therun()method. This also lets you specify on whichfiles&directoriesthis plugin should be applied to. The allowed properties (all of which are optional):id <string>(optional) A unique ID for your plugin, used byrun()to filter which Plugins you'd like to runcategories <array of strings>(optional) Similar toid, allows you to filter which Plugins you'd like to run by giving this Plugin categories (e.g. you add the stringminifyto this array of categories, and then inrun()you specify toonlyDothe Plugins with theminifycategory)onlyDo <object>(optional) Allows you to only run this Plugin on the files that meet the criteria in this ObjectfullFilePaths <array of strings or RegExp>(optional) The absolute path of any file(s) you would like to apply this plugin tofullFileNames <array of strings or RegExp>(optional) The file name(s) (including the file extension) of any file you would like to apply this plugin tofileNames <array of strings or RegExp>(optional) The file name(s) (excluding the file extension) of any file you would like to apply this plugin todirectories <array of strings or RegExp>(optional) The directory / directories of files you would like to apply this plugin toextensions <array of strings or RegExp>(optional) The file extension of the file(s) you would like to apply this plugin to
exclude <object>(optional) The opposite ofonlyDo, any file that meets the criteria in this object will not have this Plugin applied to itfullFilePaths <array of strings or RegExp>(optional) The absolute path of any file(s) you would like to NOT apply this plugin tofullFileNames <array of strings or RegExp>(optional) The file name(s) (including the file extension) of any file you would like to NOT apply this plugin tofileNames <array of strings or RegExp>(optional) The file name(s) (excluding the file extension) of any file you would like to NOT apply this plugin todirectories <array of strings or RegExp>(optional) The directory / directories of files you would like to NOT apply this plugin toextensions <array of strings or RegExp>(optional) The file extension of the file(s) you would like to NOT apply this plugin to
Running the FileLoop (.run())
Once you have added all of your Plugins to your FileLooper, you use the run method to execute run the FileLooper as you might expect. The run() method does not return any data, but it is asynchronous so make sure to watch out for that when calling it.
The run method takes one (optional) parameter: options <object>. Here is simple demo:
import FileLooper from 'file-looper';
const looper = new FileLooper('src', 'dist');
looper.addPlugin(file => {
minifyHTMLPlugin(file);
}, {
id: 'html-minifier',
categories: ['minify','html'],
onlyDo: {
extensions: ['html']
}
});
looper.addPlugin(file => {
minifyCSSPlugin(file);
}, {
id: 'css-minifier',
categories: ['minify','css'],
onlyDo: {
extensions: ['css']
}
});
// This will run all Plugins with the 'minify' category,
// but will exclude the Plugin that has the id 'css-minifier'
looper.run({
onlyDo: {
categories: ['minify']
}
exclude: {
id: ['css-minifier']
}
}).then(() => {
console.log('FileLooper has finished running!');
});Here are all of the options and configurations available to you in the run method (all of which are optional)
numLoops <number>(optional) The number of loops you would like to execute. Useful if you have Plugins that need other Plugins to apply to every file before hand. Defaults to 1 if not specified.onlyDo <object>(optional) Allows you to only run the Plugins that meet the criteria in this Objectid <array of strings>(optional) Only the Plugins that have IDs contained in this array will be runcategories <array of strings>(optional) Only the Plugins that have categories contained in this array will be run. Only one category needs to match for the Plugin to run.
exclude <object>(optional) Allows you to exclude any Plugin from running so long as it meets the criteria of this object (the opposite ofonlyDo)id <array of strings>(optional) The Plugins that have IDs contained in this array will be NOT be runcategories <array of strings>(optional) The Plugins that have categories contained in this array will NOT be run. Only one category needs to match for the Plugin to NOT run.
Quick Note: For both run and addPlugin options, if both onlyDo and exclude are specified then only the Plugins that match both creteria will be run.
License
Licensed under ISC