I am learning node.js and need to use readline for a project. I have the following code directly from the readline module example.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What do you think of Node.js? ', (answer) => {
// TODO: Log the answer in a database
console.log('Thank you for your valuable feedback:', answer);
rl.close();
});
But when I run the code via
node try.js command, it keeps giving out the errors like below:
rl.question('What is your favorite food?', (answer) => {
^^
SyntaxError: Unexpected token =>
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Arrow functions, one of the new features of the ECMAScript 6 standard, were introduced to node.js (as stable feature) only in version 4.0.0.
You can either upgrade your node.js version or use the old syntax, which would look like this:
rl.question('What do you think of Node.js? ', function(answer) {
// TODO: Log the answer in a database
console.log('Thank you for your valuable feedback:', answer);
rl.close();
});
(Note that there is one more difference between those syntaxes: The this variable behaves differently. It doesn't matter for this example, but it may in others.)
Upgrade your node version.
Arrow functions now work in node (version 4.0.0) see here: ECMAScript 2015 (ES6) in Node.js
Check to see which version you are running with node -v
You likely need to upgrade check out the compatibility table here to see what else is available:
Node Compatibility Table
For people who already upgraded node and are running into the same error: For me, this error was coming from eslint. I was using node 14 in my package.json:
"engines": {
"node": "14"
},
But only got rid of the error after updating the linter .eslintrc.js config to the following:
"parserOptions": {
"ecmaVersion": 8,
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true,
},
"sourceType": "module",
},
The => syntax, known as an Arrow Function, is a relatively new feature of JavaScript. You'll need a similarly new version of Node to take advantage of it.
Change your "es" version from 6 to 7.
For this go to your functions**>**.eslintrc.js file.
Change "es6:true" to "es7:true".
Actually, "=>" is an element of es7 and therefore throws error on es6.
Related
I am trying to run some simple commands using child_process.exec. But in some odd corner cases, it tries to execute the given command with node, rather than the given (or default) shell.
Results
E.g., given below code, I get the following results:
cmd
Result
❌
'"yarn" -v'
Cannot find module 'C:\cwd\yarn.js'
❌
'"npm" -v'
Cannot find module 'C:\cwd\node_modules\npm\bin\npm-cli.js'
✅
'yarn -v'
(works as expected)
✅
'"C:\path\to\yarn" -v'
(works as expected)
OS: Win10
Node: v16., v17. (tried several of them)
EDIT: This seems to be a cmd-specific problem. If I set processOptions.shell = 'bash', it does not occur.
Full Error Message
node:internal/modules/cjs/loader:936
throw err;
^
Error: Cannot find module 'C:\cwd\yarn.js'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Done - code 1 signal null
Thoughts
It appears that there is a special logic that is triggered, iff the "executable" is in double quotes, and has no spaces or path separators in them...?
Not sure if feature or bug?
Code
// test.js
const cp = require('child_process');
const cmd = '"yarn" install';
const child = cp.exec(cmd);
// ###########################################################################
// process monitoring
// ###########################################################################
child.on('exit', (code, signal) => {
console.log('Done - code', code, ' signal', signal);
});
child.on('error', (err) => {
console.error(`Error:`, err);
});
// inherit stdio
child.stdout.pipe(process.stdout);
process.stdin.pipe(child.stdin);
child.stderr.pipe(process.stderr);
Turns out, it is a volta bug. I filed it here.
Easy to verify: Change the command to do other things on top of "yarn" install. The following still shows hi, but the yarn part still bugs out, so it is definitely not an issue with node or cmd:
const cmd = 'echo "hi" && "yarn" install';
const child = cp.exec(cmd);
Some more explanation: volta manages node, npm and yarn for you, making it very easy to install/uninstall/pin versions globally or even per folder/project. That means that "yarn" install does not actually run yarn, but actually this:
Runs a volta executable
Which will then run yarn...
...which evidently messed up the logic to look up the actual executable.
This happens only with yarn and npm. Everything else (thus far) seems fine, including node itself.
/home/discord/project/bloodmoon/node_modules/discord.js/src/client/Client.js:42
} catch {
^
SyntaxError: Unexpected token {
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:616:28)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/home/discord/project/bloodmoon/node_modules/discord.js/src/index.js:8:11)
i'm interested in developing discord bot. so i tried it. first, it works.
but, i moved the server and i setted it. and it not works! please give advise to me.
(please understand i can't write a English essay well. sorry)
If you check the discord.js source code, you can see that they're trying to silently ignore if there is an error when their code requires the worker_threads module. They simply omit the usual (error) part after catch:
try {
// Test if worker threads module is present and used
data = require('worker_threads').workerData || data;
} catch {
// Do nothing
}
However, it only works in newer versions of JavaScript and older ones will throw a SyntaxError. So, you must be using an older version of Node, because optional catch binding is only available in Node.js v10+.
The following is an example in Node v8:
// using Node v8
try { error } catch { console.log('oops') }
⬇⬇ result ⬇⬇
try { error } catch { console.log('oops') }
^
SyntaxError: Unexpected token {
While it just works fine in Node v10+:
// using Node v16
try { error } catch { console.log('oops') }
⬇⬇ result ⬇⬇
oops
To solve this, you need to update your Node version to at least v12, as mentioned in the discord.js docs:
v12 requires Node 12.x or higher, so make sure you're up-to-date. To
check your Node version, use node -v in your terminal or command
prompt, and if it's not high enough, update it! There are many
resources online to help you with this step based on your host system.
I updated my firebase-functions and now I get this error in the Firebase console. The code is still the same, but I get an error now:
/srv/node_modules/#google-cloud/firestore/build/src/collection-group.js:54
async *getPartitions(desiredPartitionCount) {
^
SyntaxError: Unexpected token *
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:617:28)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/srv/node_modules/#google-cloud/firestore/build/src/index.js:39:28)
This is my cloud function TypeScript source:
import * as functions from 'firebase-functions';
import admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
/********************************************************************/
exports.newChatMessage = functions.firestore
.document('/games/{gameId}/chat/{chatId}')
.onCreate((snap, context) => {
const createData = snap.data();
if(!createData) {
return false;
}
const chatMessage = createData.message;
if(!chatMessage) {
return false;
}
console.log('New Chat message in game: ', context.params.gameId);
const payload = {
notification: {
title: 'New chat message',
body: chatMessage,
icon: 'ic_notification'
}
}
return admin.firestore().collection(`/games/${context.params.gameId}/members`).where( 'notificationChat', '==', true ).get().then( members => {
members.forEach( member => {
if(member.id !== createData.user) {
return admin.firestore().doc(`/users/${member.id}`).get().then( memberdata => {
if( memberdata.get('firebaseToken') === '' ) {
return memberdata.data();
} else {
return admin.messaging().sendToDevice(memberdata.get('firebaseToken'), payload).catch( error => { console.log(error) });
}
}).catch( error => { console.log(error) });
} else {
return false;
}
})
}).catch( error => { console.log(error) });
});
What is this? In my functions there isn't any method named *getPartitions.
Downgrade firebase-admin and firebase-functions to version: "firebase-admin": "^8.10.0", "firebase-functions": "^3.6.1" and it will work.
Thanks to Marcel Hoekstra for posting this in the comments.
As Uzbekjon stated, you can get this error if running node v8 instead of v10. Some comments mentioned this was not the desired solution, because they didn't want to upgrade to Firebase's Blaze plan. Unfortunately, there's not going to be much of a choice in the matter soon.
If you go to your Firebase Functions in the console, you'll notice a warning that "Node V8 has been deprecated". As of Feb 15 2021 you will no longer be able to make changes to or deploy any functions using Node.js V8. As of March 15, 2021 you will no longer be able to use the functions at all. They will be completely blocked from execution.
Blog post Migrate your Firebase Cloud Functions to Node.js 10 was really good for explaining how to upgrade to v10. I follow the author's steps and redeployed - no error and no deprecation warning.
Required Updates
Check to make sure you have at least Node.js V10 installed globally on your machine node --version.
npm install -g firebase-tools#latest (you need at least version 8.1.0)
In your package.json file, make sure Node.js V10 is targeted like this:
"engines": {
"node": "10"
}
Check your Firebase environment variables. The source I linked to goes into further detail and links other explanation sources, but basically upgrading might mean default environment variable names have changed (I didn't have to change anything here).
Recommended
Make sure firebase-functions is at least version 3.7.0. I had to update this anyway to solve another error.
Optional, but still recommended
Update your compiler options in tsconfig.json. This will make it so unnecessary language versions are not transpiled.
"compilerOptions": {
"target": "es2018",
"lib": ["es2018"],
}
Test your code :)
Like I mentioned earlier, making this upgrade removed the error for me. Once I made a new deployment, all deprecation warnings were also removed from the Firebase Functions console.
You can also get this error if you are running Node.js v8. Upgrading to Node.js v10 resolves this error.
If you are managing your Node.js version using nvm, then run:
nvm install v10 --lts
I think it is a better solution than downgrading the firebase-admin library.
I'm trying to connect to a Gremlin server with the JavaScript driver variant.
Up to package version 2.7.0, this is done easily by passing options to Gremlin.createClient() as in this example for Azure Cosmos DB:
const client = Gremlin.createClient(
config.port,
config.endpoint,
{
"session": false,
"ssl": true,
"user": `/dbs/${config.database}/colls/${config.collection}`,
"password": config.primaryKey
}
);
In newer versions of the package I can't get it done. The official docs suggest using gremlin.driver.auth.PlainTextSaslAuthenticator. However, that method seems to be not implemented in the package and returns TypeError: Cannot read property 'PlainTextSaslAuthenticator' of undefined
My test code (same config.js as in the working example):
const gremlin = require("gremlin");
const config = require("./config");
const Graph = gremlin.structure.Graph;
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const graph = new Graph();
const authenticator = new gremlin.driver.auth.PlainTextSaslAuthenticator(
`/dbs/${config.database}/colls/${config.collection}`,
config.primaryKey
);
const g = graph.traversal().withRemote(new DriverRemoteConnection(`ws://${config.endpoint}:${config.port}`, { authenticator });
Return:
C:\repos\gremlin-test\index.js:9
const authenticator = new gremlin.driver.auth.PlainTextSaslAuthenticator(
^
TypeError: Cannot read property 'PlainTextSaslAuthenticator' of undefined
at Object.<anonymous> (C:\repos\gremlin-test\index.js:9:47)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
Anyone know a solution to this?
I've not got too much experience with Gremlin.js, but I just downloaded it and have manually searched through all of its files - I can't find any trace of a PlainTextSaslAuthenticator function or its declaration.
This could mean one of two three -
Its function has been (accidentally) removed
It uses a third party package that has been (accidentally) removed
It has not been added to the package yet
Upon a swift Google search, I found this link which seems to show it being added to /lib/driver/auth, but that directory doesn't seem to exist in the package I got through npm install gremlin. Perhaps it is yet to be released?
I would therefore suggest you raise an issue on Github, but it seems that repository you linked doesn't allow for issues to be raised. So perhaps email/contact the author?
EDIT:
Thanks to Stephen for the link - the code hasn't been merged to the package yet. Keep track of it here.
I have been given an automation framework in CucumberJS and node with selenium. But it has an older version of cucumber which relies on promises. In an attempt to avail latest synchronous step feature, I decided to upgrade the cucumberJS version (1.3.3 to 4.2.1)
Now the problem is the code that was used to invoke cucumber cli programmatically in index.js isnt working anymore. I made all the other changes in step definitions and world.js, but I am not able to figure out how do I run this thing via node, something like
node index.js --tags #SampleFeature
This used to work before with the older version but not anymore.
Code that was working before -
// execute cucumber
let cucumberCli = Cucumber.Cli(process.argv);
cucumberCli.run(succeeded => {
var code = succeeded ? 0 : 1;
function exitNow() {
process.exit(code);
}
if (process.stdout.write('')) {
exitNow();
} else {
process.stdout.on('drain', exitNow);
}
});
Now it throws the error like this after version update
/Users/../node_modules/babel-runtime/helpers/classCallCheck.js:7
throw new TypeError("Cannot call a class as a function");
^
TypeError: Cannot call a class as a function
at exports.default (/Users/../node_modules/babel-runtime/helpers/classCallCheck.js:7:11)
at Object.Cli (/Users/../node_modules/cucumber/lib/cli/index.js:78:34)
at Object.<anonymous> (/Users/../index.js:90:10)
at Module._compile (internal/modules/cjs/loader.js:678:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
at Module.load (internal/modules/cjs/loader.js:589:32)
at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
at Function.Module._load (internal/modules/cjs/loader.js:520:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)
at startup (internal/bootstrap/node.js:228:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)
I googled a lot but did not find an alternative. Tried multiple things as calling Cli as class with new keyword, didn't work. Tried removing it and running via plain cucumber cli runner, didn't work.
PS. I come from a Cucumber with Java background where things were simpler :)
You need to create a new CLI object, then use it's .run method:
let runArgs = ['The cucumber args array here'];
let cliArgs = {argv : runArgs, cwd: process.cwd(), stdout: process.stdout};
let cli = (new require('cucumber').Cli)(cliArgs);
cli.run(); //Returns a promise
For reference I've employed the same approach with Typescript and cucumber 7.3.2
import { Cli } from '#cucumber/cucumber';
const runArgs = ['-p', argv['profile'], '--tags', argv['tags'], '--fail-fast'];
const cliArgs = { argv: runArgs, cwd: process.cwd(), stdout: process.stdout };
const cli = new Cli(cliArgs);
await cli.run();