How Can I Destructure an Argument With a Default? - javascript

When I run the following snippet in Chrome, it runs perfectly:
(({foo}={}) => {console.log(foo);})({foo: 'baz'});
// logs "baz"
However, if I run that same snippet in Node I get a:
ReferenceError: Invalid left-hand side in assignment
... despite the fact that I ran Node with both the default and destructuring harmony parameters:
nodejs --harmony --harmony_destructuring --harmony_default_parameters
So, my question is, what magic incantation does Node require to process this (perfectly valid, as far as I can tell) ES6 statement?

As #dvlsg suggested, this is simply a bug in the experimental implementation of these Node features.
However, as #estus suggested, and as indicated by the Node developers themselves here, the soon-to-be-released new version of Node will not only fix this problem, it will also roll the bulk of the ES6 functionality directly in to Node (ie. no more node --harmony_whatever).

Related

How to use optional chaining in Node.js 12

Optional chaining (obj?.param1?.param2) seems to be a great feature and I really wanted to see it implemented and finally get rid of nested ifs, arbitrary functions and what not for such a simple operation.
But there's a problem, it doesn't work. I updated to Node 12 and I still get an error:
var dude = res?.param?.params[0]
SyntaxError: Unexpected token '.'
or
var dude = res.param?.params[0]
SyntaxError: Unexpected token '.'
What is the problem?
Do I need to change some language config or download a library to enable this feature? Or is it simply not out yet?
Optional chaining is currently not supported in Node.js version 13 and below. It will be supported from Node.js version 14 and most of the browsers as it is moved to Stage 4. Currently, few platforms are supporting it. You can find the list of platforms supporting optional chaining in the given link. You can enable optional using --harmony flag.
The spec for the optional chaining feature was just promoted to Stage 4 (Finished) on December 22, 2019. Node 12 came out before the spec was final - and so did Node 13, for that matter.
According to node.green, optional chaining will be supported starting with Node 14, but will still require the --harmony flag. (This seems to conflict with Node's description of the --harmony flag - V8's shipping features aren't supposed to require the flag - so I'm not sure what to make of that.) Still, whether it needs a flag or not, I wouldn't expect to see the feature until the Node 14 release around April 2020.
If you want to play with optional chaining today, your best bet is to use TypeScript (which added optional chaining in version 3.7) or a preprocessor like Babel.
I was able to use nodejs v13.7.0 with --harmony flag.
node --harmony myCode.js
Dinah
undefined
undefined
//myCode.js
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
const catName = adventurer.cat?.name;
console.log(catName);
// expected output: Dinah
const dogName = adventurer.dog?.name;
console.log(dogName);
//expected output: undefined
console.log(adventurer.someNonExistentMethod?.())
//expected output: undefined
Optional Chaining will be implemented with Node.js v14, which will be released on 20/04/2020. By now, you may use Babel with #babel/plugin-proposal-optional-chaining.
If you're still having this issue, check the node version you're using node --version.
If you have nvm, make sure you're using a node version that implements the operator that is giving an error.
e.g.
nvm install 15.8
nvm use 15.8

What happened to the Node type definitions?

I've updated to WebStorm 11 and suddenly I don't have the Node Globalslibrary definitions any more (I think it was called Node Globals)?
As such I get squiggly lines for core Node objects like JSON:
I've just added the node-DefinitelyTyped library, that's got rud of the squiggles under JSON but now t says that stringify() is not a function:
There is no Node Globals library anymore, it has been merged with Node Core library that can be configured and enabled in Settings/Languages & frameworks/Node.js and NPM
JSON is not a nodejs thing, so don't include the node.d.ts, it is part of JavaScript, and TypeScript holds all the language definitions in a file called lib.d.ts or lib.es6.d.ts (In case you are outputting into ES6).
Your problem should not happen at all, unless you "told" WebStorm to use a specific version of TypeScript that was configured to ignore the lib.d.ts (And this can be done! by adding --noLib to the compiler)

Getting ES6 to work in WebStorm

Any ideas on how to use ES6 on WebStorm 10?
Here's what I have done so far:
Installed Babel.
Activated Babel with Settings > Tools > File watchers. checked Babel checkbox.
Edit configurations > Before launch file watchers > + then 'Run File Watchers".
Set code as ES6
Changed my run configuration to use the compiled version.
Then created the following trivial piece of code:
require("babel/register");
function* count(n){
console.log(n);
}
This code shows up with no syntax errors, as it should. (A convenient way to make sure ES6 is turned on).
Run it (run the compiled version, actually), and get this ....
var marked0$0 = [count].map(regeneratorRuntime.mark);
^
ReferenceError: regeneratorRuntime is not defined
Why? How do I get it to precompile with Babel and then run? Isn't the regenerator supposed to be taken care of with this line:
require("babel/register");
(Windows 7, if that is important).
Babel's require hook requires you to have BABEL_CACHE_PATH environment variable. You might need to specify them as well in your File Watcher configuration in WebStorm.
I think there are two things you probably need to do to make it work based on the nature of the error you're describing.
npm install babel-core
add --optional runtime as an argument to the invocation of babel
This is based on what's described in some detail here.
The "require hook" only works on files that you require after registering it, but not on the file that registers the hook itself.
So this works:
// index.js
require('babel/register');
require('./count');
// count.js
function* count(n){
console.log(n);
};

Using node.js, nodeunit, and ES6/Harmony

Right now I have a unit testing build environment using node.js and nodeunit. Very happy with these but now I need TCO. I know that TCO has been added into the ES6 standard, but I don't know how to allow it for use with my project. Tried the Harmony flag, but couldn't get it to work with nodeunit. Any help?
Got the idea for using Harmony here:
Node.js tail-call optimization: possible or not?
I like the way these guys think, but I can't do the first answer because then other working on the project would also be forced to change their nodeunit.cmd files (which may screw up other projects they are working on) and the second answer doesn't appear to work:
NodeUnit enable harmony features
From what I understand, it looks like you want to write unit tests in ES5 using nodeunit to test your code written in ES6.
If I understood well, then you can check out this post which shows how to achieve that.
This solution requires you to npm install traceur and then you can require() your ES6 module from within your tests like so :
var traceur = require('traceur');
traceur.require.makeDefault(function(filename) {
return filename.indexOf('node_modules') === -1; // Don't parse node modules
});
var myModule = require('./../path/to/my/module.js');
module.exports = {
// ... tests ...
};
Now you should be able to run that with nodeunit.

Using sinon mocks with nodeunit

I'm learning to use sinon with nodeunit, specifically to do mocking. The recommended approach is to use sinon-nodeunit. According to the documentation, mocks should be available via the mock method of the test parameter to each test function.
However, this doesn't seem to work. If I run nodeunit on a file containing the following —
require('sinon-nodeunit');
exports['test sinon-nodeunit'] = function (test) {
mock = test.mock({});
test.done();
};
— I get this:
$ nodeunit test/test-sinon-nodeunit.js
test-sinon-nodeunit.js
✖ test sinon-nodeunit
TypeError: Object #<Object> has no method 'mock'
at /home/malkovich/test/test-sinon-nodeunit.js:4:17
at Object.runTest (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:54:9)
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:90:21
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:508:13
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:118:13
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:134:9
at /usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:507:9
at Object.concatSeries (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/deps/async.js:147:23)
at Object.runSuite (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:79:11)
at Object.runModule (/usr/local/lib/node/.npm/nodeunit/0.5.1/package/lib/core.js:114:13)
FAILURES: 1/1 assertions failed (84ms)
I've installed current versions of both sinon (1.1.1) and sinon-nodeunit (0.1.2) via npm install.
require.path was removed in node 0.5.x and higher, which sinon-nodeunit uses. Christian Johansen just pushed a change in sinon-nodeunit which should be compatible with node 0.6.2 (and 0.5.x-series) which should fix this... It's already available on sinon-nodeunits github page, still hasnt hit npm though...
update: should be mentioned that sinon-nodeunit has been discontinued, as the creator is full focused on BusterJS which IMHO is a much better framework.

Categories

Resources