繁体   English   中英

包括异步 Function Firebase Cloud Functions 内(eslint“解析错误:意外的令牌函数”)

[英]Including Async Function Within Firebase Cloud Functions (eslint "Parsing error: Unexpected token function")

问题

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

错误

84行引用 helper function async function writeFile

Users/adamhurwitz/coinverse/coinverse-cloud-functions/functions/index.js 84:7 错误解析错误:意外令牌 function

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

npm 错误! 代码生命周期

npm 错误! 错误号 1

npm 错误:函数@lint: eslint.

npm 错误! 退出状态 1

npm 错误!

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

npm 错误。 这可能不是 npm 的问题。上面可能有其他日志记录 output。

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

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

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

设置

索引.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');
}

尝试的解决方案

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

  1. 设置 Node.js 版本"engines": {"node": "8"}

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

Lint 不喜欢这种解决方案。

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

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

变成 :

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

就像评论中的 Burak 所说的那样,当我们创建 firebase 函数时,默认情况下会放置这个点

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

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

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

  "ecmaVersion": 2017

ISSUE ES7 你必须把它改成 ES8

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

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

如果文件是 .eslintrc.json

"ecmaVersion": 2017 或 "ecmaVersion": 8

如果文件是 .eslintrc.js

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

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

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

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

变成 :

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

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

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

  • .eslintrc.js
  • .eslintrc.json

这是 eslintrc.json

这是 eslintrc.json

正如你所看到的,在两个同名文件中有不同版本的 ecmaScript,

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

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

Node.js 8 - 承诺

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

  1. 设置 Node.js 版本"engines": {"node": "8"}
  2. 使用promisify

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

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

Node.js 8 之前 - 手动转换

这是一种将回调转换为承诺的较旧方法,如this answer关于Google Text To Speech ( 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');

更改 .eslintrc.json 中的 ecmaVersion

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

.eslint.json

"parserOptions": { // 某些语法用法需要 "ecmaVersion": 6 }, 像这样改变它以帮助它理解 async/await:

“ecmaVersion”:2017

package.json "scripts": { "lint": "eslint ." }, 变成 :

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

裁判队长韦伯和道格史蒂文森

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

例如:

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

变成:

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

ESLint 语言选项文档中的更多详细信息。

我遇到了同样的问题。
我使用了与 Firebase 函数样本 GitHub 存储库中的一个函数相同的 ESLint 配置。 我在这里提到了这个特定的例子: https://github.com/firebase/functions-samples/tree/main/child-count ,它使用了异步函数。
我删除了eslintrc.js并将其替换为与上述示例中相同的eslintrc.json文件。 此外,在package.json中,添加了一个新的依赖"eslint-plugin-promise": "^4.3.1" ,并删除了默认的"eslint-config-google": "^0.14.0" (同样,如上所示样本)。

这似乎已经为我解决了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM