0

I wish to create one NodeJS source file in a Jupyter notebook which is using the IJavascript kernel so that I can quickly debug my code. Once I have it working, I can then use the "Download As..." feature of Jupyter to save the notebook as a NodeJS script file.

I'd like to have the ability to selectively ignore / include code in the notebook source that will not execute when I run the generated NodeJS script file.

I have solved this problem for doing a similar thing for Python Jupyter notebooks because I can determine if the code is running in an interactive session (IPython [REPL]). I accomplished this by using this function in Python:

def is_interactive():
    import __main__ as main
    return not hasattr(main, '__file__')

(Thanks to Tell if Python is in interactive mode)

Is there a way to do a similar thing for NodeJS?

3 Answers 3

1

I don't know if this is the correct way but couldn't find anything else basically if you

try {
   const repl = __dirname
} catch (err) {
  //code run if repl
}

it feels a little hacky but works ¯\_(ツ)_/¯

Sign up to request clarification or add additional context in comments.

2 Comments

This isn't really a good idea because it depends on the REPL using CommonJS, which may be changed in future versions of NodeJS. Not to mention CommonJS is the default execution environment for scripts that aren't explicitly marked as EJS Modules. So this could throw a false positive very frequently.
I think that won't work if you place it in a js file.
1

The fastest and most reliable route would just be to query the process arguments. From the NodeJS executable alone, there are two ways to launch the REPL. Either you do something like this without any script following the call to node.

node --experimental-modules ...

Or you force node into the REPL using interactive mode.

node -i ...

The option ending parameter added in v6.11.0 -- will never append arguments into the process.argv array unless it's executing in script mode; via FILE, -p, or -e. Any arguments meant for NodeJS will be filtered into the accompanying process.execArgv variable, so the only thing left in the process.argv array should be process.execPath. Under these circumstances, we can reduce the query to the solution below.

const isREPL = process.execArgv.includes("-i") || process.argv.length === 1;

console.log(isREPL ? "You're in the REPL" : "You're running a script m8");

This isn't the most robust method since any user can otherwise instantiate a REPL from an intiator script which your code could be ran by. For that I'm pretty sure you could use an artificial error to crawl the traceback and look for a REPL entry. Although I haven't the time to implement and ensure that solution at this time.

3 Comments

That doesn't work if I e.g. use babel-node . isREPL returns false for me then.
I changed it to const isREPL = !!require("repl").repl; Not sure if that's always reliable though.
@jtompl, I'll have to take a look at that and see if I can find a workaround for that then, I haven't played with babel-node. I was only answering the question in the context of standalone node.
1

This may not help the OP in all cases, but could help others googling for this question. Sometimes it's enough to know if the script is running interactively or not (REPL and any program that is run from a shell).

In that case, you can check for whether standard output is a TTY:

process.stdout.isTTY

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.