command line node.js; running script with modules - javascript

I'm doing some testing with node.js and several modules\libraries. For simplicity I'll focus on underscore.js.
When I run node.exe with the following source:
require("./underscore.js");
_.each({one : 1, two : 2, three : 3}, function(num, key){ console.log(num); });
I get:
C:\Dropbox\personal-work\foo\test code>node library-tests.js
node.js:208
throw e; // process.nextTick error, or 'error' event on first tick
^
ReferenceError: _ is not defined
at Object.<anonymous> (C:\Dropbox\personal-work\foo\test code\library-tests.js:2:1)
at Module._compile (module.js:425:26)
at Object..js (module.js:443:10)
at Module.load (module.js:344:31)
at Function._load (module.js:303:12)
at Array.<anonymous> (module.js:463:10)
at EventEmitter._tickCallback (node.js:200:26)
What is also strange is that when I run it like this:
node underscore.js library-tests.js
It doesn't seem to do anything at all...I've even added log statements, they don't seem to execute.
I've also tried pasting in the underscore.js source into the top of my source and I get the same error...
Does anyone know what I'm doing wrong here? Thanks.

try assigning it:
var _ = require('../underscore.js');
You can see here in the annotated source code that underscore will not add itself to the global namespace if it is running in a CommonJS implementation (of which, Node.JS is one).

Related

Discord.js module error before first line of code

I just started writing a Discord bot in Visual Studio Code in Javascript, it's literally the most basic it can be, loading discord.js, on ready event and then login.
Before it even runs the first line of code, I get this error:
Debugger listening on ws://127.0.0.1:5489/3cf4a3d1-ef26-4c1c-a274-030564d40731
For help see https://nodejs.org/en/docs/inspector
i:\Coding\Bots\PURGE\node_modules\discord.js\src\util\Util.js:584
str = str.replace(/#([^<># ]*)/gmsu, (match, target) => {
^
SyntaxError: Invalid regular expression flags
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:607:28)
at Object.Module._extensions..js (module.js:654:10)
at Module.load (module.js:556:32)
at tryModuleLoad (module.js:499:12)
at Function.Module._load (module.js:491:3)
at Module.require (module.js:587:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (i:\Coding\Bots\PURGE\node_modules\discord.js\src\index.js:3:14)
Process exited with code 1
The error occurs in the Discord.js module which I didn't write, and have no idea how it works and therefore cannot fix.
Re-installling Discord.js didn't help, reinstalling Visual Studio Code didn't either.
I sent a friend the exact same files (even the same node_modules folder) and when he runs it, it works with no problems. Any ideas what the problem is or how I can fix it?
This is my code:
console.log("test") //DOESNT LOG
const Discord = require("discord.js");
const fs = require("fs");
const config = require("./config.json");
let christian = {}
//This will define our bot
var bot = new Discord.Client()
bot.on('message', async msg => {
console.log(msg)
})
bot.on('ready', () => {
console.log(`-----Purge#2420 Online-----\nWatching over ${bot.guilds.cache.size} servers |`)
});
bot.login(config.token)
From the comments:
I am on [Node] v8.9.4, [...] on Discord.js V12
From Discord JS' upgrade guide::
v12 requires Node 12.x or higher to use, so make sure you're up-to-date.
That is -- you'll have to upgrade your Node.js.
In the ready event you have an invalid string which maybe causing the error '-----Purge#2420 Online-----\nWatching over ${bot.guilds.cache.size} servers | it maybe crashing due to the invalid single quote ' at string's start, try replacing it with a backtick (`).
Read more about template strings here

Backticks in node.js

I am attempting to use the following code as a file test2.js with node.js version 12.0.
let apiKey = '117fa18eaf7312fa52f593c6d52fc48d';
let id = '6094817';
let xu1 = `http://api.openweathermap.org/data/2.5.weather?id=$(id)&APPID=$(apiKey)`;
console.log('xul is: ', xul);
I get the following results and I am unable to understand why.
jgossage#jgossage-XPS-8700:/LinuxData/Projects/node-weather$ node test2.js
/LinuxData/Projects/node-weather/test2.js:4
console.log('value is: ', xul);
^
ReferenceError: xul is not defined
at Object.<anonymous> (/LinuxData/Projects/node-weather/test2.js:4:27)
at Module._compile (internal/modules/cjs/loader.js:936:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)
at Module.load (internal/modules/cjs/loader.js:790:32)
at Function.Module._load (internal/modules/cjs/loader.js:703:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:999:10)
at internal/main/run_main_module.js:17:11
The only thing I can see is that possibly the template string is not being handled properly, resulting in the variable xul being not defined.
As #Andreas mentioned you have a typo it should be
console.log('value is: ', xu1);
but also even if you run that you get
xu1 is: http://api.openweathermap.org/data/2.5.weather?id=$(id)&APPID=$(apiKey)
That is because you have to use ${} instead of $().
So the final fix is
let xu1 = `http://api.openweathermap.org/data/2.5.weather?id=${id}&APPID=${apiKey}`;

Why can't I eval a .load to start an interactive script in node.js?

In node.js you can pass the argument -i to get an interactive console, and then pass -e to evaluate a javascript statement.
I tried running:
$ node -i -e '.load ./someScript.js'
.load someScript.js;
^
SyntaxError: Unexpected token .
at Object.exports.runInThisContext (vm.js:53:16)
at Object.<anonymous> ([eval]-wrapper:6:22)
at Module._compile (module.js:410:26)
at node.js:578:27
at nextTickCallbackWith0Args (node.js:419:9)
at process._tickCallback (node.js:348:13)
And I get an error, but if I try to run the same thing from the interactive node prompt, it loads just fine; i.e.
> .load ./someScript.js
Is there something else I need to do to make this work?
Why can't I eval a .load to start an interactive script in node.js?
Because -e is for evaluating JavaScript code. The interactive REPL's commands aren't JavaScript, they're REPL interactive commands.
This question asks how to go interactive after running a script, which doesn't answer the "why" part (that's why I've posted the above), but its answers may give you some options for the somewhat-implied "...and what do I do instead?" part. :-)
You could maybe use a custom script to initiate the REPL from its module:
Something like:
const repl = require('repl'),
path = require('path'),
location = process.argv[2],
base = path.basename(location),
clean = path.split('.')[0];
const r = repl.start('> ');
Object.defineProperty(r.context, clean, {
configurable: false,
enumerable: true,
value: require(location)
});
So, now you can do node loadModule /path/to/load.js, the module will be available depending on the base of the path (/path/to/load.js will be available under load for example)

Creating JS library Warning instead of Error

I am creating my own JS library with NPM. I want to give the users of my library a warning but not an error, however, I want my users to have a stacktrace of the warning that I log inside my library. So to get the stacktrace, I use new Error().stack. The problem with this is (1) the word 'Error' appears in the stacktrace by default and (2) the stack trace is the same for Node and Chrome but different for Mozilla.
So my question is - what is the best way to create a warning message that has a stacktrace, but that doesn't look like an error? Chrome and Node.js are aligned and I could simply remove the first element of the stack array before calling toString() on it. But the problem is that this wouldn't work for Mozilla.
Anyway, this is what I currently do in my library when there should be a warning emitted:
var err = new Error('looks like you have called IdempotentJSON.parse on an object that was already parsed');
console.error(err.message.concat('\n'),err.stack);
this "logs a warning" that looks like this
in Chrome
looks like you have called IdempotentJSON.parse on an object that was already parsed
Error: looks like you have called IdempotentJSON.parse on an object that was already parsed
at IdempotentJSON.parse (http://localhost:3000/static/vendor/idempotent-json.js:11:23)
at Backbone.Model.extend.persistModel.save.success (http://localhost:3000/static/app/js/models/userModel.js:88:56)
at Object._.extend.save.options.success (http://localhost:3000/static/vendor/backbone.js:620:30)
at jQuery.Callbacks.fire (http://localhost:3000/static/vendor/jquery.js:3099:30)
at Object.jQuery.Callbacks.self.fireWith [as resolveWith] (http://localhost:3000/static/vendor/jquery.js:3211:7)
at done (http://localhost:3000/static/vendor/jquery.js:8264:14)
at XMLHttpRequest.jQuery.ajaxTransport.send.callback (http://localhost:3000/static/vendor/jquery.js:8605:9)
in Mozilla Firefox:
"looks like you have called IdempotentJSON.parse on an object that was already parsed
" "IdempotentJSON.prototype.parse#http://localhost:3000/static/vendor/idempotent-json.js:11:23
#http://localhost:3000/static/app/js/app.js:157:30
Backbone.batchSyncCollection/<#http://localhost:3000/static/app/js/app.js:141:16
jQuery.Callbacks/fire#http://localhost:3000/static/vendor/jquery.js:3099:10
jQuery.Callbacks/self.fireWith#http://localhost:3000/static/vendor/jquery.js:3211:7
done#http://localhost:3000/static/vendor/jquery.js:8264:5
.send/callback/<#http://localhost:3000/static/vendor/jquery.js:8605:1
in Node.js
looks like you have called IdempotentJSON.parse on an object that was already parsed
Error: looks like you have called IdempotentJSON.parse on an object that was already parsed
at IdempotentJSON.parse (/Users/amills001c/WebstormProjects/first_comcast/node_modules/idempotent-json/index.js:9:19)
at Object.<anonymous> (/Users/amills001c/WebstormProjects/first_comcast/IJSONexp/ijson.js:8:15)
at Module._compile (module.js:460:26)
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
one quick solution that would work for Node.js and Chrome would be to remove the first line of the stack trace that says "Error:...".
But this call is not valid:
err.stack.shift(); //error
apparently the stack is not an Array in JS?
And this wouldn't work for Mozilla anyway.
Is my best bet another library that checks which environment/browser that it's in? Like this:
http://www.eriwen.com/javascript/js-stack-trace/
it's 2015! By the way Mozilla, Chrome and Node have it right with the stack trace, I can click on the stack trace in Chrome and Node and it takes me to the files involved, doesn't seem like I can do this in Firefox.
What I want is something that looks like this:
Warning: looks like you have called IdempotentJSON.parse on an object that was already parsed
at IdempotentJSON.parse (http://localhost:3000/static/vendor/idempotent-json.js:11:23)
at Backbone.Model.extend.persistModel.save.success (http://localhost:3000/static/app/js/models/userModel.js:88:56)
at Object._.extend.save.options.success (http://localhost:3000/static/vendor/backbone.js:620:30)
at jQuery.Callbacks.fire (http://localhost:3000/static/vendor/jquery.js:3099:30)
at Object.jQuery.Callbacks.self.fireWith [as resolveWith] (http://localhost:3000/static/vendor/jquery.js:3211:7)
at done (http://localhost:3000/static/vendor/jquery.js:8264:14)
at XMLHttpRequest.jQuery.ajaxTransport.send.callback (http://localhost:3000/static/vendor/jquery.js:8605:9)
Looking into the source of console.trace you can try this for chrome & node.js:
function warning(message) {
var err = new Error;
err.name = 'Warning';
err.message = message; //or use util.format in nodejs
Error.captureStackTrace(err, warning); // this is to prevent `warning` function being included in the stack.
return err;
};
console.log(warning('message').stack);
In nodejs, this outputs:
Warning: message
at Object.<anonymous> (/home/ubuntu/workspace/warning.js:9:13)
at Module._compile (module.js:460:26)
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
Unfortunately firefox doesn't have captureStackTrace method. So you have to call the above directly without wrapping it in a function.

I want to run d3 from a Cakefile

I'd like to execute some d3 code from the command line. Initially I just tried something like:
task 'data', 'Build some data with d3', ->
d3 = require('lib/d3.v2')
console.log "d3 version = "+ d3.version
But this didn't work. I got errors like this:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
ReferenceError: CSSStyleDeclaration is not defined
at /Users/mydir/Documents/classes/middleclass/app/lib/d3.min.js:1:21272
at Object.<anonymous> (/Users/mydir/Documents/classes/middleclass/app/lib/d3.min.js:2:25395)
at Module._compile (module.js:432:26)
at Object..js (module.js:450:10)
at Module.load (module.js:351:31)
at Function._load (module.js:310:12)
at Module.require (module.js:357:17)
at require (module.js:368:17)
at Object.action (/Users/mydir/Documents/classes/middleclass/Cakefile:22:10)
at /usr/local/lib/node_modules/coffee-script/lib/coffee-script/cake.js:39:26
So...I figured this exception was telling me that I need to execute d3 inside of a browser. I tried this in a couple different ways. Basically though, I thought if I just fired up phantomjs I'd probably be able to do what I wanted to do. Here was my Cakefile:
task 'data2', 'Build some data with d3', ->
hem = spawn 'hem', ['server']
phantom = require('phantom')
phantom.create (ph) ->
ph.createPage (page) ->
page.open 'http://localhost:9294/sandbox.html', (status) ->
page.evaluate (-> window), (window) ->
require = window.require
require('lib/d3.v2')
console.log("d3 version = "+ d3.version)
ph.exit()
hem.kill()
When I go this route though, I always end up getting exceptions like this:
TypeError: object is not a function
at Object.CALL_NON_FUNCTION (native)
at Object.<anonymous> (/Users/mydir/Documents/classes/middleclass/Cakefile:52:13)
at Object.<anonymous> (/Users/mydir/Documents/classes/middleclass/node_modules/phantom/node_modules/dnode-protocol/index.js:274:16)
at apply (/Users/mydir/Documents/classes/middleclass/node_modules/phantom/node_modules/dnode-protocol/index.js:143:17)
at EventEmitter.handle (/Users/mydir/Documents/classes/middleclass/node_modules/phantom/node_modules/dnode-protocol/index.js:120:13)
at /Users/mydir/Documents/classes/middleclass/node_modules/phantom/node_modules/dnode-protocol/index.js:81:20
at EventEmitter.<anonymous> (/Users/mydir/Documents/classes/middleclass/node_modules/phantom/node_modules/dnode/node_modules/lazy/lazy.js:62:13)
at EventEmitter.<anonymous> (/Users/mydir/Documents/classes/middleclass/node_modules/phantom/node_modules/dnode/node_modules/lazy/lazy.js:46:19)
at EventEmitter.emit (events.js:67:17)
at EventEmitter.<anonymous> (/Users/mydir/Documents/classes/middleclass/node_modules/phantom/node_modules/dnode/node_modules/lazy/lazy.js:46:39)
What am I doin wrong??
Thanks to mbostock I got the following working:
My package.json:
{
"name": "app",
"version": "0.0.1",
"dependencies": {
"d3": "~2.8.0",
"jsdom": "~0.2.13"
}
}
My Cakefile:
task 'd3', 'Do something with d3', ->
jsdom = require('jsdom')
jsdom.env({
html: 'public/sandbox.html'
done: (errors,window) ->
require('d3/index.js')
console.log("d3 version = "+ d3.version)
})
See D3's package.json. More specifically, the file you want to require when running inside Node or similar environments is index.js rather than d3.v2.js; this file contains some special patches that make D3 compatible with the require operator.
To try it out for yourself, cd to the d3 repository, run node to create an interactive shell, and then say
var d3 = require("./");
Or, if you're in your own project folder, if you've installed D3 into node_modules/d3 via npm (npm install d3), you can say:
var d3 = require("d3");

Categories

Resources