Heroku上にてES6で書いたHubotを動かしてハマったこと


現象

HubotをES6で動かしてHerokuにdeployした時に以下のようなエラーが出た

2017-04-18T16:49:42.221610+00:00 heroku[web.1]: Starting process with command `bin/hubot -a slack -n mobasol-chan --require compiled`
2017-04-18T16:49:45.704564+00:00 app[web.1]: 
2017-04-18T16:49:45.704587+00:00 app[web.1]: > [email protected] postinstall /app
2017-04-18T16:49:45.704588+00:00 app[web.1]: > babel scripts --presets es2015 --out-dir compiled
2017-04-18T16:49:45.704588+00:00 app[web.1]: 
2017-04-18T16:49:54.365144+00:00 app[web.1]: scripts/example.js -> compiled/example.js
2017-04-18T16:50:02.696724+00:00 heroku[web.1]: State changed from starting to up
2017-04-18T16:50:02.860289+00:00 app[web.1]: [Tue Apr 18 2017 16:50:02 GMT+0000 (UTC)] INFO Logged in as mobasol-chan of XXXX
2017-04-18T16:50:02.911170+00:00 app[web.1]: [Tue Apr 18 2017 16:50:02 GMT+0000 (UTC)] INFO Slack client now connected
2017-04-18T16:50:02.913561+00:00 app[web.1]: 
2017-04-18T16:50:02.913757+00:00 app[web.1]: /app/scripts/example.js:8
2017-04-18T16:50:02.915506+00:00 app[web.1]: module.exports = ( robot => {
2017-04-18T16:50:02.915831+00:00 app[web.1]:                           ^
2017-04-18T16:50:02.926768+00:00 app[web.1]: [Tue Apr 18 2017 16:50:02 GMT+0000 (UTC)] ERROR Unable to load /app/scripts/example: SyntaxError: Unexpected token >

ちなみに下記を参考にさせてもらいました。

結論

ES6形式のjsを配置するときはsrcscripts以外名前のディレクトリにを置く

  • ES6のソースをsrcもしくはscriptsディレクトリに配置する→×
  • ES6のソースをsrcもしくはscriptsディレクトリ以外に配置する→○

補足

https://github.com/github/hubot/blob/master/bin/hubot を見てみるとsrcもしくはscriptsをロードしているっぽい。
そのためsrcもしくはscriptsディレクトリにES6のjsを置いてしまうと、babelで変換したjsではなく変換前のES6を実行してエラーになっていたと思われる。

  loadScripts = ->
    scriptsPath = Path.resolve ".", "scripts"
    robot.load scriptsPath

    scriptsPath = Path.resolve ".", "src", "scripts"
    robot.load scriptsPath

    hubotScripts = Path.resolve ".", "hubot-scripts.json"
    if Fs.existsSync(hubotScripts)
      data = Fs.readFileSync(hubotScripts)
      if data.length > 0
        try
          scripts = JSON.parse data
          scriptsPath = Path.resolve "node_modules", "hubot-scripts", "src", "scripts"
          robot.loadHubotScripts scriptsPath, scripts
        catch err
          robot.logger.error "Error parsing JSON data from hubot-scripts.json: #{err}"
          process.exit(1)

        hubotScriptsWarning = "Loading scripts from hubot-scripts.json is deprecated and " +
          "will be removed in 3.0 (https://github.com/github/hubot-scripts/issues/1113) " +
          "in favor of packages for each script.\n\n"

        if scripts.length is 0
          hubotScriptsWarning += "Your hubot-scripts.json is empty, so you just need to remove it."
        else
          hubotScriptsReplacements = Path.resolve "node_modules", "hubot-scripts", "replacements.json"

          if Fs.existsSync(hubotScriptsReplacements)
            hubotScriptsWarning += "The following scripts have known replacements. Follow the link for installation instructions, then remove it from hubot-scripts.json:\n"

            replacementsData = Fs.readFileSync(hubotScriptsReplacements)
            replacements = JSON.parse(replacementsData)
            scriptsWithoutReplacements = []
            for script in scripts
              replacement = replacements[script]
              if replacement
                hubotScriptsWarning += "* #{script}: #{replacement}\n"
              else
                scriptsWithoutReplacements.push(script)
            hubotScriptsWarning += "\n"

            if scriptsWithoutReplacements.length > 0
              hubotScriptsWarning += "The following scripts don't have (known) replacements. You can try searching https://www.npmjs.com/ or http://github.com/search or your favorite search engine. You can copy the script into your local scripts directory, or consider creating a new package to maintain yourself. If you find a replacement or create a package yourself, please post on https://github.com/github/hubot-scripts/issues/1641:\n"
              hubotScriptsWarning += "* #{script}\n" for script in scriptsWithoutReplacements

              hubotScriptsWarning += "\nYou an also try updating hubot-scripts to get the latest list of replacements: npm install --save hubot-scripts@latest"
          else
              hubotScriptsWarning += "To get a list of recommended replacements, update your hubot-scripts: npm install --save hubot-scripts@latest"

      robot.logger.warning hubotScriptsWarning

    externalScripts = Path.resolve ".", "external-scripts.json"
    if Fs.existsSync(externalScripts)
      Fs.readFile externalScripts, (err, data) ->
        if data.length > 0
          try
            scripts = JSON.parse data
          catch err
            console.error "Error parsing JSON data from external-scripts.json: #{err}"
            process.exit(1)
          robot.loadExternalScripts scripts

    for path in Options.scripts
      if path[0] == '/'
        scriptsPath = path
      else
        scriptsPath = Path.resolve ".", path
      robot.load scriptsPath

疑問点

ローカルで動かした時はエラーにならず、heroku上だとエラーになった理由がわからない。バージョンかな?