Bruford Bruford - 15 days ago 4
Node.js Question

Azure hosted node app cannot find module 'async/each'

I have been deploying my app to Azure for a few weeks now without problem. However now that I've integrated the DB to the backend it is throwing this error seen in the log stream and giving the browser a 500 code.

Application has thrown an uncaught exception and is terminated:
Error: Cannot find module 'async/each'
at Function.Module._resolveFilename (module.js:325:15)
at Function.Module._load (module.js:276:25)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (D:\home\site\wwwroot\node_modules\mongoose\lib\schema.js:11:12)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)


Mongoose appears to be the issue, and so when I exclude it then all is fine again. I tried including async-each as a dependency in my package.json but that's not helped (I've not seen a module with a / in before so was guessing here)

Also in a moment of desperation I've tried pushing the same app to another Web App service but it failed to even deploy. WebApiClient timed out - whatever THAT means.

I deployed the exact same app to Heroku and it works perfectly.

"use strict";
let express = require('express');
let path = require('path');
let favicon = require('serve-favicon');
let logger = require('morgan');
let cookieParser = require('cookie-parser');
let bodyParser = require('body-parser');
let mongoose = require('mongoose');
let passport = require('passport');
let LocalStrategy = require('passport-local').Strategy;
let session = require('express-session');

//routes
let home = require('./routes/index');
let register = require('./routes/register');
let members = require('./routes/members');
let login = require('./routes/login');
let logout = require('./routes/logout');

let app = express();

app.locals.courses = require('./data/courses');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({secret:'anything'}));
app.use(passport.initialize());
app.use(passport.session());

//mongoose passport config

require('./db').then(mongoose => {
mongoose.Promise = global.Promise;
require('./models/user').then(User => {
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
});
})


//allow CORS requests
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});

app.use('/', home);
app.use('/register', register);
app.use('/members', members);
app.use('/login', login);
app.use('/logout', logout);

// 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 (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.send(err.message);
});
}

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.send(err.message);
});


module.exports = app;

Answer

I deployed mongoose successfully to Azure, and the test code also worked well. Maybe your application will use any module which is configured in devDependenciessection in package.json file.

As Azure Web Apps as a production web server, if you deploy your app via git, be default the deployment task will run npm install --production, which will ignore the dependencies in develop mod.

So, you can try to follow Custom Deployment Script to generate the deplotment script for node.js and modify deploy.cmd, find sentence call :ExecuteCmd !NPM_CMD! install --production and modify to call :ExecuteCmd !NPM_CMD! install.

Meanwhile, you can follow https://docs.microsoft.com/en-us/azure/nodejs-specify-node-version-azure-apps to upgrade your node.js and npm version of Azure Web Apps' runtime, to avoid the nested node_modules folder structure.