Neutrino and Express Preset - express

I'm using Neutrino as scaffolding tool for Webpack 3.1 and I'm looking for a proper Neutrino preset that combines Express and Webpack so that I see a 'Hello World' website. If someone gives me one proper preset and tells me how to install it, I'll accept this as an answer.
Thank you!

This should already be possible with the #neutrinojs/node preset:
// src/index.js
import express from 'express';
import { join } from 'path';
const port = process.env.PORT || 3000;
const app = express();
app.get('/', (request, response) => {
response.sendFile(join(__dirname, 'index.html'));
});
app.listen(port, () => console.log(`Server running on port ${port}`));

Related

Access privateRuntimeConfig in express server

I've installed the express-nuxt template and I was wondering how could I get access to the privateRuntimeConfig inside nuxt.config.js from express (API folder). One approach I thought about was to put the vars inside a .env file and then installing the dotenv package for the express server, but I think that using just Nuxt could be better.
We have done precisely this by importing the Nuxt config into the file that configures the Express app, and using defu to combine public and private runtime configs, as Nuxt itself does:
// nuxt.config.js
export default {
publicRuntimeConfig: {},
privateRuntimeConfig: { redis: { url: process.env['REDIS_URL'] } }
};
// api/index.js
import express from 'express';
import defu from 'defu';
import { createClient as createRedisClient } from 'redis';
const app = express();
import nuxtConfig from '../nuxt.config.js';
let runtimeConfig;
app.use((req, res, next) => {
if (!runtimeConfig) {
// Load Nuxt config once, at runtime
runtimeConfig = defu(nuxtConfig.privateRuntimeConfig, nuxtConfig.publicRuntimeConfig);
}
next();
});
// Subsequent middlewares will then be able to read from `runtimeConfig`
app.use((req, res, next) => {
const redisClient = createRedisClient({ url: runtimeConfig.redis.url });
next();
});
export default app;

TypeError: bodyParser.json is not a function in nuxt.js

I have received an error message stating: TypeError: bodyParser.json is not a function. My nuxt.config.js file has the following details regarding bodyparser (I originally had const bodyParser = require('body-parser') but an error appeared telling me that I had to use 'import' instead of 'require' so I changed it to 'import('body-parser'):
const bodyParser = import('body-parser')
export default {
serverMiddleware: [
bodyParser.json(),
'~/api'
]
}
In my index.js file under the api folder, I have the following code:
const express = require('express')
const bodyParser = require('body-parser')
const router = express.Router()
const app = express()
router.use((req, res, next) => {
Object.setPrototypeOf(req, app.request)
Object.setPrototypeOf(res, app.response)
req.res = res
res.req = req
next()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
})
router.post('/track-data', (req, res) => {
console.log('Stored data!', req.body.data)
res.status(200).json({ message: 'Success!' })
})
module.exports = {
path: '/api',
handler: router
}
Does anyone know how to get this to run? Everytime I enter 'npm run dev' in the terminal, I get the error 'TypeError: bodyParser.json is not a function'.
I had a slightly similar issue and could solve it with this code, first i imported express in the config file, before i did it like you, with bodyParser, but got a deprecated warning, then i use it in the api folder, in the index file, like so:
// nuxt.config.js
import express from 'express';
export default {
ssr: true,
.......,
.......,
serverMiddleware: [
express.json(),
// Api middleware
{ path: '/api', handler: '~/api/index.js' },
]
}
// ~/api/index.js
// Router setup for serverMiddleware
router.use((req, res, next) => {
Object.setPrototypeOf(req, app.request);
Object.setPrototypeOf(res, app.response);
req.res = res;
res.req = req;
next();
});
export default {
path: '/api',
handler: router
};
hope it helps ! 👍
I'm not familiar with nuxtjs specifically, but after looking at the nuxtjs module export docs it looks like your require inside your index.js should be a path to the file, rather than just the string body-parser which I have to imagine just gets processed something like an npm module if no path is supplied.
Additionally, at least in NodeJS and per the MDN docs on export and import, the syntax to import something that's exported with export default is import { destructuredModuleName } from 'string/representing/relative/or/absolute/path/to/module'
or
import * as whatYouWantToCallTheObject from 'string/representing/relative/or/absolute/path/to/module' would give you a more traditional module object with properties/methods matching properties on the exported module.
This should fix it:
import bodyParser from 'body-parser'
You actually used the import() as a dynamic import. It returned a promise which didn't have the json property. Therefore, the error was displayed.

error hanlders not working properly in express together with nuxtjs

I am using Nuxtjs as a middleware in expressjs, and I have problems with handling errors in express server part.
When browser goes to 'localhost:3000', it will throw res.status is not a function error. when I comment that code block, everything is good expect that I cannot handle with uncaught server errors...
Any ideas?
import dotenv from 'dotenv'
dotenv.config({ silent: process.env.NODE_ENV === 'production', path: 'server/.env' })
import express from 'express'
import { ready } from 'consola'
import { Nuxt, Builder } from 'nuxt'
import cors from 'cors'
import { json, urlencoded } from 'body-parser'
import cookieParser from 'cookie-parser'
import passport from 'passport'
import './utils/auth'
import router from './routes'
const app = express()
app.use(json({ limit: '50mb' }))
app.use(urlencoded({ limit: '50mb', extended: true }))
app.use(cookieParser())
app.use(cors())
app.use(passport.initialize())
app.use('/api', router)
app.use('/api/*', (req, res) => {
res.status(404).end()
})
// error handlers
// it is problematic
// app.use((err, req, res) => {
// res.status(err.status || 500).end()
// })
let config = require('../nuxt.config.js')
config.dev = !(process.env.NODE_ENV === 'production')
async function start() {
const nuxt = new Nuxt(config)
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
app.use(nuxt.render)
const host = process.env.HOST || '127.0.0.1'
const port = process.env.PORT || 3000
app.set('port', port)
app.listen(port, host)
ready({
message: `Server listening on http://${host}:${port}`,
badge: true,
})
}
start()
Without testing this code myself, I had a similar issue with my custom error handler and realized at one point I removed the next argument and it was failing. Can't say it will fix the issue because you are getting an error about res. I read through this page a few times and noticed a few mistakes I was making because I was using async functions.
Error Handling Guide may provide some help if you look over it carefully, but more specifically my comment about next is found under the title Writing error handlers
I wanted to say it might be arrow functions, but I don't see why that would break the logic here.

How to run Gun server with Hapi?

I follow this tutorial to create Gun server. But I need to do it with Hapi.
Now, I get the following error:
> node server.js
Hello wonderful person! :) Thanks for using GUN, feel free to ask for help on https://gitter.im/amark/gun and ask StackOverflow questions tagged with 'gun'!
0.8 WARNING! Breaking changes, test that your app works before upgrading! The adapter interface has been upgraded (non-default storage and transport layers probably won't work). Also, `.path()` and `.not()` are outside core and now in 'lib/'.
WARNING! This `file.js` module for gun is intended for local development testing only!
/home/trex/dev/learn/gun/server/server.js:17
gun.wsp(server);
^
TypeError: gun.wsp is not a function
at Object.<anonymous> (/home/trex/dev/learn/gun/server/server.js:17:5)
Server source code:
const Hapi = require('hapi');
const Gun = require('gun');
const gun = new Gun();
const server = new Hapi.Server();
server.connection({ port: 3000, host: 'localhost' });
server.ext('onRequest', () => gun.wsp.server);
gun.wsp(server);
server.start((err) => {
if (err) {
throw err;
}
console.log(`Server running at: ${server.info.uri}`);
});
What is wrong here?
The bug solved in gun 0.8.8 https://github.com/amark/gun/pull/423
const Hapi = require('hapi');
const Inert = require('inert');
const Gun = require('../gun/');
const server = new Hapi.Server;
server.connection({ port: 8080 });
server.connections.forEach(c => Gun({ web: c.listener, file: 'data.json' }));
server.register(Inert, () => {});
server.route({
method: 'GET',
path: '/{param*}',
handler: {
directory: {
path: __dirname,
redirectToSlash: true,
index: true
}
}
});
server.start();

Is there a way to bootstrap an Express app?

I'm building an app in Express but I'd like it to call out to S3 to retrieve some keys before the server actually starts up. Is this possible in Express? If I google bootstrap Express I get hits for setting up Express with twitter Bootstrap.
I have used Sails.js before and you could specify bootstrap configurations in a bootstrap.js file so I guess I'm looking for something similar. Otherwise are there alternatives?
I have a index.js file and a separate bin/www file which calls the index.js file. I'd like the bootstrapping done in index.js so that it's included as part of the tests. Right now I 'initialize' the bootstrap but as it's asynchronous the server is already up and running before the bootstrap has complete (or errored out) i.e.
import express from 'express';
import {initializeFromS3} from './services/initializerService';
import healthCheckRouter from './routes/healthCheckRouter';
import bodyParser from 'body-parser';
initializeFromS3(); // Calls out to S3 and does some bootstrapping of configurations
const app = express();
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
// ---------------------------- Routes ----------------------------
app.use('/', express.static('dist/client/'));
app.use('/health-check', healthCheckRouter);
export default app;
Posting my solution for anyone who comes across the same and has a mind blank. I kept the bin/www and index.js files separately but had the express object returned from index.js via a method. Solution below thanks to the friendly people of Github.
Index.js file:
import express from 'express';
import {initialize} from './services/appService';
import healthCheckRouter from './routes/healthCheckRouter';
import loginRouter from './routes/loginRouter';
export function getExpress() {
return initialize()
.then(() => {
const app = express();
// ---------------------------- Routes ----------------------------
app.use('/', express.static('dist/client/'));
app.use('/login', loginRouter);
app.use('/health-check', healthCheckRouter);
return app;
})
}
bin/www file:
import winston from 'winston';
import bodyParser from 'body-parser';
import {getExpress} from '../index';
getExpress()
.then(app => {
app.use(bodyParser.json()); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
const port = 3002;
app.listen(port, () => {
winston.info(`Server listening on port ${port}!`);
});
})
.catch(err => {
winston.error('Error starting server', err);
});
Integration tests:
import request from 'supertest';
import {getExpress} from '../../index'
describe('/login integration test', () => {
let app = null;
beforeEach(done => {
getExpress()
.then(res => {
app = res;
done();
});
});
describe('GET /login', () => {
it('should return 400 error if \'app\' is not provided as a query string', done => {
request(app)
.get('/login')
.expect(400, done);
});
});
});