[英]'SyntaxError: await is only valid in async function' when using top level await feature in Node v14.14.0
I'm trying to use the new top level await that was added in Node v14.8.我正在尝试使用 Node v14.8 中添加的新顶级 await。 See here and here for more info.请参阅此处和此处了解更多信息。 I've not found a question on here about issues with using this new feature, but I hope this isn't a duplicate.我没有在这里找到有关使用此新功能的问题的问题,但我希望这不是重复的。 The closest is @DanStarns answer on this question , but I have tried his solution as well (and his answer was before the 14.8 release).最接近的是@DanStarns 对这个问题的回答,但我也尝试过他的解决方案(他的回答是在 14.8 版本之前)。
I'm in the process of extracting my Axios instance from my controller into a standalone service.我正在将我的 Axios 实例从我的控制器中提取到一个独立的服务中。 In that service file, I'm attempting to instantiate and then export an Axios instance created with a stored authorization header from Spotify's API.在该服务文件中,我尝试实例化然后导出使用 Spotify API 中存储的授权标头创建的 Axios 实例。 Since this is then imported into my controller (passed into the constructor then it exports new SpotifyApiController(SpotifyApiService)
) and imports are synchronous, I am trying to use the new top level await feature to have this fully instantiated at startup/import, but getting the following error:由于然后将其导入我的控制器(传递到构造函数然后它导出new SpotifyApiController(SpotifyApiService)
)并且导入是同步的,我试图使用新的顶级 await 功能在启动/导入时完全实例化它,但得到以下错误:
[nodemon] starting `babel-node bin/www.js --harmony-top-level-await --experimental-repl-await`
E:\projects\harmonic-mixing-companion\server\services\SpotifyApiService.mjs:117
var SpotifyApiService = await createApiService();
^^^^^
SyntaxError: await is only valid in async function
at wrapSafe (internal/modules/cjs/loader.js:979:16)
at Module._compile (internal/modules/cjs/loader.js:1027:27)
at Module._compile (E:\projects\harmonic-mixing-companion\server\node_modules\pirates\lib\index.js:99:24)
at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Object.newLoader [as .mjs] (E:\projects\harmonic-mixing-companion\server\node_modules\pirates\lib\index.js:104:7)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.<anonymous> (E:\projects\harmonic-mixing-companion\server\controllers\/SpotifyApiController.js:1:1)
From the error, it looks like babel-node is transpiling my code properly since const SpotifyApiService = ...
became var SpotifyApiService = ...
.从错误来看,看起来 babel-node 正在正确地转换我的代码,因为const SpotifyApiService = ...
变成了var SpotifyApiService = ...
。 I have also added "@babel/plugin-syntax-top-level-await"
to my babel.config.json
.我还在我的babel.config.json
添加了"@babel/plugin-syntax-top-level-await"
。
The service's file extension is .mjs
.该服务的文件扩展名为.mjs
。 I have also tried setting "type": "module"
in my server's package.json too, but that was unfruitful as well.我也尝试在我的服务器的 package.json 中设置"type": "module"
,但这也没有结果。 Correct me if I'm wrong, but it also doesn't sound right to me for my whole backend server to be set as a module because it doesn't sound like a modular unit to me (versus a reusable SpotifyApiService
).如果我错了,请纠正我,但将我的整个后端服务器设置为模块对我来说也不合适,因为对我来说它听起来不像是一个模块化单元(相对于可重用的SpotifyApiService
)。
Double checked my node's version using console.log(process.version);
使用console.log(process.version);
双重检查我的节点版本console.log(process.version);
at the top of my main entry file and it printed the expected 14.14.0 version.在我的主条目文件的顶部,它打印了预期的 14.14.0 版本。
SpotifyApiController.js
Snippet: SpotifyApiController.js
片段:
import SpotifyApiService from '../services/SpotifyApiService.mjs';
import handleHttpError from '../handlers/handleHttpError';
class SpotifyApiController {
constructor(spotifyApiService) {
this.spotifyApi = spotifyApiService;
}
...
}
SpotifyApiService.mjs
Snippet: SpotifyApiService.mjs
片段:
...
const createApiService = async () => {
const accessToken = await authorizeApp();
console.log(accessToken);
const authHeader = { Authorization: `Bearer ${accessToken}` };
const axiosInstance = axios.create({
baseURL: 'https://api.spotify.com/v1',
headers: authHeader,
});
createAuthRefreshInterceptor(axiosInstance, authorizeApp);
return axiosInstance;
};
const SpotifyApiService = await createApiService();
export default SpotifyApiService;
package.json
Dependencies: package.json
依赖项:
"devDependencies": {
"@babel/cli": "~7.12.1",
"@babel/core": "~7.12.1",
"@babel/eslint-parser": "~7.12.1",
"@babel/node": "~7.12.1",
"@babel/plugin-proposal-class-properties": "~7.12.1",
"@babel/plugin-syntax-top-level-await": "~7.12.1",
"@babel/plugin-transform-arrow-functions": "~7.12.1",
"@babel/plugin-transform-runtime": "~7.12.1",
"@babel/preset-env": "~7.12.1",
"@babel/preset-react": "~7.12.1",
"babel-loader": "~8.1.0",
"nodemon": "~2.0.5"
},
"dependencies": {
"axios": "~0.20.0",
"axios-auth-refresh": "~3.0.0",
"cookie-parser": "~1.4.5",
"cors": "~2.8.5",
"debug": "~4.2.0",
"dotenv": "~8.2.0",
"express": "~4.17.1",
"querystring": "~0.2.0"
}
Server is started with the following npm script: "dev-server": "nodemon --exec babel-node bin/www.js --ignore dist/"
服务器使用以下 npm 脚本启动: "dev-server": "nodemon --exec babel-node bin/www.js --ignore dist/"
You can wrap it in async function:您可以将其包装在 async 函数中:
var SpotifyApiService = (async()=> await createApiService())();
After you can use than, catch在你可以使用than 之后,catch
As the documentation indicates, babel only enables the "syntax" for this feature,正如文档所示,babel 只为这个特性启用“语法”,
Syntax only仅语法
This plugin only enables parsing of this feature.此插件仅启用此功能的解析。 Babel doesn't support transforming top-level await , but you can use Rollup's experimentalTopLevelAwait or webpack@5's experiments.topLevelAwait options. Babel 不支持转换顶级 await ,但您可以使用 Rollup 的 ExperimentalTopLevelAwait 或 webpack@5 的 Experiments.topLevelAwait 选项。
which just means that babel won't complain when compiling your code but it doesn't actually implement the steps that will actively transform a line such as var SpotifyApiService = await createApiService();
这只是意味着 babel 在编译你的代码时不会抱怨,但它实际上并没有实现会主动转换一行的步骤,比如var SpotifyApiService = await createApiService();
into valid ES5.进入有效的 ES5。
So anything executing your code ( browser, node ) will complain since they don't know how to handle this feature.因此,执行您的代码(浏览器、节点)的任何内容都会抱怨,因为他们不知道如何处理此功能。
The catch is that top level await is only supported in ES modules.问题是顶级 await 仅在 ES 模块中受支持。 In other words, you either have to add "type": "module"
to your package.json or rename your .js
file to .mjs
.换句话说,您要么必须将"type": "module"
到您的 package.json 或将您的.js
文件重命名为.mjs
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.