Available modules in node script - javascript

why do I get different results when trying to find out more about the http module in node.js in the following to ways?
If I enter the node REPL and then print the content of the http module, i.e. if I run
me#mymachine:~> node
> console.log(http)
I get all the details of the http object:
{ IncomingMessage:
{ [Function: IncomingMessage]
super_:
{
...
If I write a script file called, say, script.js containing the following single line
console.log(http);
and execute it by running
node script.js
I get
ReferenceError: http is not defined
I would have expected both cases to behave in the same way - either the http module is preloaded or not. Why is there a difference? What am I getting wrong here?
I thought I could 'fix' this by preloading module http by running (in version 2)
node -r http script.js
Shouldn't this preload module http and thus avoid the reference error?
Looking forward to your input!

Repl has all the standard Node.js core modules required by default.
https://nodejs.org/api/repl.html#repl_accessing_core_node_js_modules

Related

Fetch local files with Node.js

In a browser environment fetching a local file is quite trivial: one just need to start a server (using MAMP, XAMP, Mac's Python server, etc...), and then doing:
fetch("./foo.txt").then(etc...)
However, in Node.js this simple task has been a challenge. I've tried the same snippet using Node 18 (which comes with an experimental fetch API), but I'm always getting an invalid URL error:
TypeError: Failed to parse URL from foo.bar
[cause]: TypeError [ERR_INVALID_URL]: Invalid URL
I've tried installing node-fetch, but I'm getting the same error. I could start a local server for node like http-server, but it tells me to go to http://localhost:8080 to see the server, that is, using the browser, but the issue is that I can do that without node, using only a node build is the whole point.
My question is: is it possible to fetch a local file in a node build (Sublime Text, VS Code etc...), without using a browser? (note: I can do it with fs, but in my question I'd like to discuss fetch only)
My question is: is it possible to fetch a local file in a node build (Sublime Text, VS Code etc...), without using a browser? (note: I can do it with fs, but in my question I'd like to discuss fetch only)
The Node.js implementation of fetch does not currently support file: scheme URLs…
fetch("file:///tmp/123").then(r => r.text()).then(d => console.log(d));
reports:
Error: not implemented... yet...
…nor (it appears) does it resolve a relative path to a file: scheme URI.
You should use the fs module.

Bad HTTPS cert: "TypeError: Failed to execute 'compile' on 'WebAssembly': HTTP status code is not ok" in Webworker

I'm trying to run Webassembly inside a Webworker
I can load heavyLifting.wasm perfectly fine the traditional way (aka not in a webworker) but trying to load it inside a webworker runs into warnings (not errors actually). Here's how I loaded it:
// worker.js
self.importScripts('heavyLifting.js');
And the warning:
wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': HTTP status code is not ok
From what I gather, it finds the file - but I assume it has something to do with it not being HTTPS.
I actually haven't tried serving it through HTTPS yet (because locally serving HTTPS has become a lot more difficult for some reason). However, does anyone have any knowledge that might save me a few more hours of banging my head against the wall? Did I forget some setting or config? Why would a webworker be extra picky about what wasm it serves (because as I mentioned, I'm able to serve up my wasm fine as a regular script)
Update:
It wasn't an HTTPS error - it had to do with importScript().
worker.js
js/
heavyLifting.js // glue code
heavyLifting.wasm
This was all fixed by moving worker.js down into the js folder.
I immediately ran in to the following error:
'Uncaught (in promise) TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.'
It turns out the node package http-server doesn't serve wasm properly, but the python3 http.server does.

Handle global variable in node.js server

I have a node.js server that reads messages from a rabbitmq server. Every message contains an url that returns a json object whit specifications to download some jsx code.
The node.js server gets the code from the urls and compiles it with webpack.
My problem is that I need to keep aware of the information of the json objects in the webpack compilation instance, because I need to print the downloaded objects in the index page.
Node Server -- Get messages --> RabbitMQ Server
RabbitMQ Server -- Return messages --> Node Server
Node Server -- Get code [from URL] --> URL service
URL service -- Return code --> Node Server
Node Server: Compile downloaded code.
I don't know if I was clear. I tried to use global variables and module.exports, but did not work. Maybe I am missing something, I am a kind of beginner in JS, node and webpack.
Could you cache those in memory, that way they would be available to access.
One of the popular module is memory-cache
Though memory caching comes in with it's own set of limitations.
Hope I understood the question correct.

browserify Error : http.createServer is not a function

I tried to browserify this node js script :
var phantom = require('phantom')
phantom.create(function(ph) {
ph.createPage(function(page) {
page.open("editor.html", function(status) {
console.log("opened diagram? ", status);
page.evaluate(function() {
return document.getElementById("GraphImage").src;
}, function(result) {
//console.log(result);
ph.exit();
});
});
});
});
So I used this command:
browserify myscript.js > bundle.js
and when I run bundle.js from an html file I get this error:
http.createServer is not a function
it seems that browserify does not support httpserver. How can I resolve this problem?
You can't run a web server from inside a web browser. There really isn't anything in the browser that could act like Node's http module. Also it doesn't make sense to run PhantomJS in a browser, because PhantomJS is a web browser.
What is the desired behavior you are trying to accomplish?
Update:
It seems like you are trying to run code intended for Node.js inside a browser instead.
The JavaScript engine inside the browser is much more restrictive than in Node.js, for example you can't access the file system from inside the browser for security reasons (or else you could read the hard drive of anyone who visited your web page).
Browserify does include some "shims" that will put small JS libraries into your code that work in the browser and match the API of Node.js, allowing some Node.js specific JS code to execute in the browser.
In your case, you are requiring Phantom, which seems to in turn require http. Accoring to the Browserify documentation, it will see require('http') and include a shim for the http module (because browser's don't provide an http module of their own).
The Phantom module then tries to call http.createServer() but accoring to the documentation for that http shim:
This module implements http.request, http.get, and most of http.ClientRequest and http.IncomingMessage in addition to http.METHODS and http.STATUS_CODES.
so http.createServer() is not supported by the shim. This also makes sense because a browser would never let you open an http server inside of itself, or else navigation to someone's web site could cause your browser to start serving content to the outside world, which obviously doesn't make sense.
In your comment:
"i want that my node js script can be executed from another JS code"
You don't specify what "other JS code" is running in. If that JS code is already running in Node, then you don't need Browserify at all. If you are trying to have a web browser start up an actual Node.js process, that isn't going to happen, again for obvious security reasons, because browsing to a web page shouldn't have the ability to run any executable on your system.
What Browserify lets you do is take code originally intended for Node.js, and run it in a browser instead, but a t runtime it is executing in the browser, not in Node.js, so you can only use JS code that works within the constraints of the browser's JS runtime.
If you are trying to execute your code in Node.js, then you need to do that by having something start the Node.js executable, either from the command line or by having another program start the process for you, but that can't be done from within a web browser. If you are trying to have users navigate to your web site and then have this code run on their machines in a browser and not in Node.js, then you need to only use modules that work in the browser.

Frisby.js: Expected valid JavaScript object to be given, got undefined

I'm having some trouble getting a new test off the ground with this Frisby.js API testing framework.
For context, I have written some other tests that don't require reading in reference files from disk, and have run some of the samples that came with Frisby, and they all run very quickly and accurately. Really liking the speed of execution so far. Seeing as how all of that comes back OK, I am fairly certain that my environment is sound.
Below is a simplified version of a problematic JavaScript file, that I am running through jasmine-node:
var frisby = require('frisby');
var fs = require('fs');
var path = require('path');
var URL = 'http://server/api/';
var getJSON = fs.readFileSync(path.resolve(__dirname, 'GET.json'), 'utf-8').replace(/^\uFEFF/, ''); // the .replace removes the BOM from the start of the file
console.log(getJSON); // this dumps the file contents to the screen, no problems here
frisby.create('GET from API')
.get(URL + 'Endpoint?Parameters=Values')
.expectStatus(200) // tests that HTTP Status code equals expected 200, still no worries
.expectJSON(getJSON) // this is where the 'undefined' error is thrown
.toss();
Running the test from the command line is very straight forward:
C:\Testing\Frisby> jasmine-node apitest.js
I believe I'm doing things in the right order, with the synchronous file read, and then the Frisby calls afterwards, but when executed it throws the following error:
Failures:
1) Frisby Test: GET from API
[ GET http://server/api/Endpoint?Parameters=Values ]
Message:
TypeError: Expected valid JavaScript object to be given, got undefined
Stacktrace:
TypeError: Expected valid JavaScript object to be given, got undefined
at _jsonContains (C:\Users\jlucktay\AppData\Roaming\npm\node_modules\frisby\lib\frisby.js:1182:11)
at jasmine.Matchers.toContainJson (C:\Users\jlucktay\AppData\Roaming\npm\node_modules\frisby\lib\frisby.js:1141:12)
at null.<anonymous> (C:\Users\jlucktay\AppData\Roaming\npm\node_modules\frisby\lib\frisby.js:686:24)
at null.<anonymous> (C:\Users\jlucktay\AppData\Roaming\npm\node_modules\frisby\lib\frisby.js:1043:43)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
Finished in 0.292 seconds
1 test, 2 assertions, 1 failure, 0 skipped
I have the jasmine-node and frisby packages both installed globally via npm, and have used npm link frisby which created the appropriate junction from my testing directory over to %APPDATA%\npm.
I have also tried changing the code around, to use fs.readFile instead of fs.readFileSync with the frisby calls inside the callback, but still have the same problem.
As I said above, my other tests and the samples that came with Frisby run and come back without error. Specifically, the httpbin_binary_post_put_spec.js sample uses almost identical code to what I ended up writing myself, and that sample works just fine.
I have routed the HTTP requests through Fiddler and can see the request and response, and everything looks fine there. It gets a HTTP 200 and the response body has the expected JSON that I want to compare against the file contents.
Why am I getting this error about an undefined object?
Rubber duck problem solving seems to have rescued me from my own stupidity.
The string needed to be turned into a proper JSON object:
.expectJSON(getJSON) -> .expectJSON(JSON.parse(getJSON))

Categories