Output an executable file with webpack

I'm surprised no one said a thing about webpack's BannerPlugin. I do something similar than @oklas, but using BannerPlugin to add the specific node shebang:

{
  plugins: [
    new webpack.BannerPlugin({
      banner: '#!/usr/bin/env node',
      raw: true,
    }),
  ],
}

Then I simply add the execution permissions just adding chmod to my package.json file:

"scripts": {
  "build": "webpack && chmod +x dist/mycommand"
}

Anyway, if you'd like to just use webpack you can use the WebpackShellPlugin, as said by oklas (note that using this forces you to add a new dependency, that's why I avoid using this approach):

const WebpackShellPlugin = require('webpack-shell-plugin')
{
  // [...]
  plugins: [
    new WebpackShellPlugin({
      onBuildEnd:['chmod +x dist/mycommand'],
    }),
  ],
}

If you want to avoid including WebpackShellPlugin as a dependency, you can try to define a custom plugin based on fs, as said by @taylorc93


One simple way is to use npm. Do you have an package.json in your project? Add "build": "webpack && chmod +x outputFile" to the scripts section of your package.json and build your project by running npm run build.

Another way is to add one of these solutions to your webpack.config.js:

  • simple plugin from this answer which has pre and post build handlers

  • use on-build-webpack plugin, which executes js code at the end of the webpack build process

Whatever you choose, you'll need to add this piece of code:

var chmod = require('chmod');
chmod("outputFile", 500);

You'll need to append #!/usr/bin/env node on top of the file.
I ended up with this webpack plugin using shelljs

plugins: [
  // ...plugins,
  function () {
      this.plugin('done', () => {
      shell
        .echo('#!/usr/bin/env node\n')
        .cat(`${__dirname}/build/outputfile.js`)
        .to(`${__dirname}/commandname`)
      shell.chmod(755, `${__dirname}/commandname`)
    })
  },
]