2.0.0 • Published 6 years ago

bin-exec-loader v2.0.0

Weekly downloads
65
License
MIT
Repository
github
Last release
6 years ago

bin-exec-loader

Build Status npm version npm downloads dependencies Greenkeeper badge

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

License

MIT © Rafael Milewski