How can I start an Express app using Now? - node.js

When deploying to Now, I'm trying to build and start an Express server. It's currently building, but not starting the server.
My package.json looks like this, am I missing anything?
"scripts": {
"dev": "node server.js",
"build": "next build && cross-env NODE_ENV=production node server.js",
"start": "cross-env NODE_ENV=production node server.js",
"export": "next build && next export"
}

I have a file called /utilities/app.ts where I setup my common express configuration (this is what I use but you can add/remove things as needed):
import express from 'express';
import helmet from 'helmet';
import { commonMiddlewares } from '../middlewares'
const expressApp = express();
expressApp.use(helmet());
expressApp.set("trust proxy", 1);
expressApp.use(...commonMiddlewares);
export const app = expressApp;
Then in the api endpoint where I want to use express I import this utility:
import { app } from "../utilities/app";
import { Request, Response } from "express";
app.get("*", async (req: Request, res: Response) => { ... })

Related

How do you hot-reload express when tsc recompiles?

I have a simple nodeJS server and I have it set to watch for changes on the code using tsc --watch. What I was wondering is how do I set up express to reload itself when I make changes to the code (note I am asking specifically on Windows)?
I am presuming it is something to do with chokidar in which I have the following index.ts code
import AWS from "aws-sdk";
import express from "express";
import chokidar from "chokidar";
console.log(AWS.S3);
const route = express.Router();
route.get("/signed-url-put-object", async (req, res) => {
console.log(process.env)
});
if (process.env.NODE_ENV !== "production") {
const watcher = chokidar.watch("./index.js");
watcher.on("all", ()=> {
console.log("reloading...");
// what do I do here?
})
}
express().listen(3000, ()=>console.log('listening'))
Try this snippet that I took from this repo.
watcher.on('ready', function() {
watcher.on('all', function() {
console.log("Clearing /server/ module cache from server");
Object.keys(require.cache).forEach(function(id) {
if (/[\/\\]server[\/\\]/.test(id)) delete require.cache[id];
});
});
});
Keep in mind you might run into some issues.
I usually use nodemon and concurrently for my hot reloading needs when both front-end and back-end are in the same repo.
With concurrently and nodemon, I would have something like this.
"scripts": {
"start": "concurrently \"yarn start:fe\" \"yarn start:watch\"",
"start:watch": "nodemon --inspect=5858 ./server/server.ts",
"start:be": "set TS_NODE_PROJECT=./tsconfig.server.json && node --inspect=5858 -r ts-node/register ./server/server.ts",
"start:fe": "react-app-rewired start --scripts-version react-scripts",
}

How to Setup Proxy Target in React Native with Nodejs?

Trying to configure proxy in react native with node to run axios calls.
Tried the following code in server/package.json
"proxy": {
"/*": {
"target": "http://localhost:5000/"
}
},
"scripts": {
"start": "node index.js",
"server": "nodemon index.js",
"client": "cd ../client && yarn ios",
"dev": "concurrently \"yarn server\" \"yarn client\""
}
server/authRouter.js
const authRouter = require('express').Router();
authRouter.get('/test', (req, res) => {
res.send('proxy success');
});
module.exports = authRouter;
server/index.js
const express = require('express');
const authRouter = require('./authRouter');
const app = express();
app.use('/auth', authRouter);
const PORT = process.env.PORT || 5000;
app.listen(PORT);
client/app.js
await axios.get('/auth/test');
When I run yarn dev and test an axios call, it logs the following error
LOG [Error: Network Error]
any help would be much appreciated.
Try calling the proxy directly in axios
http://localhost:5000/auth/test
I'm not sure why it doesn't work that way, even i had a problem in the past.

Using TypeScript and nodemon: SyntaxError: Cannot use import statement outside a module

I am converting the code to use nodemon to leverage TypeScript.
In my package.json:
"scripts": {
"serve-fake-api": "nodemon fake-api/server.ts --watch 'fake-api/*.*' ",
"serve-vue": "vue-cli-service serve",
"serve": "concurrently -k \"npm run serve-fake-api\" \"npm run serve-vue\"",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
and the fake-api/server.ts file:
import { readFileSync } from 'fs';
import { create, defaults, bodyParser, rewriter, router as _router } from 'json-server';
import { join } from 'path';
const server = create();
const defaultMiddleware = defaults();
// It is recommended to use the bodyParser middleware before any other middleware in your application
server.use(bodyParser);
server.use(defaultMiddleware);
// Define custom routes (routes.json)
const routes = JSON.parse(readFileSync(join(__dirname, 'routes.json'), "utf8"));
server.use(rewriter(routes));
// Add custom middleware before JSON Server router
const customMiddleware = require(join(__dirname, 'middleware.ts'));
server.use(customMiddleware);
// This is where `json-server`'s magic happens ;)
const router = _router(join(__dirname, 'db.json'));
// Start the application by listening to port 3000,
// Although this won't print the nice starting message you see when
// running `json-server` as CLI command, it still runs the app correctly.
server.use(router);
server.listen(3000, () => {
console.log('JSON Server is running')
});
but when running npm run serve:
[0] C:\Users\eperret\Desktop\tabulator-tests\fake-api\server.ts:1
[0] import { readFileSync } from 'fs';
[0] ^^^^^^
[0]
[0] SyntaxError: Cannot use import statement outside a module
I googled a bit and ended up here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Is there a workaround to keep using this kind of import?
I answered to my question on the related GitHub issue thread:
https://github.com/remy/nodemon/issues/1625#issuecomment-560115741
I solved my issue by changing the module type with commonjs in tsconfig.json instead of esnext:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
...

i have an issue accessing env variables in NodeJS

Well, i have 3 types of environments (i.e development,test,production) am using nodejs with express. My problem is this my either development and production scripts don't run because they can't access .env variables i have searched online but i can't find something helpful. This is what i did i created .env file and put my variables in. i tried using export command i.e export key=value. please help
I created a .env file and added either of development database url and production database url, but when i run either of environment it doesn't work. i also tried using export command export key=value. but it works for a while and then it fails again.
//my config
require('dotenv').config();
module.exports ={
development :{
use_env_variable: process.env.DEVELOPMENT_URL,
dialect: 'postgres'
},
production :{
use_env_variable:process.env.PRODUCTION_URL,
dialect: 'postgres',
}
}
//my package.json scripts
{
"name": "report_deck",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "export NODE_ENV=production && sequelize db:migrate && node ./build/index.js",
"dev": "nodemon --exec babel-node ./api/index.js",
"test": "export NODE_ENV=test && sequelize db:migrate:undo:all && sequelize db:migrate && nyc --require #babel/register mocha ./api/test/test.js --timeout 20000 --exit",
"build": "rm -rf ./build && babel -d ./build ./api -s",
"generate-lcov": "nyc report --reporter=text-lcov > lcov.info",
"coveralls-coverage": "coveralls < lcov.info",
"codeclimate-coverage": "codeclimate-test-reporter < lcov.info",
"coverage": "nyc npm test && npm run generate-lcov && npm run coveralls-coverage && npm run codeclimate-coverage"
},
}
//.env
DEVELOPMENT_URL=postgres://example1:pass#example:5432/dbname
PRODUCTION_URL=postgres://example2:pass#example:5432/dbname
//my index.js
import express from 'express';
import bodyParser from 'body-parser';
import classRoutes from './server/routes/classRouter';
// all routes
import cors from 'cors';
const app = express();
app.use(bodyParser.json());
app.use(cors());
//use all routes
app.use(bodyParser.urlencoded({ extended: false }));
const port = process.env.PORT || 8003;
app.get('*', (req, res) => res.status(200).send({
message: "Entrance"
}));
app.listen(port, () => {
console.log("Entrance done, We are running at port " + port);
});
export default app;
Expectations:
It should log "entrance done we are running on port 8003" for (npm run dev)
It should log "entrance done we are running on port 5000" for(heroku local web)
Actual:
throw new TypeError('Parameter "url" must be a string, not ' + typeof url);
You should add -r dotenv/config to your starting script to preload dotenv =>
"start": "export NODE_ENV=production && sequelize db:migrate && node -r dotenv/config ./build/index.js",
Check docs

Use newrelic in nuxt

I am trying to add newrelic agent to my nuxt application. I have installed the needed package and added my license key and set an application name in newrelic.js configuration file:
npm i newrelic
cp node_modules/newrelic/newrelic.js .
nano newrelic.js
My problem is that I also need to require this configuration file at the top of my server.js file and since this file is dynamically created and placed under the .nuxt folder I have no idea how to do this.
In a standard nodejs application I would simply add the require('newrelic'); to the top of my startup script or perhaps add a new script entry in package.json looking something like this:
"scripts": {
"dev": "node -r newrelic.js app.js"
}
I ended up using express to solve this:
npm i express
touch server/index.js
We will now load newrelic in the server/index.js file and after that create our nuxt instance:
require('newrelic');
const express = require('express');
const consola = require('consola');
const { Nuxt, Builder } = require('nuxt');
const app = express();
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js');
config.dev = process.env.NODE_ENV !== 'production';
async function start () {
// Init Nuxt.js
const nuxt = new Nuxt(config);
const { host, port } = nuxt.options.server;
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt);
await builder.build();
} else {
await nuxt.ready();
}
// Give nuxt middleware to express
app.use(nuxt.render);
// Listen the server
app.listen(port, host);
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
});
}
start();
I also updated the script section in my package.json:
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js"
}
Hope this can help anyone who faces the same kind of problem.
For anyone struggling with this I found a much simpler solution by using Nuxt modules and hooks.
Create a new file modules/newRelic.js with the following content:
module.exports = function () {
this.nuxt.hook("listen", () => {
require("newrelic");
});
};
Import the module in nuxt.config.js
modules: [
"~/modules/newRelic.js"
]
Don't forget to install newrelic (npm i newrelic) and paste newrelic.js into the applications root folder.
In Node.js, you can require a module with the -r [module] syntax (see Node.js docs) before your actual script starts up.
For Nuxt, alter your npm run scripts like this (instead nuxt start):
node -r newrelic node_modules/nuxt/bin/nuxt.js start
This way, Node loads NewRelic first, then Nuxt, and ensures NewRelic is able to instrument all dependencies. If you let Nuxt bootup first, NewRelic is not aware of some dependencies, e.g. express.
This is recommended by NewRelic, see their docs.

Resources