If you have this error when running yarn, chances are you have installed the wrong yarn package which come from cmdtest
, let’s remove it and install the correct one using npm
sudo apt remove cmdtest npm install -g yarn
If you have this error when running yarn, chances are you have installed the wrong yarn package which come from cmdtest
, let’s remove it and install the correct one using npm
sudo apt remove cmdtest npm install -g yarn
Imagine the original app.js is this long file, how to split app.js of express into smaller files is as following
var http = require('http'), path = require('path'), methods = require('methods'), express = require('express'), bodyParser = require('body-parser'), session = require('express-session'), cors = require('cors'), passport = require('passport'), errorhandler = require('errorhandler'), mongoose = require('mongoose'); var isProduction = process.env.NODE_ENV === 'production'; // Create global app object var app = express(); var router = app.Router(); app.use(cors()); // Normal express config defaults app.use(require('morgan')('dev')); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(require('method-override')()); app.use(express.static(__dirname + '/public')); app.use(session({ secret: 'conduit', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false })); if (!isProduction) { app.use(errorhandler()); } if(isProduction){ mongoose.connect(process.env.MONGODB_URI); } else { mongoose.connect('mongodb://localhost/conduit'); mongoose.set('debug', true); } var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; var mongoose = require('mongoose'); var User = mongoose.model('User'); passport.use(new LocalStrategy({ usernameField: 'user[email]', passwordField: 'user[password]' }, function(email, password, done) { User.findOne({email: email}).then(function(user){ if(!user || !user.validPassword(password)){ return done(null, false, {errors: {'email or password': 'is invalid'}}); } return done(null, user); }).catch(done); })); router.get('/user', auth.required, function(req, res, next){ User.findById(req.payload.id).then(function(user){ if(!user){ return res.sendStatus(401); } return res.json({user: user.toAuthJSON()}); }).catch(next); }); router.put('/user', auth.required, function(req, res, next){ User.findById(req.payload.id).then(function(user){ if(!user){ return res.sendStatus(401); } // only update fields that were actually passed... if(typeof req.body.user.username !== 'undefined'){ user.username = req.body.user.username; } if(typeof req.body.user.email !== 'undefined'){ user.email = req.body.user.email; } if(typeof req.body.user.bio !== 'undefined'){ user.bio = req.body.user.bio; } if(typeof req.body.user.image !== 'undefined'){ user.image = req.body.user.image; } if(typeof req.body.user.password !== 'undefined'){ user.setPassword(req.body.user.password); } return user.save().then(function(){ return res.json({user: user.toAuthJSON()}); }); }).catch(next); }); /// catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); /// error handlers // development error handler // will print stacktrace if (!isProduction) { app.use(function(err, req, res, next) { console.log(err.stack); res.status(err.status || 500); res.json({'errors': { message: err.message, error: err }}); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.json({'errors': { message: err.message, error: {} }}); }); // finally, let's start our server... var server = app.listen( process.env.PORT || 3000, function(){ console.log('Listening on port ' + server.address().port); });
Split passport and routes
var http = require('http'), path = require('path'), methods = require('methods'), express = require('express'), bodyParser = require('body-parser'), session = require('express-session'), cors = require('cors'), passport = require('passport'), errorhandler = require('errorhandler'), mongoose = require('mongoose'); var isProduction = process.env.NODE_ENV === 'production'; // Create global app object var app = express(); app.use(cors()); // Normal express config defaults app.use(require('morgan')('dev')); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(require('method-override')()); app.use(express.static(__dirname + '/public')); app.use(session({ secret: 'conduit', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false })); if (!isProduction) { app.use(errorhandler()); } if(isProduction){ mongoose.connect(process.env.MONGODB_URI); } else { mongoose.connect('mongodb://localhost/conduit'); mongoose.set('debug', true); } require('./config/passport'); app.use(require('./routes')); /// catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); /// error handlers // development error handler // will print stacktrace if (!isProduction) { app.use(function(err, req, res, next) { console.log(err.stack); res.status(err.status || 500); res.json({'errors': { message: err.message, error: err }}); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.json({'errors': { message: err.message, error: {} }}); }); // finally, let's start our server... var server = app.listen( process.env.PORT || 3000, function(){ console.log('Listening on port ' + server.address().port); });
var passport = require('passport'); var LocalStrategy = require('passport-local').Strategy; var mongoose = require('mongoose'); var User = mongoose.model('User'); passport.use(new LocalStrategy({ usernameField: 'user[email]', passwordField: 'user[password]' }, function(email, password, done) { User.findOne({email: email}).then(function(user){ if(!user || !user.validPassword(password)){ return done(null, false, {errors: {'email or password': 'is invalid'}}); } return done(null, user); }).catch(done); }));
var mongoose = require('mongoose'); var router = require('express').Router(); var passport = require('passport'); var User = mongoose.model('User'); var auth = require('../auth'); router.get('/user', auth.required, function(req, res, next){ User.findById(req.payload.id).then(function(user){ if(!user){ return res.sendStatus(401); } return res.json({user: user.toAuthJSON()}); }).catch(next); }); router.put('/user', auth.required, function(req, res, next){ User.findById(req.payload.id).then(function(user){ if(!user){ return res.sendStatus(401); } // only update fields that were actually passed... if(typeof req.body.user.username !== 'undefined'){ user.username = req.body.user.username; } if(typeof req.body.user.email !== 'undefined'){ user.email = req.body.user.email; } if(typeof req.body.user.bio !== 'undefined'){ user.bio = req.body.user.bio; } if(typeof req.body.user.image !== 'undefined'){ user.image = req.body.user.image; } if(typeof req.body.user.password !== 'undefined'){ user.setPassword(req.body.user.password); } return user.save().then(function(){ return res.json({user: user.toAuthJSON()}); }); }).catch(next); });
Rather than using methods chain and callback, from express router we can call to mongoose findOne using async await as following
we can then search for mongo, if found then use the object, not found then create new one and attach to the second entity.
// mongoose.model("Child", ChildSchema); // mongoose.model("Parent", ParentSchema); router.post('/create', async function (req, res, next) { const user = req.user; const childObject = req.body.object1; const parentObject = req.body.object2; console.log('create parent-child for user: ', user, ' from parent: ', parentObject, 'to child:', childObject); var parentEntity = await Parent.findOne({criteria1: parent.value1}).exec(); if(!parentEntity) { parentEntity = new Parent(parentObject); parentEntity.extra = 'extra'; parentEntity.userId = user.id; parentEntity.save(); } var childEntity = await Child.findOne({criteria1: child.value1}).exec(); if(!childEntity) { childEntity = new Child(child); childEntity.extra = 'extra'; childEntity.userId = user.id; childEntity.parentId = parentEntity.id; childEntity.save(); } });
This helps us solve the express mongoose mongodb object dependency issue
module.exports = Object.freeze({ STATES: { "AL": "Alabama", "AK": "Alaska", "AS": "American Samoa", "AZ": "Arizona", "AR": "Arkansas", "CA": "California", "CO": "Colorado", "CT": "Connecticut", "DE": "Delaware", "DC": "District Of Columbia", "FM": "Federated States Of Micronesia", "FL": "Florida", "GA": "Georgia", "GU": "Guam", "HI": "Hawaii", "ID": "Idaho", "IL": "Illinois", "IN": "Indiana", "IA": "Iowa", "KS": "Kansas", "KY": "Kentucky", "LA": "Louisiana", "ME": "Maine", "MH": "Marshall Islands", "MD": "Maryland", "MA": "Massachusetts", "MI": "Michigan", "MN": "Minnesota", "MS": "Mississippi", "MO": "Missouri", "MT": "Montana", "NE": "Nebraska", "NV": "Nevada", "NH": "New Hampshire", "NJ": "New Jersey", "NM": "New Mexico", "NY": "New York", "NC": "North Carolina", "ND": "North Dakota", "MP": "Northern Mariana Islands", "OH": "Ohio", "OK": "Oklahoma", "OR": "Oregon", "PW": "Palau", "PA": "Pennsylvania", "PR": "Puerto Rico", "RI": "Rhode Island", "SC": "South Carolina", "SD": "South Dakota", "TN": "Tennessee", "TX": "Texas", "UT": "Utah", "VT": "Vermont", "VI": "Virgin Islands", "VA": "Virginia", "WA": "Washington", "WV": "West Virginia", "WI": "Wisconsin", "WY": "Wyoming" } });
When this error happened, beside the normal configuration for passport, you may want to add the following configuration
passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(user, done) { done(null, user); });
For ExpressJS 4, running nodemon app.js
won’t work, use the following command:
nodemon www/bin # or nodemon
To create a layout that other view can inherit / extend from using Express EJS engine
## First create a project and install important libs npm install express-generator -g express --ejs --git extend-layout cd extend-layout npm install --save express-ejs-extend ## Make change to app.js var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var app = express(); // view engine setup app.engine('ejs', require('express-ejs-extend')); // add this line app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', indexRouter); app.use('/users', usersRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app; ## Create views/layout.ejs <!DOCTYPE html> <html> <body> <%- content %> </body> </html> ## Change to views/index.ejs <%# views/index.ejs %> <% extend('layout') %> <h1>Hello <%= title %></h1> ## Finally run and test DEBUG=extend-layout:* npm start
var express = require('express') var app = express() var myLogger = function (req, res, next) { console.log('LOGGED') next() } app.use(myLogger) app.get('/', function (req, res) { res.send('Hello World!') }) app.listen(3000
var express = require('express') var app = express() var requestTime = function (req, res, next) { req.requestTime = Date.now() next() } app.use(requestTime) app.get('/', function (req, res) { var responseText = 'Hello World!<br>' responseText += '<small>Requested at: ' + req.requestTime + '</small>' res.send(responseText) }) app.listen(3000)
var express = require('express') var cookieParser = require('cookie-parser') var cookieValidator = require('./cookieValidator') var app = express() async function validateCookies (req, res, next) { await cookieValidator(req.cookies) next() } app.use(cookieParser()) app.use(validateCookies) // error handler app.use(function (err, req, res, next) { res.status(400).send(err.message) }) app.listen(3000)
. ├── app.js ├── bin │ └── www ├── package.json ├── public │ ├── images │ ├── javascripts │ └── stylesheets │ └── style.css ├── routes │ ├── index.js │ └── users.js └── views ├── error.pug ├── index.pug └── layout.pug
express --view=pug myapp create : myapp create : myapp/package.json create : myapp/app.js create : myapp/public create : myapp/public/javascripts create : myapp/public/images create : myapp/routes create : myapp/routes/index.js create : myapp/routes/users.js create : myapp/public/stylesheets create : myapp/public/stylesheets/style.css create : myapp/views create : myapp/views/index.pug create : myapp/views/layout.pug create : myapp/views/error.pug create : myapp/bin create : myapp/bin/www