README
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-looper
Getting 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:
src
directory (of typestring
, relative to your project)dist
directory (optional - of typestring
, relative to your project)- If no
dist
is specified thensrc
is modified directly
- If no
FileLooper
has two methods: addPlugin
and run
.addPlugin()
)
Adding a Plugin (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 thisstring
will be written to the given file. By default this will be used forHTML
files unless specified with theuseDoc
attribute.document <JSDOM document>
(optional) Only available if the current file is anHTML
file. This is aJSDOM
representation of the current file. The contents of the file was input into aJSDOM
Object, and then thedom.window.document
of 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 totrue
if you would likeFileLooper
to ignore thedataStr
property and use thedocument
property (only applicable forHTML
files). 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 anid
and / orcategories
to your Plugin so you can select which Plugins you'd like to run in therun()
method. This also lets you specify on whichfiles
&directories
this 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 stringminify
to this array of categories, and then inrun()
you specify toonlyDo
the Plugins with theminify
category)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
FileLoop
(.run()
)
Running the 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