I have a route that calls my controller and the controller does nothing but respond with a view. Nothing dynamic happening here. I am using Swig for my views. For some reason, my view is not getting refreshed with the new changes. it still shows me the old view. I have tried the following to no avail:
app.set('view cache', false);
// To disable Swig's cache, do the following:
swig.setDefaults({ cache: false });
app.disable('view cache');
app.set('etag', 'strong');
I have a console.log statement in my controller and it never seems to log anything out leading me to believe that that controller is never called. I do have a simple middleware that logs the path out before the routes are set up and I see the request for my route but the controller never gets called and an older version of the template view is served.
Am I missing something??
Update: Server controller code:
exports.index = function (req, res) {
res.render('myapp', {});
};
In order to check your code without node.js restart, consider to use pm2 or nodemon
After installation of pm2:
pm2 start app.js --watch
PM2 automatically restarts your app when a file changes in the current directory or its subdirectories.
But my favorite choice is nodemon:
nodemon [your node app]
Related
So my express app has a small Node server setup so it can serve up the index.html file when the home route '/' is hit. This is a requirement of using the App Services from Azure, there has to be this server.js file to tell the server how to serve up the client, and i had a previous implementation of this working, however i wanted to change my file structure. previously i had, the client React app in a folder client and the server.js in a folder server along with all of the conrtollers and routes. i've since moved the server API to its own application as there are other apps that depend on it. and i moved the client up one directory into the main directory. Everything was working fine till the other day when all of the sudden when you hit the home route / it will not serve up the index.html file. if you hit any other route it works, if you even hit a button linking back to the homepage, it works, but it wont serve up the app from the / and i cannot for the life of me figure out why, on my development server there are no errors in the console. and im most definitely targeting the correct directory and place for the index. but its like the server isnt reading the route to serve up.
if (process.env.NODE_ENV === 'production') {
console.log('running');
app.use(express.static(path.resolve(path.join(__dirname, 'build'))));
// no matter what route is hit, send the index.html file
app.get('*', (req, res) => {
res.sendFile(path.resolve(path.join(__dirname, 'build', 'index.html')));
});
} else {
app.get('/', (req, res) => {
res.send('API is running...');
});
}
So here im saying if the NODE_ENV is in production make the build folder static, and then whatever route is hit. (Note: i also tried this app.get with other route formats such as /* or / all have the same issues. however in my previous iteration when the client and server where deployed in the same location, /* is what i used.) The .env varialbes are setup correctly, as when the server is ran, itll console log running.. but even if i put a console log inside of the app.get() its like its never hit unless i access the route from something else first.
for example, if i place a console log inside of app.get that states hit whenever the route is hit, hitting / directly does nothing, but if i go to /login itll serve up the correct html on the client and console log hit in the terminal...
If you are having server files inside the client react app, then we are basically accessing file which are not inside our server file. So, we can serve static files using the following code:
const express = require("express");
const app = express(); // create express app
const path = require('path');
app.use(express.static(path.join(__dirname, "..", "build")));
app.use(express.static("build"));
app.listen(5000, () => {
console.log("server started on port 5000");
});
Now in your packages.json of the client react app change the name of start tag under scripts tag to start-client. Then add this following tag to the scripts tag:
"start":"npm run build && (cd server && npm start)",
Basically, this will build the react app and start the server.
It should look like this :
Also in the packages.json of your server add the following tag under script tag
"start":"node server.js"
So when you run the following command npm start it should look like this :
I am getting a super unhelpful message 'Cannot GET /' printed to my browser when I run my node dev server through webpack. I am building a Vuejs application with the following:
VueJs structured in a way that was dicated by this Vue Template with my node scripts being identical to the default commands
Webpack config based on Vue Loader
Routes handled through Vue Router
I know this is not a great deal to go off but an idea of what is firing this error (Node? Webpack? Vue Router?) it would point me in the right direction and be greatly appreciated.
If you're experiencing this with Vite, make sure you ran just vite in your package.json script, NOT vite preview
I found myself in the same problem. In my case it was related to the use of Express with Vue.js. So I am leaving my solution in case anyone finds it useful
I added this code for handling the calls to my index.html file
app.route('/*')
.get(function(req, res) {
res.sendFile(path.join(__dirname + '/dist/index.html'));
});
module.exports = app;
Node is throwing the error and make sure your vue router is configured properly,Cannot GET simply means you have not assigned a view to your url e.g on express we use
app.use('/', your route)
and on connect we use
app.get or app.post
All it's saying is there is no content/view assigned to that url.
It turns out it was an issue with the vuejs webpack template I was working from: https://github.com/vuejs-templates/webpack
The build path was being used in the dev server configuration.
Made this pull request to fix the issue: https://github.com/vuejs-templates/webpack/pull/188#issuecomment-230968416
I had this issue while running my app in dev. Adding this to the devServer of my webpack.dev.config file helped:
historyApiFallback: true
Answer by Jezperp here.
If you are using express check that you have this line:
app.use(express.static('static'));
And that "static" matches with the folder specified in your vue.config.js
outputDir: path.resolve("../Server/static")
I've recently installed Node.js on a local server and when I create a 'server.js' file (adding a server using the .createServer() method), it loads fine.
However after installing Express.js, the default files are as follows:
/bin
/node_modules
/public
/routes
/views
app.js
package.json
After following some documentation, I am instructed to go to Terminal and enter the following command:
node app.js
To which nothing happens, the command line refreshes to the next line in less than a second, and opening a browser after visiting the proper IP and port, to no avail.
Below is the code inside of the app.js file:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 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('/', routes);
app.use('/users', users);
// 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.render('error', {
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.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
I understand that the actual 'express' module that is being required in the beginning of the file is where the magic happens, however, when I run the command line:
node app.js
Nothing happens. However, if I call the following line:
npm start
Everything appears to be okay. I would like to follow the documentation as is, any reason why the app.js wouldn't be working?
Thank you.
UPDATE: My question was too similar to another one already posted, so I must clarify exactly how they were different. In the other question, a person was questioning a code number they received while running the Supervisor command on the default 'app.js' file.
While similar in nature, this question should remain, as those who are confused by using my same approach will focus on the identity of the actual 'app.js' file by using 'node app.js' without having full knowledge of the Supervisor utility.
Regards.
Thank you all for your great responses, as they really allowed me to understand what is actually going on with the app.js file and where it receives it's functionality. Thank you to both Matthew Bakaitis and Bjarni Leifsson for their great input.
The only reason why I am going to go ahead and answer my own question is because while the nature of the app.js file was explained, exactly how to replicate calling the 'node app.js' command from the command line as to replicate a Node.js book that I was following wasn't implicitly addressed.
After searching google with the specific phrase "app.js in previous express.js versions", I happened upon a great article by Jilles Soeters entitled "Understanding the Express app.js":
http://jilles.me/getting-the-express-app-js/
Below is the excerpt of the solution that worked for me:
The file I'm covering is app.js, the main configuration file for your
Express app. When I first opened app.js it confused me. I will save
you the trouble of doing research and just cover them here.
Before you do anything add the following to your app.js
app.listen(3000);
You need that in order to be able to actual open your app in the
browser. Go to 127.0.0.1:3000 after you've started your app (using
node app.js)
After doing this, I was able to run the command
node app.js
I was able to run this command from the root directory of the Express install and proceed with my Node.js book with no additional problems.
This is a common problem that is caused when tutorials don't clearly explain what express is doing when it generates an app. You're trying to learn the new tech, but the tutorial is actively working against you. :(
The answer:
When you use the generator, package.json is configured so that npm start calls ./bin/www.
That file includes app.js and after the include, calls app.listen.
app.js doesn't call app.listen which is why if you call it directly, it exits with no code or info. You've got to call ./bin/www or you have to modify app.js...which then defeats some of the reasons you'd use a generator.
A related question here on the site saw a similar problem when trying to use supervisor to keep an app running but kept getting an exit 0 result.
How I understand this, and I have just started to use node.
There is a bin folder with www in it. There all the magic happens. So when you do node app.js it gets executed but the logic to the everything is in bin/www
So if you look into package.json you see this init :
"scripts": {
"start": "node ./bin/www"
},
So giving that, you see to execute the script you use the start method and it is linked to ./bin/www
If you take a look in that file you will find out that the whole logic of the server to start up is in there.
So if you change start to something else, like TurnOn and would do npm TurnOn, it will execute ./bin/www and the whole project for you.
The structor of the project is all linked together, and app.js is not enough to start the server.
Hope this helps.
When using Express the Express instance will create the server for you. Typically your app/index/server.js file will begin with these lines:
const express = require('express');
const app = express();
These lines require Express and then instantiate an instance of Express within the app variable. Express then uses var server = http.createServer(app); to start a server for you. All you need to do is to make sure your app listens to that server (as you wrote). However, the port for the connection may vary so it is not advisable to hard-code it. Instead it should be retrieved from the app variable as such:
app.listen(app.get('port'), function(){
//Something to do when the server starts.
});
Additionally, after creating your own app.js file make sure to change your package.json file to start the app via app.js instead of the Express module. By default your package.json might look like this:
"scripts": {
"start": "node ./bin/www"
},
But after you created your own app/index/server.js file you want node to start running that file on startup instead:
"scripts": {
"start": "node app.js"
}
You can then start your app by writing npm start from the project directory.
I am working off of Yeoman's gulp-webapp generator. I have modified my gulp serve task to use my Express server, rather than the default connect server it ships with. My issue is with Livereload functionality. I am trying to simply port the connect-livereload to work with my Express server rather than having to install new dependencies. It's to my understanding that most connect middleware should work fine with Express, so I am assuming connect livereload is compatible with Express 4.
Here are the contents of the relevant tasks in my gulpfile:
gulp.task('express', function() {
var serveStatic = require('serve-static');
var app = require('./server/app');
app.use(require('connect-livereload')({port: 35729}))
.use(serveStatic('.tmp'));
app.listen(3000);
});
gulp.task('watch', ['express'], function () {
$.livereload.listen();
// watch for changes
gulp.watch([
'app/*.ejs',
'.tmp/styles/**/*.css',
'app/scripts/**/*.js',
'app/images/**/*'
]).on('change', $.livereload.changed);
gulp.watch('app/styles/**/*.css', ['styles']);
gulp.watch('bower.json', ['wiredep']);
});
gulp.task('styles', function () {
return gulp.src('app/styles/main.css')
.pipe($.autoprefixer({browsers: ['last 1 version']}))
.pipe(gulp.dest('.tmp/styles'));
});
gulp.task('serve', ['express', 'watch'], function () {
require('opn')('http://localhost:3000');
});
With this simple setup, when I run gulp serve in my cmd everything spins up fine and I can accept requests at http://localhost:3000.
Now if I go and change the body's background color from #fafafa to #f00 in main.css and hit save, my gulp output will respond with main.css was reloaded, as seen in the bottom of this screenshot.
However, my webpage does not update. The background color is still light-grey instead of red.
Is there perhaps a conflict between my express server config and the way gulp handles its files? Is my Express server forcing the use of app/styles/main.css rather than the use of .tmp/styles/main.css? Shouldn't the livereload script handle the injection of the new temporary file?
Thanks for any help.
EDIT:
I was able to move forward a bit by adding livereload.js to the script block of my index file, like so:
<script src="http://localhost:35729/livereload.js"></script>
I am now able to get live changes pushed to the client. Why was this file not getting injected before? How can I ensure this is getting used programatically as opposed to pasting it into my files?
I was able to get past this issue by removing the app.use(require('connect-livereload')({port: 35729})) from my gulpfile, along with a couple of other lines, and having that instantiate in my Express server's app.js file.
My gulpfile's express task now looks like this:
gulp.task('express', function() {
var app = require('./server/app');
app.listen(3000);
});
I added in the connect-livereload just above where I specify my static directory in Express:
if (app.get('env') === 'development') {
app.use(require('connect-livereload')());
}
app.use(express.static(path.join(__dirname, '../app')));
Once I started using this setup, I was getting the livereload.js script injected into my document, and client-side changes are now auto-refreshed just how I wanted.
Hope this helps someone!
My setup:
Express 4.2.0
Jade 1.3.1
I'm learning express and jade templating.
I have a view, mypage, which display name and age vars defined in the route below.
Everytime I change the options args of render (changing name or age to anything), the mypage view doesn't get updated when I reload. So I always have to restart the node app (killing with ctrl+C and npm start) to get the last update.
It seems like it's caching, but I'm in development mode.
/* GET my page */
router.get('/mypage', function(req, res){
res.render('mypage', {
name: 'Default John',
age: 213456
});
});
I tried app.disable('view cache') and nothing. Is this the expected behavior?
Try to use
app.set('view cache', true);