使用webpack输出可执行文件

时间:2017-01-23 19:30:24

标签: node.js webpack

我目前正在编写节点CLI工具并使用webpack捆绑我的所有资产。此应用程序的入口点是js文件,我实际解析process.argv并运行命令(供参考,我正在使用tj/commander)。这样,捆绑完成后,我可以输入./<outputFile>,它将运行我的应用程序。条目文件如下所示:

import cli from './cli';

cli.parse(process.argv);

// If nothing was supplied
if (!process.argv.slice(2).length) {
  cli.outputHelp();
}

捆绑工作正常,但我无法让webpack将文件作为可执行文件输出。一旦我运行chmod +x <outputFile>,一切都很完美。有没有办法告诉webpack授予输出文件的权限是什么?

4 个答案:

答案 0 :(得分:4)

一种简单的方法是使用npm。你的项目中有package.json吗? 将"build": "webpack && chmod +x outputFile"添加到scripts的{​​{1}}部分,然后运行package.json来构建项目。

另一种方法是将这些解决方案之一添加到npm run build

  • 来自this answer的简单插件,其中包含webpack.config.jspre构建处理程序

  • 使用on-build-webpack plugin,它在webpack构建过程结束时执行js代码

无论您选择什么,您都需要添加以下代码:

post

答案 1 :(得分:3)

我很惊讶没有人对webpack BannerPlugin说了些什么。我执行的操作与@oklas类似,但使用BannerPlugin添加特定节点shebang:

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

然后我只需添加执行权限,只需将chmod添加到我的package.json文件中:

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

无论如何,如果你想使用webpack,你可以使用WebpackShellPlugin,正如oklas所说的那样(注意使用这会强迫你添加一个新的依赖,这就是为什么我避免使用这种方法):

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

如果您想避免将WebpackShellPlugin包含为依赖项,则可以尝试根据fs定义自定义插件,如@taylorc93所述

答案 2 :(得分:2)

您需要在文件顶部附加#!/usr/bin/env node 我使用shelljs

结束了这个webpack插件
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`)
    })
  },
]

答案 3 :(得分:1)

虽然@ oklas的解决方案对我来说非常合适,但我真的很想在webpack中保留所有这些。我意识到这可以通过一个非常简单的插件来完成:

plugins: [
  // ...plugins,

  function() {
    this.plugin('done', () => {
      fs.chmodSync('bin/program-name.js', '755');

      // When the webpack output doesn't have a .js extension, minification fails :(
      fs.renameSync('bin/program-name.js', 'bin/program-name');
    })
  },
]

使用适合您需求的方式!