Nodemon keeps restarting server - javascript

I have an express server that uses a local json file for a database. I'm using https://github.com/typicode/lowdb for getters and setters.
Currently the server keeps starting and restarting without any problems, but can't access it. Below is my Server.js file:
import express from 'express'
import session from 'express-session'
import bodyParser from 'body-parser'
import promisify from 'es6-promisify'
import cors from 'cors'
import low from 'lowdb'
import fileAsync from 'lowdb/lib/storages/file-async'
import defaultdb from './models/Pages'
import routes from './routes/index.js'
const app = express();
const db = low('./core/db/index.json', { storage: fileAsync })
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/', routes);
app.set('port', process.env.PORT || 1337);
db.defaults(defaultdb).write().then(() => {
const server = app.listen(app.get('port'), () => {
console.log(`Express running → PORT ${server.address().port}`);
});
});
Anyone have an issue like this before? I think it has something to do with this line:
db.defaults(defaultdb).write().then(() => {
const server = app.listen(app.get('port'), () => {
console.log(`Express running → PORT ${server.address().port}`);
});
});

From the documentation:
nodemon will watch the files in the directory in which nodemon was started, and if any files change, nodemon will automatically restart your node application.
If your db's .JSON file is under the watch of nodemon, and you're constantly writing to it, your server will restart in an infinite loop thus making it inaccessible. Try moving your .JSON file outside the scope of nodemon's watch via moving it outside your directory or via some nodemon configuration (if possible).

I solved this issue from this page.
practically you just have to do
nodemon --ignore 'logs/*'
Update: the link was hijacked and has been removed.

My solution: I've added nodemonConfig in package.json file in order to stop infinite loop/restarting. In package.json:
"nodemonConfig": { "ext": "js", "ignore": ["*.test.ts", "db/*"], "delay": "2" },
"scripts": { "start": "nodemon" }

I was puzzled by a constant stream of restarts. I started with nodemon --verbose to see what was causing the restarts.
This revealed that my package.json file was the culprit. I was running my installation in a Dropbbox folder and had just removed all files from my node_modules folder and done a fresh install. Another computer that shared my Dropbox folder was running at the time, and unknown to me, it was busily updating its node_module files and updating the Dropbox copy of package.json files as it did so.
My solution turned out to be simple, I took a break and waited for Dropbox to finish indexing the node_modules folder. When Dropbox finished synching, nodemon ran without any unexpected restarts.

In my case (which is the same as the OP) just ignoring the database file worked
nodemon --ignore server/db.json server/server.js

You can use this generalized config file.
Name it nodemon.json and put in the root folder of your project.
{
"restartable": "rs",
"ignore": [".git", "node_modules/", "dist/", "coverage/"],
"watch": ["src/"],
"execMap": {
"ts": "node -r ts-node/register"
},
"env": {
"NODE_ENV": "development"
},
"ext": "js,json,ts"
}

I solved this by adding the following code to the package.json file
"nodemonConfig": {
"ext": "js",
"ignore": [
"*.test.ts",
"db/*"
],
"delay": "2"
}
}

Add this in your package.json:
"nodemonConfig": {
"ext": "js",
"ignore": [
"*.test.ts",
"db/*"
],
"delay": "2"
}

I solved this by creating a script in my package.json like this:
scripts": {
"start-continuous": "supervisor server/server.js",
},
This will work if you have supervisor installed in your global scope.
npm install supervisor -g
Now all I do is: npm run start-continuous

Related

Unable to transpile ES6 express server using Parceljs in development mode

I am trying to transpile an ES6 express app using Parceljs.
Trying to run the parcel dev server using yarn parcel index.js displays that it is running at localhost:1234 but the page is blank. It also generates the following output when trying to run node dist/index.js:
index.js:116
throw error;
^
TypeError: Cannot read properties of undefined (reading 'prototype')
Running yarn parcel index.js --target node does not yield any localhost port for me to test the API with. However, the API now works as I can use node dist/index.js to run the script but now I have to resort to npx nodemon /dist/index.js to have file watching.
Here is the sample code.
index.js
import express from "express";
const app = express();
const port = 5000;
app.get("/", (req, res) => {
res.json({ msg: "Hello!" });
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
package.json
...
"dependencies": {
"express": "^4.17.3",
"parcel": "^2.3.2",
"parcel-bundler": "^1.12.5"
}
...
I would greatly appreciate a solution that allows me to use Parceljs to watch for file updates directly, preferably with HMR.
See issue 355: Is parcel meant to work with server-side code insluding HMR?: parcel does not (yet) support hot module reloading in nodejs.
parcel creates a web server and serve your code but express need to be called by itself to be able create a web server and server requests.
You'd better use babel & nodemon instead of parcel
I use command bellow
nodemon --exec babel-node src/index.js

Azure App Service - Nodejs ES Module Error

Trying to host a simple nodejs api server on azure app service, but getting the following error when azure tries to deploy it
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: D:\home\site\wwwroot\server.js
require() of ES modules is not supported.
require() of D:\home\site\wwwroot\server.js from D:\Program Files (x86)\iisnode\interceptor.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename server.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from D:\home\site\wwwroot\package.json.
Checked the azure app service, WEBSITE_NODE_DEFAULT_VERSION is set to ~14, and the installed nodejs version is v14.15.0 in the web app. Don't think this version of node has problem with import export anymore.
The code runs perfectly fine locally with either
node server.js
# or
node --experimental-modules server
Not sure why it is failing in azure
My code is below:
server.js
import express from 'express';
import bodyParser from 'body-parser';
let app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
let port = process.env.PORT || 8080;
let router = express.Router();
// Middleware to use for all requests
router.use(function(req, res, next) {
next();
});
router.get('/', function(req, res) {
res.json({ message: 'Default home page for the api!' });
});
app.use('/api', router);
// START THE SERVER
// =============================================================================
app.listen(port);
console.log(`Server up and running on port ${port}`);
package.json
{
"name": "my_package",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node --experimental-modules server",
"test": "mocha"
},
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1"
}
}
However, if I change the import & export to require, then it will run in azure web app, it seems like perhaps azure iisnode is not compatible with emac6 yet? Anyone knows?
Anyone has any work around of this beside using babel to transpile emac6 down to emac5? As I have having some problem with executing and running the transpiled emac5 code.
Thankz
This can be solved by adding a new file next to your server.js and configuring it as the app service's (or more specifically iisnode's) entry point (see your web.config).
Let's call the new file run.cjs and put only the following line into it:
import("./server.js");
The cjs file extension is important because it tells Node that this file is not a ES module, as it would expect because of "type": "module" in your package.json. This allows other CommonJS files to include our new file - namely iisnode's interceptor.js.
It again imports the server.js which then runs fine as ES module.
Add "type": "module" in package.json file. It work for me.
{
"name": "module-error",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node --experimental-modules server",
"test": "mocha"
},
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1"
},
"author": "",
"license": "ISC",
"type": "module"
}

Configure local php endpoint for Axios in Nuxt JS

I want to use Axios to make client AJAX calls that point to a local PHP file. Why PHP? I have tons of security-tested approaches in a simple PHP-based API that work great and don't need re-inventing.
I'm guessing I'm missing something easy, but so far I've had a wonky/hacky approach that works. Right now, I've got a PHP file in the /static folder, and in nuxt.config.js I have a proxy setup:
... other config stuff
axios: {
proxy: true
},
proxy: {
'/api': 'http://some-site.local/api.php'
}
... other config stuff
In order for the url above to resolve, I have a host entry setup via MAMP that resolves http://some-site.local to the /static directory in my Nuxt project.
So far, it works. But, it requires setting up MAMP to have the hosts entry, and when it comes to npm run build, this approach fails, because the build will take the PHP files from the /static and put them the the docroot of /dist, but that breaks the API proxy setup for Axios in nuxt.config.js.
I really don't want to install some PHP package (I've seen that Laravel has one that works with Nuxt), because the aim is just to be able to have a couple PHP files within my Nuxt project instead of a full library. Anyone have any insight on what I'm missing to make this work better?
For NUXT and PHP all in one project (small project)
Lets say there is already Node and PHP-CLI installed.
Create NUXT project:
npx create-nuxt-app my-app
Create file static/api/index.php (lets say):
<?php
header('Content-type: application/json; charset=utf-8');
$rawPaylaod = file_get_contents('php://input');
try {
$payload = json_decode($rawPaylaod, true);
} catch (Exception $e) {
die(json_encode(['error' => 'Payload problem.']));
}
echo json_encode([
'echo' => $payload,
]);
Install dependencies
npm i -D concurrently
npm i #nuxtjs/axios #nuxtjs/proxy
Update config.nuxt.js:
module.exports = {
...
modules: [
...
'#nuxtjs/axios',
'#nuxtjs/proxy',
],
...
proxy: {
'/api': {
target: 'http://localhost:8000',
pathRewrite: {
'^/api' : '/'
}
},
},
axios: {
baseURL: '/',
},
}
Update package.json:
"dev": "concurrently -k \"cross-env NODE_ENV=development nodemon server/index.js --watch server\" \"php -S 0.0.0.0:8000 static/api/index.php\"",
And it's ready.
Now locally in development API will be available thanks to proxy and after deployment just under path.

Why can't I see my test text on the front page of my original React web app?

As of now, my React app runs on port 3000 via npm start.
I've decided that I want to use MySQL for the web app I'm building via yarn add express mysql.
I made server.js listen in on port 3001.
Whenever I run nodemon server.js and then hit refresh, I'm not seeing test on the front page of my React app (which would indicate that everything works fine).
I can see test if I type localhost: 3001 in my browser but it's completely blank, meaning, I only see test and not the original front page of my web app. It's a whole new different page.
Inside package.json file, I tried to include "proxy":"http://localhost:3001" at the bottom of the file as well as various other places, but it still doesn't work.
How do I make it so that I can see test on the original front page of my web app (port 3000) so I can conclude that everything's working fine and can proceed with integrating MySQL?
Here's my server.js file:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.get('/', (req, res) => {
res.send('test');
});
app.listen(3001, () => {
console.log("listening port 3001");
});
Update
If you don't need to build and try your app in production, meaning you only need to run both of them for development then just use a proxy as suggested in the comments. Run both servers and make requests to your Express API routes on the frontend. You can add a proxy like this in your client's (React part) package.json file.
"proxy": {
"/api/*": {
"target": "http://localhost:3001"
}
}
Then, any request made for /api/* on the frontend goes through your Express server.
For starting both servers at the same time, you can use concurrently. First install it on the server side:
yarn add concurrently
After installing it you add something like this in your scripts part:
"scripts": {
"server": "nodemon index.js",
"client": "npm run start --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"prod": "NODE_ENV=production nodemon app.js"
},
I misunderstood your intention at first, this is why I gave an answer like the below one.
This is normal behavior since you haven't configured Express to serve your frontend properly.
First of all, for a React app you don't need any server at all. What you are using right now (on port 3000) is for developing purposes. So, after completing your app you should build it and configure Express to serve it statically.
First, build it:
yarn build
After this step, you will have static files in your client's build directory.
Now, your Express config should be something like this:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());
app.get('/test', (req, res) => {
res.send('test');
});
app.use( express.static( "client/build" ) );
app.get( "*", ( req, res ) =>
res.sendFile( path.resolve( __dirname, "client", "build", "index.html" ) ) );
app.listen(3001, () => {
console.log("listening port 3001");
});
Notice the route change for Express. I changed / with /test. So, when you hit /test you will see what your Express route serves. Other than this route you should see your React app.
Also, don't forget to change those if your setup is different:
client/build
and
path.resolve( __dirname, "client", "build", "index.html" )
This means Express searches a client directory and you React app resides there.
PS: You will only start the Express server, there will be no more server for React since you don't need it to serve with Express.
Also, related part can be enhanced like this:
if ( process.env.NODE_ENV === "production" ) {
app.use( express.static( "client/build" ) );
app.get( "*", ( req, res ) =>
res.sendFile( path.resolve( __dirname, "client", "build", "index.html" ) ) );
}
So, at runtime you can pass an environment variable and Express hits this route only in production.

express' response.sendFile() sends Uncaught SyntaxError: Unexpected token <

I'm using react-router with browserHistory. This function:
app.get('*', function (request, response){
response.sendFile(path.join(__dirname + "/public/index.html"))
})
is supposed to send the Index.html since the routing happens client-side with react-router.
But somehow my index.html is misunderstood by the server and I get this error:
Uncaught SyntaxError: Unexpected token <
I don't know what the problem here is. Is the file path wrong? My tree looks like this:
/app
/app/myJavascriptStuff.js
/public
/public/index.html
/moreStuffThatsNotRelevant
/server.js <- my express file
without the above described function my page usually responds with:
Cannot GET /whatever
on every page refresh that doesn't happen on localhost:3000 (e.g. localhost:3000/whatever)
Because I'm aware that i suck at describing things, here is a link to the repository.
Help is very appreciated. :)
Problem can be because for each request you are sending index.html even when browser asks for your bundle.js or style.css via
app.get('*', function (request, response){
response.sendFile(path.join(__dirname + "/public/index.html"))
});
Define a public folder from where these files can be served let say public(where you have your index.html in your github repo). Let webpack to generate the bundle.js in that folder. Also point in your index.html to use bundle.js from that folder.
Next in your server.js you need to do some changes. Let express to use public path for serving these files when asked by browser.
An example can be -
const app = express();
const publicPath = express.static(path.join(__dirname, 'public'), { redirect : false });
const indexPath = path.join(__dirname, 'public/index.html');
app.use(publicPath);
app.get('/', function (_, res) { res.sendFile(indexPath) });
app.get('*', function (_, res) { res.sendFile(indexPath) });
First of all you did not build your bundle.js file with your webpack. Before you can serve it you need to build it first.
Change you package.json script to
"scripts": {
"build": "webpack --progress --color --config webpack.config.js --watch",
"start": "node server.js"
}
and run the command npm run build before running your server.
If you webpack bundle.js doesn't get created inside /public/build then create a directory build inside public and run the above command again.
This should solve your problem.

Categories

Resources