在 Firebase Cloud Functions 中包含异步函数 (eslint "Parsing error: Unexpected token function" )



问题

如何将async辅助方法添加到Cloud Functions的index.js文件中?在将fs.writefile转换为Promise时,需要async函数才能使用await,如StackOverflow文章中所述:fs.writeFile中的Promise异步同步内容。但是,lint不赞成在index.js文件中添加exports函数之外的其他方法。

错误

84指的是辅助函数async function writeFile

Users/adamhurwitz/converse/converse云函数/functions/index.js84:7错误分析错误:意外的令牌函数

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

npm ERR!代码ELIFECYCLE

npm ERR!错误1

npm ERR!函数@lint:eslint .

npm ERR!退出状态1

npm ERR!

npm ERR!函数@lint脚本失败。

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

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

npm ERR/用户/adamhurwitz/.npm/_logs/2018-12-12T01_47_50_684Z-debug.log

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

设置

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

尝试的解决方案

启用Node.js8,如Firebase Async Await样式的后云函数中所建议的。

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

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

Lint不喜欢这种解决方案。

我尝试了上面所有的解决方案,但都不适用。这是由于我的包.json:中的语法不好

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

更改为:

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

就像Burak在评论中所说的那样,当我们创建firebase函数时,这个点是默认的

您的esint未配置为理解ECMAScript 2017语法。默认情况下,由Fire缺席CLI创建的.eslint.json配置文件包括以下配置:

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

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

"ecmaVersion": 2017

发布ES7您必须将其更改为ES8

2016年发布的ES7没有异步、等待或箭头功能
  • 2017年发布的ES8具有异步、等待和箭头功能
  • 您必须在.eslintrc上检查您是否至少有es8或2017,这是相同的。

    如果文件是.eslintrc.json

    "ecmaVersion":2017或"ecmaVersion":8

    如果文件是.eslintrc.js

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

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

    在我的案例中,它通过更改package.json来解决

    "脚本":{"lint":"eslint"},

    更改为:

    "脚本":{"lint":"eslint"},

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

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

    • .eslintrc.js
    • .eslintrc.json

    这是eslintrc.json

    这是eslintrc.json

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

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

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

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

    例如:

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

    变为:

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

    更多详细信息,请参阅ESLint语言选项文档。

    Node.js 8-Promisify

    启用Node.js8,如Firebase Async Await样式的后云函数中所建议的。

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

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

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

    Pre-Node.js 8-手动转换

    这是一种将回调转换为承诺的旧方法,如本答案所述,该答案涉及有关谷歌文本到语音(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

    "parserOptions":{
    //某些语法用法需要
    "ecmaVersion":8

    我遇到了同样的问题
    我使用了与Firebase函数示例GitHub repo中的一个函数相同的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"(同样,与上面的示例一样)。

    这似乎为我解决了问题。

    .eslint.json

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

    "ecmaVersion":2017年

    package.json"脚本":{"lint":"eslint"},更改为:

    "脚本":{"lint":"eslint";},

    裁判Web队长和Doug Stevenson

    相关内容

    最新更新