$ cat test.js
'use strict';
console.log(process.versions.node);
new require('module').constructor('/foo/bar/baz');
$ node test.js
16.0.0
undefined:3
/foo/bar/baz
^
SyntaxError: Invalid regular expression flags
This behaviour is very odd! I'm hoping someone can explain it to me. I see no syntax error here.
Interestingly, new module.constructor('/foo/bar/baz') works in the REPL.
I have a typescript project. In some of the typescript files I include a plain javascript/node file called config.js which looks like this:
'use strict';
module.exports = {
a: 'a',
b: 'b',
c: 'c',
};
When I run tsc the transpilation fails with an error that refer to files that import this config.js file. The error seems to point at some typescript type related problem:
src/db/index.ts:138:26 - error TS2345: Argument of type 'string' is not assignable to parameter of type '"source" | "command" | "training" | "page"'.
138 await mutateCollection(CONFIG.commandCollectionName, mutateCommandCollection, commands);
The error looks like an application level error but what is a total mystery to me is that when I change my config.js to:
'use strict';
module.exports = {
a: 'a',
b: 'b',
c: 'c',
...undefined
};
The transpilation step succeeds.
The import of the config.js in the typescript file looks like this: import CONFIG from '../config';
Now my question is: without knowing anything about my typescript code, how could adding a spread of undefined (...undefined) ever cause the transpilation to succeed? As far as I know {...undefined} results in an empty object. Is there some weird bug or edge case that I don't know of?
Note: it doesn't matter where in the object I put the spread of undefined: { a: 1, ...undefined, b: 2 } also makes the transpilation succeed, only leaving it out entirely will make it fail.
The people in the comments were right.
If I turn the config.js file into a typescript file with explicit types defined (as can be seen below), then my project transpiles succesfully. It indeed looks like using a spread of undefined ({ ...undefined }) causes typescript to not infer the types in the plain .js file anymore and then also not complain about them when used in the typescript files themselves.
An alternative would be to keep using a plain .js file and provide a d.ts file to specify the types.
const CONFIG: {
a: string,
b: string
} = {
a: 'a',
b: 'b'
}
export default CONFIG;
Is there a way in node.js (ideally mocha too) to simulate the behavior of python
python -m pdb setup.py test
That will fallback to debug interface on if the program throws an uncaught exception.
EDIT
#robertklep suggested the undocumented breakOnException command which looks really awesome but not so much in practice:
test.js
var hello = {};
function testFunc () {
anotherFunct();
}
function anotherFunct () {
var b = hello.unfound;
}
testFunc();
And then it freezes at:
$ node debug test.js
< Debugger listening on port 5858
connecting to port 5858... ok
break in test.js:1
> 1 var hello = {};
2 function testFunc () {
3 anotherFunct();
debug> breakOnException
debug> c
debug> backtrace
EDIT2: test.js didn't yield an error in the first place. The above works fine.
Add this to your script:
process.on('uncaughtException', function() {
debugger;
});
And start it with node debug script.js. That will drop you into the debugger on uncaught exceptions/errors.
To get this (somewhat) working for Mocha tests, you can add the lines above and follow the instructions here (specifically installing node-inspector and starting Mocha using --debug-brk).
EDIT: the Node debugger also has the ability to break on errors/exceptions:
$ node debug script.js
debug> breakOnException
debug> c
...
Came across strange behavior in node. I have an emscripten compiled program that I would like to use as a library. emscripten use a variable Module to control runtime behavior, and generates code like ./lib/g.js below. In the browser, Module is properly aliased from the global defined in index.js to the local var in ./lib/g.js. However, in node, this does not seem to be the case. The construct: var Module = Module || {}; wipes out my global Module.
index.js:
global.Module = { name: 'Module' };
var g = require ( './lib/g.js' );
./lib/g.js:
console.log ( 'Module: ', Module );
var Module = Module || {};
Output of node index.js:
Module: undefined
I assume in g.js, Module is hoisted and dereferenced only in the local scope, masking the global version (in global.Module). Can anyone suggest a work-around?
This problem can be fixed by editing the emscripten produced code to use var Module = global.Module || {}. While this is a possible workaround, I would rather not edit the code generated by emscripten.
You might take a look at using rewire
var rewire = require("rewire");
var g = rewire("./lib/g");
g.__set__("Module", {name: "Module"});
Can anyone suggest a work-around?
Just remove the var keyword.
I have a script foo.js that contains some functions I want to play with in the REPL.
Is there a way to have node execute my script and then jump into a REPL with all the declared globals, like I can with python -i foo.py or ghci foo.hs?
There is still nothing built-in to provide the exact functionality you describe. However, an alternative to using require it to use the .load command within the REPL, like such:
.load foo.js
It loads the file in line by line just as if you had typed it in the REPL. Unlike require this pollutes the REPL history with the commands you loaded. However, it has the advantage of being repeatable because it is not cached like require.
Which is better for you will depend on your use case.
Edit: It has limited applicability because it does not work in strict mode, but three years later I have learned that if your script does not have 'use strict', you can use eval to load your script without polluting the REPL history:
var fs = require('fs');
eval(fs.readFileSync('foo.js').toString())
i always use this command
node -i -e "$(< yourScript.js)"
works exactly as in Python without any packages.
I made Vorpal.js, which handles this problem by turning your node add into an interactive CLI. It supports a REPL extension, which drops you into a REPL within the context of your running app.
var vorpal = require('vorpal')();
var repl = require('vorpal-repl');
vorpal
.delimiter('myapp>')
.use(repl)
.show()
.parse(process.argv);
Then you can run the app and it will drop into a REPL.
$ node myapp.js repl
myapp> repl:
Another way is to define those functions as global.
global.helloWorld = function() { console.log("Hello World"); }
Then preload the file in the REPL as:
node -r ./file.js
Then the function helloWorld can be accessed directly in the REPL.
Here's a bash function version of
George's answer:
noderepl() {
FILE_CONTENTS="$(< $1 )"
node -i -e "$FILE_CONTENTS"
}
If you put this in your ~/.bash_profile you can use it like an alias, i.e.:
noderepl foo.js
I created replpad since I got tired of reloading the script repeatedly.
Simply install it via: npm install -g replpad
Then use it by running: replpad
If you want it to watch all files in the current and all subdirectories and pipe them into the repl when they change do: replpad .
Check out the videos on the site to get a better idea of how it works and learn about some other nice features that it has like these:
access core module docs in the repl via the dox() function that is added to every core function, i.e. fs.readdir.dox()
access user module readmes in the repl via the dox() function that is added to every module installed via npm,
i.e. marked.dox()
access function's highlighted source code, info on where function was defined (file, linenumber) and function
comments and/or jsdocs where possible via the src property that is added to every function, i.e. express.logger.src
scriptie-talkie support (see .talk command)
adds commands and keyboard shortcuts
vim key bindings
key map support
parens matching via match token plugin
appends code entered in repl back to file via keyboard shortcut or .append command
See: https://github.com/thlorenz/replpad
Why not load the file into an interactive node repl?
node -h
-e, --eval script evaluate script
-i, --interactive always enter the REPL even if stdin
node -e 'var client = require("./build/main/index.js"); console.log("Use `client` in repl")' -i
Then you can add to package.json scripts
"repl": "node -e 'var client = require(\"./build/main/index.js\"); console.log(\"Use `client` in repl\")' -i",
tested using node v8.1.2
Currently you can't do that directly, but you can mylib = require('./foo.js') in the REPL. Remember methods are exported, not declared as globals.
replpad is cool, but for a quick and easy way to load a file into node, import its variables and start a repl, you can add the following code to the end of your .js file
if (require.main === module){
(function() {
var _context = require('repl').start({prompt: '$> '}).context;
var scope = require('lexical-scope')(require('fs').readFileSync(__filename));
for (var name in scope.locals[''] )
_context[scope.locals[''][name]] = eval(scope.locals[''][name]);
for (name in scope.globals.exported)
_context[scope.globals.exported[name]] = eval(scope.globals.exported[name]);
})();
}
Now if your file is src.js, running node src.js will start node, load the file, start a REPL, and copy all the objects declared as var at the top level as well as any exported globals.
The if (require.main === module) ensures that this code will not be executed if src.js is included through a require statement. I fact, you can add any code you want to be excuted when you are running src.js standalone for debugging purposes inside the if statement.
Another suggestion that I do not see here: try this little bit of code
#!/usr/bin/env node
'use strict';
const repl = require('repl');
const cli = repl.start({ replMode: repl.REPL_MODE_STRICT });
cli.context.foo = require('./foo'); // injects it into the repl
Then you can simply run this script and it will include foo as a variable
Old answer
type test.js|node -i
Will open the node REPL and type in all lines from test.js into REPL, but for some reason node will quit after file ends
Another problem is, that functions will not be hoisted.
Better answer
node -e require('repl').start({useGlobal:true}); -r ./test2.js
Then all globals declared without var within test2.js will be available in the REPL
not sure why var a in global scope will not be available
There is an Official Node.js REPL that supports also async methods
console.js
const repl = require('repl')
const mongoose = require('mongoose')
const run = async () => {
await mongoose.connect(process.env.DB_URL, {
useNewUrlParser: true,
useUnifiedTopology: true
})
const r = repl.start(`(${process.env.NODE_EN}) ⚡️ `)
r.context.User = require('./src/models/user.model')
r.context.mongoose = mongoose
console.log(`Ready 🚀`);
}
run()
Start the console:
NODE_OPTIONS=--experimental-repl-await node console.js
User model its exposed to console
await User.find({})
source