Use newrelic in nuxt - node.js

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.

Related

Prevent Nodemon to restart some specific code

I'm using nodemon in my nodejs project because I want whenever I made any changes it will restart automatically everything works fine but now problem is I want to use a lib
which include puppeteer lib whenever I made any changes nodemon close the chromium browser and re-open it which take some time. This is making me slow in development. Is there any way I can stop this behaviour.
Here is my code.
const express = require("express");
const app = express();
const http = require("http");
const server = http.createServer(app);
const { Client } = require("whatsapp-web.js");
const client = new Client({ puppeteer: { headless: false } });
client.initialize();
console.log("changes 7");
server.listen(3000, () => {
console.log("listening on *:3000");
});
Whenever I made any changes it restart everything. I don't want to restart the client every time.
I don't know about nodemon, but if you can edit the library, you can re-use an existent browser.
Try, from node shell:
(await require('puppeteer').launch()).wsEndpoint()
this return a connection string that you can reuse.
And, then, you can connect with the created instace with connect api
Edit: your library allows ws socket! :-)
const client = new Client({
puppeteer: {
browserWSEndpoint: `ws://localhost:3000`
}
});
create nodemon.json in your project directory
nodemon will automatically look for this file and use it if exist
and write in nodemon.json
{
//list of directory you want to watch
"watch": ["./","server","someOtherDir"],
"ext": "js,ts,json", //file extension to watch
"ignore": ["ignoreThisDir","someDir/*.js"], //specify files or directory to ignore
// specify entry of the project
"exec" : "node app.js"
//another example for exec "exec": "ts-node --project tsconfig.server.json server/app.ts"
}

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 properly configure Next.js as a frontend and Express app as a backend?

Currently I have create-react-app for frontend and express server for backend. In package.json of my create-react-app I use proxy like this "proxy": "http://localhost:5000".
I need to achive the same thing for Next.js app with the same express server.
I just want to be able to use my express server instead of API routes built in Next.js and proxy it like I do in create-react-app.
Do I need to create custom Next.js server even though i'm not changing any of it's functionality? How to do this properly?
yes you have to add custom server in next js
install express js then add file server.js in root directory of next js project
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.use(bodyParser.json())
// add custom path here
// server.post('/request/custom', custom);
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('Ready on http://localhost:5000')
})
})
after that change package.json file script section
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js",
}

Handling absolute urls in nodejs server

this is my firs project with electron and nodejs
I need to load a specific folder in my electron application
the final structure should be like:
Myapp.app
folder-contents
MyApp must read contents from folder-contents directory
import httpServer from './server'
function createMainWindow() {
const window = new BrowserWindow()
if (isDevelopment) {
window.webContents.openDevTools()
}
window.loadURL(`http://localhost:18081/${app.getAppPath()}/folder-contents/`)
}
in server.js
const path = require("path");
const http = require('http');
const express = require('express');
const PORT = 18081;
const app = express();
app.use(express.static(process.cwd()));
app.set('port', PORT);
const server = http.createServer(app);
server.listen(PORT, "127.0.0.1");
module.exports = app;
In my package.json
"scripts": {
"dev": "electron-webpack dev",
"compile": "electron-webpack",
"dist": "yarn compile && electron-builder",
"dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null",
"start": "electron ."
},
launching npm run dist --mac and open myapp.app i get this error
Cannot GET /folder-contents/
any idea?
you can add your files to a folder name public and inside that you can have all your static files stored and then you need to call it in your app.js like:
app.use(express.static('public') //Public is the name of the folder and then you might be able to use all of your static files presented in that folder in your project if this didn't clear you here's a refrence if i am wrong and you get the correct answer else where please correct me.Thank you.
This is an express documentation

Using Koa2 with Babel in Node

I know I'm missing something here. I'm running node through babel and using koa2 on my server. Fairly new to this so not quite sure what I'm missing, as I've been referencing a lot of things online.
Versions: Node 6.4, babel-core 6.14.0, babel-polyfill": 6.13.0
Getting a fun error. Looks like a generator is not being produced somehow.
assert.js:89
throw new assert.AssertionError({
^
AssertionError: app.use() requires a generator function
at Application.app.use (/Users/administrator/Dropbox/Development/moonlite/moonlitewww/node_modules/koa/lib/application.js:106:5)
Here's what I'm running off of:
Package.json
"start:dev": "node -r babel-core/register index.js",
.Babelrc
{
"presets": ["es2015", "react", "stage-3"]
}
Index.js
require("babel-polyfill");
import nodeServer from "./web-server.js";
var config = {
prod: process.env.NODE_ENV === "production",
serverPort: process.env.PORT || 3000
};
nodeServer(config);
web-server.js
import Koa from 'koa';
import koaRouter from 'koa-router';
import send from 'koa-send';
import serve from 'koa-serve';
import logger from 'koa-logger';
const router = koaRouter();
const app = new Koa();
export default (config) => {
app.use(logger());
app.use(serve(__dirname + '/client/build'));
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(config.serverPort, () => {
console.log('Server running on port:' + config.serverPort);
});
};
What am I missing here?
Noob mistake on my part. I was merging the packages from another package.json file in, and somehow koa got reverted back to the 1.x branch. Was chasing a red haring thinking it was babel.
If you see a similar error double check your koa version, and upgrade to koa2 like so:
npm install koa#next --save
"NOW YOU KNOW, AND KNOWING IS HALF THE BATTLE..."

Resources