bin-exec-loader
v2.0.0
Published
Execute any binary as a webpack loader
Downloads
21
Maintainers
Readme
bin-exec-loader
Pipe any file through any binary with webpack.
Usage Examples
- You could transform any
/\.wav$/
to.mp3
using ffmpeg - You could transform any
/\.pdf$/
to single JPGs ImageMagick - This list could go on indefinitely...
Install
$ npm install bin-exec-loader --save
Usage
In your webpack.config.js
add the bin-exec-loader
Examples
Let's say you would like to use imagemagick convert
to scale all your images down by 50%
In plain bash you would do like this:
$ convert input/image.png -resize 50% output/image.png
Then if you wish to execute the same command but as a webpack-loader you would do:
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{ loader: 'file-loader', options: { name: '[name].[ext]' } },
{
loader: 'bin-exec-loader',
options: {
binary: 'convert', // imagemagick converter binary
prefix: '-', // because imagemagick uses an uncommon syntax -like-this --instead-of-this
export: false, // because i want to let file-loader handle the output
emitFile: false, // otherwise we will end up with the original input file also saved on disk
args: {
$1: '[input]', // [input] will be replaced by the current file that is being proceed
resize: '50%',
$2: '[output]' // [output] will be where your output get's temporarily written
}
}
}
]
}
]
}
You can also set dynamic args like this:
const smallImage = require('./test/sample-files/sample.png?resize=50%25') // 50%25 is the encoded version of 50%
{
test: /\.(png|jpg|gif)$/,
loader: 'bin-exec-loader',
options: {
binary: 'convert',
prefix: '-',
args: {
$1: '[input]',
resize: '[resize]', // now all the parameters you send from the queryString will be available here as [param]
//resize: '[resize=50%]', // optionally you can set a default value
$2: '[output]'
}
}
}
if your binary produces multiple outputs you can grab those like this:
convert each page of a pdf to jpg and retrieve an array of paths as result
{
test: /\.pdf$/,
loader: 'bin-exec-loader',
options: {
binary: 'convert',
prefix: '-',
multiple: true, // let the loader knows there will be more than one output
emitFile: /\d\.jpg$/ // emit only the files ending with this pattern. e.g file-01.jpg
name: '[name].jpg'
args: {
$1: '[input]',
$2: '[output]'
}
}
}
console.log(require('./some/file.pdf'))
// [ 'file-01.jpg', file-02.jpg', 'file-03.jpg', 'file-04.jpg' ]
How about a loader over http? optimizing your image using tinypng api?
$ curl --user api:YOUR_API_KEY --data-binary @unoptimized.png https://api.tinify.com/shrink
{
test: /\.(png|jpg|gif)$/,
use: 'bin-exec-loader',
options: {
binary: 'curl',
export: true,
args: {
user: 'api:YOUR_API_KEY',
dataBinary: '@[input]',
$0: 'https://api.tinify.com/shrink'
}
}
}
Then in some file in your bundle..
const file = require('some-file.png')
console.log(file);
/**
{
"input": {
"size": 826071,
"type": "image/png"
},
"output": {
"size": 183477,
"type": "image/png",
"width": 1000,
"height": 665,
"ratio": 0.2221,
"url": "https://api.tinify.com/output/sau7d5debbhlrtae.png"
}
}
**/
You can also chain it with pretty much with any loader, you just need to understand the use of the option export, e.g: in the example above you could also archive the same result chaining it with json-loader
:
{
test: /\.(png|jpg|gif)$/,
use: [
{ loader: 'json-loader' },
{
loader: 'bin-exec-loader',
options: {
binary: 'curl',
//export: true, disable export so the raw output is passed to the next loader
args: {
user: 'api:YOUR_API_KEY',
dataBinary: '@[input]',
$0: 'https://api.tinify.com/shrink'
}
}
}
]
}
Options
Testing
To run the tests locally it's necessary to have installed ImageMagick and GhostScript