Grunt Livereload not showing HTML changes


On my MEAN stack application, I'm trying make changes to the HTML view files and see those changes as I make them using Grunt's livereload.

Grunt's livereload is working fine in the sense that it detects changes in my HTML files and refreshes the page during development. However, the actual changes are not reflecting on the page. If I push the files up the server, and reload the publicly available site, the changes are there. But I still can't see the changes while I'm developing.

I'm 99% sure that the problem has to do with the server is using the "build" files or something rather than the files located in the /public folder. However, I'm new to using the back-end and the MEAN stack and can't figure out what file the browser is showing or where this file is. Could anyone give any guidance on how to figure out what file the browser is displaying and what I can do to show HTML changes I make as I make them?

Here is my gruntfile if this helps. The below files I'm making changes to are watchFiles.clientViews.

'use strict'; module.exports = function(grunt) { // Unified Watch Object var watchFiles = { serverViews: ['app/views/**/*.*'], serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'app/**/*.js'], clientViews: ['public/modules/**/views/**/*.html'], clientJS: ['public/js/*.js', 'public/modules/**/*.js'], clientCSS: ['public/modules/**/*.css'], mochaTests: ['app/tests/**/*.js'] }; // Project Configuration grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), watch: { options: { livereload: true }, serverViews: { files: [watchFiles.serverViews], options: { livereload: true } }, serverJS: { files: watchFiles.serverJS, tasks: ['jshint'], options: { livereload: true } }, clientViews: { files: watchFiles.clientViews, options: { livereload: true, } }, clientJS: { files: watchFiles.clientJS, tasks: ['jshint'], options: { livereload: true } }, clientCSS: { files: watchFiles.clientCSS, tasks: ['csslint'], options: { livereload: true } } }, jshint: { all: { src: watchFiles.clientJS.concat(watchFiles.serverJS), options: { jshintrc: true } } }, csslint: { options: { csslintrc: '.csslintrc', }, all: { src: watchFiles.clientCSS } }, uglify: { production: { options: { mangle: false }, files: { 'public/dist/application.min.js': 'public/dist/application.js' } } }, cssmin: { combine: { files: { 'public/dist/application.min.css': '<%= applicationCSSFiles %>' } } }, nodemon: { dev: { script: 'server.js', options: { nodeArgs: ['--debug'], ext: 'js,html', watch: watchFiles.serverViews.concat(watchFiles.serverJS) } } }, 'node-inspector': { custom: { options: { 'web-port': 1337, 'web-host': 'localhost', 'debug-port': 5858, 'save-live-edit': true, 'no-preload': true, 'stack-trace-limit': 50, 'hidden': [] } } }, ngAnnotate: { production: { files: { 'public/dist/application.js': '<%= applicationJavaScriptFiles %>' } } }, concurrent: { default: ['nodemon', 'watch'], debug: ['nodemon', 'watch', 'node-inspector'], options: { logConcurrentOutput: true, limit: 10 } }, env: { test: { NODE_ENV: 'test' } }, mochaTest: { src: watchFiles.mochaTests, options: { reporter: 'spec', require: 'server.js' } }, karma: { unit: { configFile: 'karma.conf.js' } } }); // Load NPM tasks require('load-grunt-tasks')(grunt); // Making grunt default to force in order not to break the project. grunt.option('force', true); // A Task for loading the configuration object grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() { var init = require('./config/init')(); var config = require('./config/config'); grunt.config.set('applicationJavaScriptFiles', config.assets.js); grunt.config.set('applicationCSSFiles', config.assets.css); }); // Default task(s). grunt.registerTask('default', ['lint', 'concurrent:default']); // Debug task. grunt.registerTask('debug', ['lint', 'concurrent:debug']); // Lint task(s). grunt.registerTask('lint', ['jshint', 'csslint']); // Build task(s). grunt.registerTask('build', ['lint', 'loadConfig', 'ngAnnotate', 'uglify', 'cssmin']); // Test task. grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']); };

In addition, here is the file structure to my MEAN stack. The highlighted below is where the HTML file that I'm making changes to is located.

<img alt="Imgur" class="b-lazy" data-src="https://i.imgur.com/njmfACT.jpg" data-original="https://i.imgur.com/njmfACT.jpg" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" />

Please let me know if there is any other code or info I could provide that would make solving this problem easier. Thank you.

<strong>Update: Content of Server.js</strong>

Here is my server.js content:

'use strict'; /** * Module dependencies. */ var init = require('./config/init')(), config = require('./config/config'), mongoose = require('mongoose'); /** * Main application entry file. * Please note that the order of loading is important. */ // Bootstrap db connection var db = mongoose.connect(config.db, function(err) { if (err) { console.error('\x1b[31m', 'Could not connect to MongoDB!'); console.log(err); } }); // Init the express application var app = require('./config/express')(db); // Bootstrap passport config require('./config/passport')(); // Start the app by listening on <port> app.listen(config.port); // Expose app exports = module.exports = app; // Logging initialization console.log('MEAN.JS application started on port ' + config.port);


It's hard to tell exactly what your "server.js" is serving without seeing the contents of it, but if my assumption is correct and you are serving the contents of the "public" directory, you don't have any sort of task being fired by watch that facilitates copying the contents of your changed files into your "public" directory. It looks like this happens initially when your server is started (by running the build task), but not run subsequently whenever something is changed.

I would suggest modifying your watch tasks to perform some of the build-related tasks on your files as they are changed. Since your build-related tasks are physically copying the changes to the "public" directory for you as part of their jobs, you should finally see the results of your changes. Here's an example of your watch task list that's modified to copy your JS and CSS files on change:

watch: { options: { livereload: true }, serverViews: { files: [watchFiles.serverViews], options: { livereload: true } }, serverJS: { files: watchFiles.serverJS, tasks: ['jshint', 'loadConfig', 'ngAnnotate', 'uglify'], options: { livereload: true } }, clientViews: { files: watchFiles.clientViews, options: { livereload: true, } }, clientJS: { files: watchFiles.clientJS, tasks: ['jshint', 'loadConfig', 'ngAnnotate', 'uglify'], options: { livereload: true } }, clientCSS: { files: watchFiles.clientCSS, tasks: ['csslint', 'cssmin'], options: { livereload: true } } },

<strong>One last thing:</strong> Assuming your views don't need to have any modifications done to them post-change, you can simply straight-up copy them to the public directory when they are changed. Take a look at <a href="https://github.com/gruntjs/grunt-contrib-copy" rel="nofollow">grunt-contrib-copy</a> for doing simple file copying between directories.


  • How to load minified file in angular 2 using gulp uglify ? (which minifies TYpescript Bundled File)
  • How do I modify jshint sublimelinter settings?
  • Make gulp-uglify not mangle only one variable
  • Task not found using grunt
  • How to turn off JSHint error?
  • Gulp-sourcemaps not creating a sourcemap file?
  • Disable JSHint warning: Expected an assignment or function call and instead saw an expression [dupli
  • gruntjs load external config
  • Angular and Jasmine: How to test requestError / rejection in HTTP interceptor?
  • Disable warnings (ids selector) in linter-csslint on Atom?
  • How to run JSLint / JSHint in a file with templates?
  • Resample in a rolling window using pandas
  • Should `System.IO.Path` be concrete?
  • C#'s “protected internal” means “protected” *OR* “internal”. Does any keyword mean “protected”
  • gulp: passing dependent task return stream as parameter
  • How to save R plot image to database?
  • Convert Python date to Unix timestamp
  • How to label data points in matplotlib scatter plot while looping through pandas dataframes?
  • Get both date and time in milliseconds
  • how to download any file to any device and view?
  • web scrape with rvest
  • After message type e, program doesn't return to selection-screen ABAP
  • finding symmetric difference/unique elements in multiple arrays in javascript
  • How to convert NAnt function “path::combine(path1, path2)” to MSBuild?
  • Get pretty git rev name
  • Simplifying the use of meshgrid in Matlab
  • Combine two small queries (that group by different values) into one query
  • Gruntfile.js - Throwing error 'Recursive process.nextTick detected\"
  • How to implement simple validation in Scala
  • Problem in concatenation of objects in javascript
  • Counting problem C#
  • KnockoutObservableArray with typed elements in TypeScript
  • R Split data.frame using a column that represents and on/off switch
  • Display images in Django
  • Custom validator control occupying space even though display set to dynamic
  • Combining SpatialPolygonsDataFrame of two neighbour countries
  • JSON response opens as a file, but I can't access it with JavaScript
  • Resize panoramic image to fixed size
  • Importing jscolor library in angular 2
  • apache spark aggregate function using min value