Problem with compile PKG to exe: Babel parse has failed: 'await' is only allowed within async functions and at the top levels of modules - node.js

I wrote a script that works with puppeteer and with async/await. I specified the type as a module because it supports async/await without problems. But when compiling to exe with PKG I get an error:
pkg#5.8.0
Warning Babel parse has failed: 'await' is only allowed within async functions and at the top levels of modules. (6:8)
Warning Failed to make bytecode node16-x64 for file C:\snapshot\my-script\main.js
Tried solutions from the links:
topLevelAwait invalid with babel-loader: 'await' is only allowed within async functions
And a few more...
Basically, everyone advises using promises, but firstly, I'm new to node js and secondly, I need to do it with "crutches" in the whole script
I even tried to do it on different computers) The result is the same.
I just don't understand what I'm doing wrong. I wrote a small script for the test, it also gives this error when trying to compile..
main.js
async function Sum(x, y)
{
return x + y;
}
let x = await Sum(1, 3);
console.log(x);
package.json
{
"name": "Test",
"type": "module",
"main": "main.js",
"devDependencies": {
"#babel/plugin-syntax-top-level-await": "^7.14.5"
}
}

Related

How to use a dynamic import in a firebase cloud function using Javascript

How can I make this work without having the pre-deploy linter produce an error? If I disable the linter will it work on the cloud? (It works with my mocha tests).
async function() {
const { ChatGPTAPI } = await import('chatgpt');
}
29:32 error Parsing error: Unexpected token import
✖ 1 problem (1 error, 0 warnings)
Setting type: "module" in package.json produces error with the eslintrc.js

Unexpected reserved word 'yield' when running Jest unit tests

I'm using TypeScript and Jest to write unit tests. When I tried to run them, I got the following error messages:
Test suite failed to run
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.
SyntaxError: C:\..\my\file\name.web.spec.ts: Unexpected reserved word 'yield'.
This came from an original TypeScript section like the following:
it("should do things right", () => {
const payload = { ... };
await manager.init(payload);
});
The solution seems obvious in retrospect when looking at the code, but easy to miss. I just simply needed to make the function async.
it("should do things right", async () => {
const payload = { ... };
await manager.init(payload);
});

Cypress: Cannot use cy.task() to load dataset to Mongo before tests

I'm trying to use cy.taks() to load certain datasets to mongo before a test is run. But I'm getting errors. I've got a module where I export 2 functions, one from dropping a collection, and the other to load an object to a collection. Here is my cypress/plugins/index.js:
module.exports = (on, config) => {
on("task", {
"defaults:db": () => {
const {dropCollection, createUser } = require("../../lib/connectDB");
dropCollection("users");
createUser(userData)
},
});
};
Here is my /lib/connecDB.js:
export function dropCollection(collection) {
return mongoose.connection.dropCollection(collection);
}
export async function createUserInDB(userData) {
await User.create(userData);
}
So when I run the test, I'm getting:
cy.task('defaults:db') failed with the following error:
Unexpected token 'export'
Tried as well importing these function outside the index.js export, but getting same result.
I'd say it is something about export/import. The functions are exported as ES6, and imported as ES5.
I've tried to import the function the ES6 like:
import { dropCollection, createUser } from '../lib/connectDB'
And then export the plugin function also as ES6, but then I get:
Error: The plugins file is missing or invalid.
Your `pluginsFile` is set to `C:\Users\someRoute\cypress\plugins\index.js`, but either the file is missing, it contains a syntax error, or threw an error when required. The `pluginsFile` must be a `.js`, `.ts`, or `.coffee` file.
I've also tried to import required modules outside the function like:
const globalDbUtils = require('../lib/connectDB')
And then use the functions as
globalDbUtils.dropCollection("collectionName")
globalDbUtils.createUser(userData)
But I'm getting last error. I've tried pretty much everything, I tried to import Mongoose models straight, mongo client etc...Also I tried to import just one function and return it (just copy/pasting official doc...) but cannot make it work. I researched for a couple of days getting nothing, I found there is a npm package that helps u doing this, but since cypress allows you to do this by using no more plugins, I'd like to do it with no more tools than cypress itself.
Anyone knows what I am doing wrong?
Thanks in advance!
You need to use require instead of import at the top of your file and when exporting at the bottom use
module.exports = { createUserInDB }
Instead of exporting as you are currently doing.

How to find missing Await on Async function calls in Node+Typescript+VSCode?

We've deployed bugs in our node app b/c we forgot to prefix async function calls with "await".
Example:
const getUsers = async () => db.query('SELECT * from Users');
const testMissingAwait = async () => {
const users = getUsers(); // <<< missing await
console.log(users.length);
};
testMissingAwait();
Is there an easy way to find async function calls missing the await keyword?
Failing that, how much effort would it be to write a Visual Studio Code extension that flags these automatically? (I'm up for tackling if anyone can point me in the right direction).
TypeScript compiler doesn't provide a compiler option for that. However, TSLint 4.4 provides an option to detect floating promises. You can read this blog post for more detailed answer: Detect missing await in typescript
Download TSLint:
npm install -g tslint typescript
Configure TSLint:
{
"extends": "tslint:recommended",
"rules": {
"no-floating-promises": true
}
}
Run TSLint:
tslint --project tsconfig.json
If there are floating promises in your code, you should see the following error:
ERROR: F:/Samples/index.ts[12, 5]: Promises must be handled appropriately
TypeScript already does this
// users is a Promise<T>
const users = getUsers(); // <<< missing await
// users.length is not a property of users... then and catch are
console.log(users.length);
You can find situations where you won't be told about your mistake - where the types are compatible, for example I missed an await here:
function delay(ms: number) {
return new Promise<number>(function(resolve) {
setTimeout(() => {
resolve(5);
}, ms);
});
}
async function asyncAwait() {
let x = await delay(1000);
console.log(x);
let y = delay(1000);
console.log(y);
return 'Done';
}
asyncAwait().then((result) => console.log(result));
Because console.log doesn't cause any type incompatibility between my numbers and my promises, the compiler can't tell I have made a mistake.
The only solution here would be a type annotation... but if you're gonna forget an await, you're just as likely to forget a type annotation.
let y: number = delay(1000);
tslint is deprecated but typescript-eslint has a rule for this: no-floating-promises
This rule forbids usage of Promise-like values in statements without handling their errors appropriately ... Valid ways of handling a Promise-valued statement include awaiting, returning, and either calling .then() with two arguments or .catch() with one argument.
To use it, you'll need to set up typescript-eslint:
Install dependencies
npm install --save-dev eslint #typescript-eslint/parser #typescript-eslint/eslint-plugin
Modify your .eslintrc file
These are the minimum required settings; see the documentation for more options (https://typescript-eslint.io/docs/linting/linting):
{
"parser": "#typescript-eslint/parser",
"parserOptions": { "project": "./tsconfig.json" },
"plugins": ["#typescript-eslint"],
"rules": {
"#typescript-eslint/no-floating-promises": ["error"]
}
}
If there are places where you want to call an async function without using await, you can either:
Use the void operator as mentioned in the documentation for the rule, e.g.
void someAsyncFunction();
Or just change error to warn in the .eslintrc configuration above
Next time you run eslint you should see the rule applied:
$ npm run lint
...
./src/database/database.ts
219:7 warning Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator #typescript-eslint/no-floating-promises
Since you mentioned VS Code specifically, this also integrates great with the ESLint plugin:

Node-Webkit sharing data in node via exports

I'm experimenting with Node-Webkit lately, if I call sth like that;
exports.name = function() {
console.log('My name is Uğur');
};
Node-WebKit renderer throws a error:
"Uncaught ReferenceError: exports is not defined"
I couldn't understand, Is it caused by node-webkit or node.js itself. Since; 'node test.js'
works without problem.
You need to run this in the Node's context (not WebKit's context). To do that, specify the script in 'node-main' in the manifest.
Here is an example:
index.js:
exports.callback0 = function (win) {
}
index.html:
<body onload="process.mainModule.exports.callback0(window)">
package.json:
{
"name": "nw-demo",
"node-main": "index.js",
"main": "index.html"
}
HTH

Resources