【问题标题】:Including Async Function Within Firebase Cloud Functions (eslint "Parsing error: Unexpected token function")在 Firebase 云函数中包含异步函数(eslint“解析错误:意外的令牌函数”)
【发布时间】:2019-05-13 02:02:34
【问题描述】:

问题

如何将async 辅助方法添加到Cloud Functions' index.js 文件中?在将 fs.writefile 转换为 Promise 时,需要 async 函数才能使用 await,如 StackOverflow 帖子中所述:fs.writeFile in a promise, asynchronous-synchronous stuff。但是,lint 不赞成在 index.js 文件中添加 exports 函数之外的其他方法。

错误

84行引用了辅助函数async function writeFile

用户/adamhurwitz/coinverse/coinverse-cloud-functions/functions/index.js 84:7 错误解析错误:意外的令牌函数

✖ 1 个问题(1 个错误,0 个警告)

npm 错误!代码生命周期

npm 错误!错误号 1

npm 错误!函数@ lint:eslint .

npm 错误!退出状态 1

npm 错误!

npm 错误! functions@lint 脚本失败。

npm 错误!这可能不是 npm 的问题。上面可能还有额外的日志输出。

npm 错误!可以在以下位置找到此运行的完整日志:

npm 错误! /Users/adamhurwitz/.npm/_logs/2018-12-12T01_47_50_684Z-debug.log

错误:函数预部署错误:命令以非零退出代码终止

设置

index.js

const path = require('path');
const os = require('os');
const fs = require('fs');
const fsPromises = require('fs').promises;
const util = require('util');
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const {Storage} = require('@google-cloud/storage');
const textToSpeech = require('@google-cloud/text-to-speech');

const storage = new Storage({
  projectId: 'project-id',
});
const client = new textToSpeech.TextToSpeechClient();

admin.initializeApp();

exports.getAudiocast = functions.https.onCall((data, context) => {
  const bucket = storage.bucket('gs://[bucket-name].appspot.com');
  var fileName;
  var tempFile;
  var filePath;

  return client.synthesizeSpeech({
    input: {text: data.text },
    voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
    audioConfig: {audioEncoding: 'MP3'},
  })
  .then(responses => {
    var response = responses[0]; 
    fileName = data.id + '.mp3'
    tempFile = path.join(os.tmpdir(), fileName);  
    return writeFile(tempFile, response.audioContent)
  })
  .catch(err => {
    console.error("Synthesize Speech Error: " + err);
  })
  .then(() => {
     filePath = "filePath/" + fileName;
     return bucket.upload(tempFile, { destination: filePath })
  })
  .catch(err => {
     console.error("Write Temporary Audio File Error: " + err);
  })
  .then(() => {
   return { filePath: filePath }
  })
  .catch(err => {
     console.error('Upload Audio to GCS ERROR: ' + err);
  });
});

辅助方法:

async function writeFile(tempFile, audioContent) {
    await fs.writeFile(tempFile, audioContent, 'binary');
}

尝试的解决方案

按照Cloud Functions for Firebase Async Await style 帖子中的建议启用 Node.js 8

  1. Set Node.js version "engines": {"node": "8"}

  2. return await fs.writeFile(tempFile, audioContent, 'binary');

Lint 不喜欢这种解决方案。

【问题讨论】:

    标签: javascript node.js firebase google-cloud-functions firebase-cli


    【解决方案1】:

    我尝试了上述所有对我不起作用的解决方案。这是由于我的 package.json 中的语法错误:

    "scripts": {
        "lint": "eslint ."
      },
    

    改为:

    "scripts": {
        "lint": "eslint"
      },
    

    就像在 cmets 中说的 Burak 一样,这个点在我们创建 firebase 函数时默认放置

    【讨论】:

    • 我不确定这是否能解决问题。根据我的经验,它使 eslint 对错误的目标目录起作用。尝试有不好的缩进,它不会被标记了
    • 对此要小心。也许我错过了一些东西,但对我来说,这个“修复”完全关闭了 lint 警告。
    • 这不是一个修复它不会让 eslint “工作”——它让 eslint 实际上不会扫描你的代码。如果你打算这样做,你也可以删除整个 lint 脚本。
    【解决方案2】:

    您的 eslint 未配置为理解 ECMAScript 2017 语法。 Fireabse CLI 默认创建的 .eslint.json 配置文件包含以下配置:

    "parserOptions": {
      // Required for certain syntax usages
      "ecmaVersion": 6
    },
    

    像这样改变它以帮助它理解 async/await:

      "ecmaVersion": 2017
    

    【讨论】:

    • 我已将"ecmaVersion": 2017 添加到项目的 eslintrc.json 文件中,但是 Lint 在返回承诺时仍然抛出错误从await生成:return await fs.writeFile(tempFile, responses[0].audioContent, 'binary');
    • 这听起来像是一个不同的问题。
    • 唯一的区别是将promisify替换为await。否则,writeFile 方法在使用 promisify 时会按预期工作,因此我可以继续使用该方法。
    • 没错,最新版本在 env 部分采用es2017: true 格式
    【解决方案3】:

    ISSUE ES7 你必须把它改成 ES8

    • 2016 年发布的 ES7 没有 async、await 和箭头函数
    • 2017 年发布的 ES8 具有异步、等待和箭头功能

    你必须检查你的 .eslintrc 你至少有 es8 或 2017 这是相同的。

    如果文件是 .eslintrc.json

    “ecmaVersion”:2017 要么 “ecmaVersion”:8

    如果文件是 .eslintrc.js

    环境:{ es8:真的, 节点:真 }

    对于某些人来说,它是这样工作的

    在我的情况下,它通过更改 package.json 解决了

    "scripts": { "lint": "eslint." },

    改为:

    “脚本”:{“lint”:“eslint”},

    正如乔纳森所说,但我想知道为什么?

    a 意识到我有两个同名的文件

    • .eslintrc.js
    • .eslintrc.json

    this is eslintrc.json

    this is eslintrc.json

    如您所见,两个同名文件中存在不同版本的 ecmaScript,

    • "ecmaVersion": 2017 // 等于文件中的es8:.eslintrc.json
    • es6: true, // 于 2015 年 6 月在文件中发布:.eslintrc.js

    所以当我们运行时: npm run lint 它运行 .eslintrc.js 并带有 es6:true 所以解决这个冲突只是删除.eslintrc.js,因为它有错误的ecmaScript。

    【讨论】:

      【解决方案4】:

      如果您有 .eslint.js - 只需将 es6: true 更改为 es2017: true

      例如:

        env: {
          es6: true,
          node: true,
        },
      

      变成:

        env: {
          es2017: true,
          node: true,
        },
      

      更多详情请见ESLint language options doc

      【讨论】:

        【解决方案5】:

        Node.js 8 - 承诺

        按照Cloud Functions for Firebase Async Await style 帖子中的建议启用 Node.js 8

        1. Set Node.js version "engines": {"node": "8"}
        2. 使用promisify

          const writeFile = util.promisify(fs.writeFile);

          return writeFile(tempFile, response.audioContent, 'binary')

        Pre Node.js 8 - 手动转换

        这是answer 所概述的将回调转换为承诺的旧方法,涉及有关 Google 文本转语音 (TTS) 的更具体问题。

        const writeFilePromise = (file, data, option) => {
           return new Promise((resolve, reject) => {
               fs.writeFile(file, data, option, error => {
                  if (error) reject(error);
                  resolve("File created! Time for the next step!");
               });
           });
        };
        
        return writeFilePromise(tempFile, response.audioContent, 'binary');
        

        【讨论】:

        • "engines": {"node": "8"} 对我来说是关键,非常感谢
        【解决方案6】:

        更改 .eslintrc.json 中的 ecmaVersion

        “解析器选项”:{
        // 某些语法用法需要
        “ecmaVersion”:8
        }

        【讨论】:

          【解决方案7】:

          .eslint.json

          “解析器选项”:{ // 某些语法用法需要 “ecmaVersion”:6 }, 像这样改变它以帮助它理解 async/await:

          “ecmaVersion”:2017

          package.json “脚本”:{ “lint”:“eslint”。 }, 改为:

          “脚本”:{ “lint”:“eslint” },

          引用韦伯上尉和道格·史蒂文森

          【讨论】:

          猜你喜欢
          • 2021-07-08
          • 2018-10-21
          • 1970-01-01
          • 2020-01-13
          • 1970-01-01
          • 2017-12-29
          • 2019-12-25
          • 1970-01-01
          • 2022-01-02
          相关资源
          最近更新 更多