Easy ways to quit and restart an entire script? - javascript

I have a Discord bot that I'm writing a restart function for. I want to be able to run one command that will not only stop the script, but kill and restart it, so I can implement updates quickly. I've realized that the Discord API is not sufficient for this so I haven't added it to the tags. The simplest way I can think of is by using two scripts that call each other.
Every resource I've found references either a module (?) called PM2 or a programming language called VBScript. I do not want to mess around with a module that automatically reboots every single time I save, and I especially don't want to try learning a new language.
Here is my pseudocode showing what I'm aiming for:
[bot.js]
function reboot() {
runFile(`./reboot.js`)
}
[reboot.js]
kill (`./bot.js`)
runFile(`./bot.js`)
The result I'm hoping for is for bot.js to run reboot.js. Reboot.js will then quit bot.js and run it again. Then reboot.js will close. I don't care about any processes already running on bot.js.
Of course, if there are even simpler ways to do this, please let me know. I need as much simplicity as I can get.

PM2 is a process manager and would do the trick for you.
It's easily installed: npm install pm2 -g
Start your bot: pm2 start bot.js --name "Discord Bot"
Code-wise, you'll want to simply kill the process. PM2, being a process manager, will restart it for you.

I've figured it out. I used the child-process module built into node.js.
[bot.js]
var cp = require('child_process');
function reboot() {
var ls = cp.spawn('node', ['reboot.js']);
client.destroy()
}
[full contents of reboot.js]
var cp = require('child_process');
var ls = cp.spawn('node', ['bot.js']);
(posting all this for fellow noobs to use)
Edit: Note that after restarting, console outputs no longer work, as it's running from reboot.js rather than directly from the terminal.

I'm not familiar with Discord bots, but if you want to start, kill and restart processes programmatically in NodeJS then you want to look into the child_process module.
https://nodejs.org/api/child_process.html#child_process_child_process

Related

Is there a way to find out in which terminal a Node.js process is being run in?

I want to know in my code what kind of terminal the process is being run in (CMD, PowerShell, Bash, ...)
Is there some cross-platform way to display some info about the current terminal or an npm module I can use?
I've searched for a while now but can't seem to find anything on this.
process.env.SHELL is the closest I could find.
It's '/usr/local/bin/zsh' in my case (Homebrew zsh on macOS).
I have no Windows at hand to compare the results.
May be unreliable, if I start bash from my zsh, or when I start PowerShell.app, I still get '/usr/local/bin/zsh'...

How to run multiple js servers

I'm developing a discord bot for discord at the moment, and to run the bot, I have a few different files. I've run into some problems along the way that all ended up having the same fix, or at least the only fix that I could come up with. That fix would be, instead of running them in my main file (index.js), I could just run 3 separate batch files using nodemon (https://www.npmjs.com/package/nodemon). I currently have 3 batch files to do so. Those batch files look like this:
nodemon index.js
pause
This would be for the main file.
nodemon logs.js
pause
This would be for the file that logs messages.
nodemon welcome and goodbye.js
pause
And this would be for the welcome and goodbye logs.
The only issue is, is that it clutters up my desktop with 3 different prompts, making it confusing as to what does what. I was wondering if it'd be possible with nodemon (or any other npm like this) for me to run all 3 of those batch files in one single command prompt.
And of course I'm open to other npms, but if I'd have to use another one, please include a way for it to automatically restart the server when I save the file in it as well (if possible). Since that's the main reason I like nodemon. I'd also like to be able to use a command prompt/batch file rather than the Visual Studio Code terminal.
If you're wondering what I mean when I say, "...automatically restart the server when I save the file," . (https://imgur.com/a/rw2Qagp if it doesn't show, don't know how to format this stuff)
Whenever I save my code in Visual Studio it will restart and load the new code.
I'm still a little new to coding and stuff like that, so if my terminology is off I do apologize. If I did use a term incorrectly and you are confused/have a question about it, leave a comment and I will do my best too explain what I mean.
Thank you for taking time to read this.
You can use concurrently or parallel in order to make it cross platform
example with concurrently:
package.json
{
"scripts": {
"serve": "nodemon index.js",
"logs": "nodemon logs.js",
"start": "concurrently \"npm:serve\" \"npm:logs\""
},
"devDependencies": {
"concurrently": "^5.0.0",
}
}
Edit: you may want to take a look at the VSCode Compound tasks
Here's an example setup
Welcome :-)
I think you mean bash file (.sh) instead of batch file. So, in the terminal, you can && commands to chain them together.
For example, you could chain them together like this:
nodemon ./appOne/index.js && nodemon ./appTwo/index.js && nodemon welcome and goodbye.js
and they will all execute at one time. Additionally, you could make a bash file somewhere on your computer that did exactly what I typed above :-)
Now if you wanted them to go to the background and you wanted to forget about them, you could put them in the background with one ampersand... like so:
nodemon index.js &
and it would disappear and you'd have your console back. It would also print out a process ID (PID) of what that node process is under, so you can find it and kill it later (via kill -9 processid)

How to debug/inspect hexo blog

I'd like to start a Nodejs debugger for my Hexo blog to understand how my theme works and possibly find a bug.
I needed 2 things to achieve this:
Install hexo-cli as a dev dependency rather than global. I used npm i hexo-cli --save-dev.
In package.json, under scripts, add a script called debug. I used this command: node --inspect=4300 ./node_modules/hexo-cli/bin/hexo server.
Then just use npm run debug and you're good to connect with a debugger to port 4300 (or whatever port you want to set in your command) and do line-to-line debugging etc.
One caveat is that with the --inspect setting, for some reason hexo is starting extremely slow (takes more than 2 minutes). I wonder what causes this.
Also, I haven't found a way to start hexo in a way that it generates pages dynamically. It would help with real time debugging.

Run code once for a single version of a Node.js based CLI

I have written a CLI in Node.js, that you can globally install using npm. Now I want to run a specific piece of code the first time a user runs my CLI. But it should only run once.
My question is: How could I detect that the CLI is run for the very first time?
Of course, I could write a file into the user's home directory, and if it exists, skip code execution. This would be pretty simple.
But now things get slightly more complicated: I want this check to be re-run when the user updates the CLI to a new version. So, again, I could write a file into the user's home directory, and store the versions in it, for which I have run the "once"-code block.
But this again means that every time the user runs the CLI it has to open the file, parse it, look for the version, and so on. I fear that this could negatively impact startup performance.
Is there a better way to solve this?
I have a stupid idea, treat this as an academic example of hacky metaprogramming. Create a script named script.js:
var fs = require('fs');
if(!process.env.firstRun){
var content = fs.readFileSync("script.js", "utf8");
fs.writeFileSync('script.js', 'process.env.firstRun=true;\r\n' + content, 'utf8');
console.log('first run');
} else {
console.log('next run');
}
The script simply overwrites itself by adding an additional flag declaration at the beginning if it's not set. Otherwise it goes the other path:
λ node .\script.js
first run
λ node .\script.js
next run
λ node .\script.js
next run
The above was just for fun. For production code you should go for a configuration file as you proposed. Reading single small file is not a big deal, according to this method it takes <0.5ms in my setup (I5 processor, SSD drive), so it's definitely a way to go.

How can I use a javascript library on the server side of a NodeJS app when it was designed to run on the client?

I'm diving into NodeJS and Express (it's sooo complicated to me) to build a real-time web app. At the moment, I'm trying to understand how I can use an existing javascript library on the server side. The problem is the library appears to be designed to run on the client side and, as a result, the instructions only show you how to use it on the client side. The library I'm talking about can be found here...
https://github.com/replit/jsrepl
Questions:
Since a NodeJS web app is built on javascript, is it fair to say I can run any non-gui javascript library on the server side?
Can anyone offer some guidance on how I can add that jsrepl library to my Express 3.0 app in a way that allows me to use it in the same way that I would use it on the client side in a browser? Do I have to modify the jsrepl code and add "exports." to the methods I want to use?
Meaning, on the server side, I can execute the following code...
var jsrepl = new JSREPL({
input: inputCallback,
output: outputCallback,
result: resultCallback,
error: errorCallback,
progress: progressCallback,
timeout: {
time: 30000,
callback: timeoutCallback
}
});
Thanks in advance for all your wisdom! I'm doing my best to understand all this.
So this is possible, but you need some serious hackery in order to get it working. Since this is not a node module and is written from the browser as others have noted, you need a DOM within node to execute it into. Luckily, we have the wonderful jsdom project which allows us to do just that. So let's get this thing set up.
cd into your node project (create one if there isn't one already)
clone down the jsrepl repo git clone git://github.com/replit/jsrepl.git
cd into jsrepl and initialize submodules git submodule update --init --recursive
still in the folder, run npm install coffee-script and npm install uglify-js, dependencies that are not mentioned anywhere in the repo (ugh).
make sure java is installed and run cake bake. After a lengthy process of compiling java files and such the command will finish and jsrepl will be built and ready to go.
run npm install jsdom, then we can start writing an example file
Here's a minimal example:
var jsdom = require('jsdom'),
fs = require('fs'),
jsrepl = fs.readFileSync('./jsrepl/repl.js', 'utf8');
jsdom.env({
html: "<script src='jsrepl.js' id='jsrepl-script'></script> ",
src: [jsrepl],
done: function(err, window){
if (err) return console.error(err);
run_jsrepl.call(window);
}
});
function run_jsrepl(){
console.log(this.JSREPL)
}
Here's the minimum amount of code required to get JSREPL into a place where it's working. All we're doing here is requiring jsdom and instantiating it, reading in the jsrepl source straight from the file. If you run this file with node filename it will log out your JSREPL object, which can be used just like it's in the browser : )
You can run phantomjs in Node, which is a headless webkit browser. Then run jsrepl inside of phantomjs.
No. There are things on the client side that you don't have on the server side (and vice-versa): for instance, the DOM.
I've never worked with jsrepl myself, but assuming that it's platform-agnostic, require()ing it from a node module should be OK. However, there seem to be some DOM-specific things in the scripts in question (e.g. document.getElementById) that suggest otherwise.

Categories

Resources