Including Async Function Within Firebase Cloud Functions (eslint "Parsing error: Unexpected token function")
Including Async Function Within Firebase Cloud Functions (eslint "Parsing error: Unexpected token function")
问题
如何将 async
辅助方法添加到 Cloud Functions 的 index.js 文件中?在将 fs.writefile
转换为 Promise 时,需要一个 async
函数才能使用 await
,如本 Whosebug post 中所述:fs.writeFile in a promise, asynchronous-synchronous stuff。但是,lint 不赞成在 exports
函数之外向 index.js 文件添加额外的方法。
错误
行84指的是辅助函数async function writeFile
.
Users/adamhurwitz/coinverse/coinverse-cloud-functions/functions/index.js
84:7 error Parsing error: Unexpected token function
✖ 1 problem (1 error, 0 warnings)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! functions@ lint: eslint .
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the functions@ lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/adamhurwitz/.npm/_logs/2018-12-12T01_47_50_684Z-debug.log
Error: functions predeploy error: Command terminated with non-zero exit code1
设置
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');
}
尝试的解决方案
按照 post .
中的建议启用 Node.js 8
Set Node.js version
"engines": {"node": "8"}
return await fs.writeFile(tempFile, audioContent, 'binary');
Lint 不喜欢这个解决方案。
Node.js 8 - 承诺
按照 post .
中的建议启用 Node.js 8
- Set Node.js version
"engines": {"node": "8"}
使用promisify
const writeFile = util.promisify(fs.writeFile);
return writeFile(tempFile, response.audioContent, 'binary')
前 Node.js 8 - 手动转换
这是一种将回调转换为 Promises 的旧方法,如此 所概述的关于 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');
您的 eslint 未配置为理解 ECMAScript 2017 语法。 .eslint.json 默认情况下由 Fireabse CLI 创建的配置文件包含此配置:
"parserOptions": {
// Required for certain syntax usages
"ecmaVersion": 6
},
改成这样帮助它理解async/await:
"ecmaVersion": 2017
更改 .eslintrc.json 中的 ecmaVersion
"parserOptions": {
// Required for certain syntax usages
"ecmaVersion": 8
}
我尝试了上面所有的解决方案,但都不适合我。这是由于我的语法错误 package.json :
"scripts": {
"lint": "eslint ."
},
更改为:
"scripts": {
"lint": "eslint"
},
就像 Burak 在评论中所说的那样,这个点是我们创建 firebase 函数时默认放置的
.eslint.json
“解析器选项”:{
// 对于某些语法用法是必需的
“ecma版本”:6
},
像这样更改它以帮助它理解 async/await:
“ecma版本”:2017
package.json
“脚本”:{
“lint”:“eslint。”
},
更改为:
“脚本”:{
“lint”:“eslint”
},
裁判 Web 队长和 Doug Stevenson
问题 ES7 您必须将其更改为 ES8
- 2016 年发布的 ES7 没有 async,await 和箭头函数
- 2017年发布的ES8有async,await和arrow函数
你必须检查你的 .eslintrc 你至少有 es8 或 2017,这是相同的。
如果文件是 .eslintrc.json
“ecma版本”:2017
要么
“ecma版本”:8
如果文件是 .eslintrc.js
环境:{
es8:true,
node:true
}
对于某些人来说它是这样工作的
在我的例子中,它通过更改 package.json
解决了
“脚本”:{“lint”:“eslint。” },
更改为:
“脚本”:{“lint”:“eslint”},
正如乔纳森所说,但我想知道为什么?
然后我意识到我有两个名为
的文件
- .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 运行 lint 它 运行s .eslintrc.js with es6:true
所以解决这个冲突只是 delete .eslintrc.js 因为它有错误的 ecmaScript.
如果您有 .eslint.js
- 只需将 es6: true
更改为 es2017: true
。
例如:
env: {
es6: true,
node: true,
},
变为:
env: {
es2017: true,
node: true,
},
ESLint language options doc 中有更多详细信息。
问题
如何将 async
辅助方法添加到 Cloud Functions 的 index.js 文件中?在将 fs.writefile
转换为 Promise 时,需要一个 async
函数才能使用 await
,如本 Whosebug post 中所述:fs.writeFile in a promise, asynchronous-synchronous stuff。但是,lint 不赞成在 exports
函数之外向 index.js 文件添加额外的方法。
错误
行84指的是辅助函数async function writeFile
.
Users/adamhurwitz/coinverse/coinverse-cloud-functions/functions/index.js 84:7 error Parsing error: Unexpected token function
✖ 1 problem (1 error, 0 warnings)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! functions@ lint:
eslint .
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the functions@ lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/adamhurwitz/.npm/_logs/2018-12-12T01_47_50_684Z-debug.log
Error: functions predeploy error: Command terminated with non-zero exit code1
设置
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');
}
尝试的解决方案
按照 post
Set Node.js version
"engines": {"node": "8"}
return await fs.writeFile(tempFile, audioContent, 'binary');
Lint 不喜欢这个解决方案。
Node.js 8 - 承诺
按照 post
- Set Node.js version
"engines": {"node": "8"}
使用
promisify
const writeFile = util.promisify(fs.writeFile);
return writeFile(tempFile, response.audioContent, 'binary')
前 Node.js 8 - 手动转换
这是一种将回调转换为 Promises 的旧方法,如此
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');
您的 eslint 未配置为理解 ECMAScript 2017 语法。 .eslint.json 默认情况下由 Fireabse CLI 创建的配置文件包含此配置:
"parserOptions": {
// Required for certain syntax usages
"ecmaVersion": 6
},
改成这样帮助它理解async/await:
"ecmaVersion": 2017
更改 .eslintrc.json 中的 ecmaVersion
"parserOptions": {
// Required for certain syntax usages
"ecmaVersion": 8
}
我尝试了上面所有的解决方案,但都不适合我。这是由于我的语法错误 package.json :
"scripts": {
"lint": "eslint ."
},
更改为:
"scripts": {
"lint": "eslint"
},
就像 Burak 在评论中所说的那样,这个点是我们创建 firebase 函数时默认放置的
.eslint.json
“解析器选项”:{ // 对于某些语法用法是必需的 “ecma版本”:6 }, 像这样更改它以帮助它理解 async/await:
“ecma版本”:2017
package.json “脚本”:{ “lint”:“eslint。” }, 更改为:
“脚本”:{ “lint”:“eslint” },
裁判 Web 队长和 Doug Stevenson
问题 ES7 您必须将其更改为 ES8
- 2016 年发布的 ES7 没有 async,await 和箭头函数
- 2017年发布的ES8有async,await和arrow函数
你必须检查你的 .eslintrc 你至少有 es8 或 2017,这是相同的。
如果文件是 .eslintrc.json
“ecma版本”:2017 要么 “ecma版本”:8
如果文件是 .eslintrc.js
环境:{ es8:true, node:true }
对于某些人来说它是这样工作的
在我的例子中,它通过更改 package.json
解决了“脚本”:{“lint”:“eslint。” },
更改为:
“脚本”:{“lint”:“eslint”},
正如乔纳森所说,但我想知道为什么?
然后我意识到我有两个名为
的文件- .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 运行 lint 它 运行s .eslintrc.js with es6:true 所以解决这个冲突只是 delete .eslintrc.js 因为它有错误的 ecmaScript.
如果您有 .eslint.js
- 只需将 es6: true
更改为 es2017: true
。
例如:
env: {
es6: true,
node: true,
},
变为:
env: {
es2017: true,
node: true,
},
ESLint language options doc 中有更多详细信息。