在 Firebase 云函数中包含异步函数(eslint“解析错误:意外的令牌函数”)
Posted
技术标签:
【中文标题】在 Firebase 云函数中包含异步函数(eslint“解析错误:意外的令牌函数”)【英文标题】:Including Async Function Within Firebase Cloud Functions (eslint "Parsing error: Unexpected token function") 【发布时间】:2019-05-13 02:02:34 【问题描述】:问题
如何将async
辅助方法添加到Cloud Functions' index.js 文件中?在将 fs.writefile
转换为 Promise 时,需要 async
函数才能使用 await
,如 *** 帖子中所述: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。
Set Node.js version
"engines": "node": "8"
return await fs.writeFile(tempFile, audioContent, 'binary');
Lint 不喜欢这种解决方案。
【问题讨论】:
【参考方案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.jsonthis 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。
-
Set Node.js version
"engines": "node": "8"
使用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” ,
引用韦伯上尉和道格·史蒂文森
【讨论】:
请阅读formatting help page 以改进您的答案格式,并查看How do I write a good answer? 以改进您的答案。以上是关于在 Firebase 云函数中包含异步函数(eslint“解析错误:意外的令牌函数”)的主要内容,如果未能解决你的问题,请参考以下文章