How does require work when calling node module directly? - node.js

When calling a node module directly, e.g. $ ./node_modules/.bin/webpack -d, how is the module aware of how to handle any require functions?
I understand how the require function works, but I'm confused where it is defined.
I had assumed that using something like $ npm start would give context to handle require, but how does Node get involved (and define how to handle require) when the module is called directly?

You're not calling the module directly, you're calling an executable that got installed as part of a package.
That executable runs a full Node interpreter, with the contents of the executable file as the script.
Basically, it's similar to running this on the command line:
node ./node_modules/.bin/webpack

Related

How can I execute node cli script from another node.js script/module?

I have a node library with multiple scripts (ES modules to be precise). One of the module, when invoked, uses exec function from built-in child_process module. I need to run ts-node command using the exec function.
The problem is that ts-node is not recognized as exec doesn't do the path manipulation magic that npm scripts do by appending the node_modules/.bin to the path variable. Further, I cannot rely on __dirname and __filename special values as I use ESM and not CJS (I know there is a way to get these values but I would rather prefer if there is any standard approach to execute commands with the semantics of npm scripts).
So, how can I execute ts-node command from my own script which could be installed anywhere (as a nested dependency)?

MeteorJs es6 modules imports

I recently discovered that, whenever I try to to execute a node script like that:
"run-my-script": "node ./folder/function.js executeFunction $ARG"
It seem that using a script with node causes troubles with ES6 imports.
If I run a basic script like that I get this error:
SyntaxError: Cannot use import statement outside a module
My running command line look like that:
ARG=myArg npm run run-my-script
Like if it was impossible for meteor to run a node script outside without the need to transpile code to ES6 first.
All my modules are designed by ES6 modules approach:
import { SchemaBuyers } from './schema';
I don't want to specify type=module inside my package.json because first of all, it's not necessary, I don't have compilation errors when building the apps, ony when running pure node script, and secondly it would require to rename all my files extentions to .mjs for example.
Thank you very much !
You can use node.js's --input-type option for this if you pipe the file into it:
cat test.js | node --input-type=module
Or in your case:
"run-my-script": "cat ./folder/function.js | node --input-type=module executeFunction $ARG"
This assumes that the code in function.js will parse the provided arguments.

how to require a .js file in node repl

so i usually use ruby irb, and I can pull .rb files I wrote into the console environment by running
load './script.rb'
and then all of the functions I wrote in script.rb will be available.
I cannot figure out for the life of me how to do this in the node "console" environment!
You can load JavaScript files using the require function. The following example assume that the Node.js process was started at the directory where your file is located.
require('./script.js');
This will execute the contents of the file.
If you have exported functions or objects, you can assign them to a variable and use them later.
const myFunction = require('./script.js').myFunction;
myFunction();
Like many other development frameworks/languages, Node has a Modules/Package System which, is a CommonJS variant. To load a Module use require(). The usage of require() is the same when running JavaScript files or running in the REPL.
You can require Node Core Modules, NPM Installed Packages or your own local modules. When loading NPM Packages specified in a package.json or a local module, Node will load them from the Current Working Directory(CWD), you can check this using process.cwd(). The CWD will be set to the absolute path of the directory you launched the REPL from.
You can launch the REPL via running node in your CLI and require your packages like below.
// Core Package
const os = require('os')`
console.log(os)
// NPM Package
const moment = require('moment')
console.log(moment)
// Local Package
const myPackage = require('./myPackage')
console.log(myPackage)
You can also pre-require module(s) using the -r flag when running node. The below will launch the Node REPL with the os package preloaded. You can then access the os package using the variable os
node -r os
console.log(os)
In the future, Node may also support ECMAScript Modules (ie. import). You can read more detailed info about that in the Enhancement Proposal.

How to I run in nodejs a javascript file produced by haste?

If I have a file, hello.hs:
main = putStrLn "Hello, World!"
I can compile it to hello.js using haste command:
hastec hello.hs
How do I run the result hello.js file under nodejs?
By default, Haste's main is set to execute when the browser's onload event fires. This obviously makes no sense for Node, so you need to pass the --onexec flag to Haste when compiling your program:
$ hastec --onexec hello.hs
Haste uses Node to run its test suite in this way. Note, however, that with the exception of writing to standard output (like putStrLn), Haste does not map system operations (file IO, etc.) to Node equivalents. If you're writing an application that needs to interact with the OS, you're better off using vanilla GHC.
Update:
Thank you, and good answer. To recap, if you want to compile and run hello.hs under node, the two lines would be:
hastec --onexec hello.hs
node hello.js
haste doesn't know about node, so the .js files in produces doesn't export anything.
You need to somehow augment the .js file to export the functionality that you want, namely you need to export the hasteMain() function.
You may try the --with-js command line option to hastec
Or you may simply append the following line to the end of your hello.js file:
module.exports = hasteMain;
Once you do that, you can load hello.js as a module using require and run the code:
hasteMain = require('./hello.js');
hasteMain();
You may also want to look at ghcjs. The React team recently moved one of the modules from haste to ghcjs

getting node.js working

So I'm following:
http://giantflyingsaucer.com/blog/?p=894
and installing node.js.
I got up to the part with sudo make install.
It works, then it says to create a js file.
What I don't understand is where I put the sayhello.js?
Node.js looks at least for the programmer more like a interpreter. Thus, you can place your sayhello.js whereever you want and run it by executing node sayhello.js.
However, you might consider using external modules. Then you must check that they are set by full path or the relative path can be resolved from the location you execute node in.

Resources