Javascript (Angular) not loading when using Express

12,553

Solution 1

You need another static directory route:

app.use(express.static(__dirname + '/app'));
//add this so the browser can GET the bower files
app.use('/bower_components', express.static(__dirname + '/bower_components'));

In order for deployment to work on heroku, you need to set up a postinstall script in your package.json file to heroku will run bower install for you.

Here's a blog post describing that.

"scripts": {
    "postinstall": "./node_modules/bower/bin/bower install"
}

Because currently bower install is not running, the actual angularjs files you need are not there, which causes these errors in the browser console, which causes the ReferenceError about angular not being defined.

GET http://localhost:5000/bower_components/angular/angular.js 404 (Not Found) localhost/:22
GET http://localhost:5000/bower_components/angular-route/angular-route.js 404 (Not Found) localhost/:23
GET http://localhost:5000/bower_components/angular-sanitize/angular-sanitize.js 404 (Not Found) localhost/:24
GET http://localhost:5000/bower_components/angular-animate/angular-animate.js 404 (Not Found) localhost/:25
Uncaught ReferenceError: angular is not defined

Go step by step. First, make sure the files actually get properly installed both locally and on heroku. Then make sure they properly load into the browser. Then make sure your actual javascript code is correct for your application.


Next Problem

Followup Error 2: Okay, that fixed the problem of not being able to push to Heroku. So now I can push changes to Heroku, but the AngularJS and CSS are still not displaying on the Heroku domain. I checked the console on the domain, which says:

GET http://myapp.herokuapp.com/bower_components/angular-sanitize/angular-sanitize.js 404 (Not Found) lit-inlet-8601.herokuapp.com/:24
GET http://myapp.herokuapp.com/bower_components/angular-animate/angular-animate.js 404 (Not Found) lit-inlet-8601.herokuapp.com/:25
Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
Error: [$injector:modulerr] Failed to instantiate module ngAnimate due to:
Error: [$injector:nomod] Module 'ngAnimate' is not available! You either misspelled the modul...<omitted>...1) angular.js:78

So both angular-sanitize and angular-animate are missing from heroku, which means the bower install didn't install them. Verify you actually reference them properly in your bower.json files.

Solution 2

Have you considered keeping your bower_components folder under version and control and if so have you checked your .gitignore? I just ran into a similar problem where certain bower installed dependencies were not loading after deployment. Turns out I was ignoring all dist/ folders.

Share:
12,553

Related videos on Youtube

user2669464
Author by

user2669464

Updated on June 04, 2022

Comments

  • user2669464
    user2669464 almost 2 years

    I'm trying to get my application deployed to a public domain using node.js, express.js, and Heroku (or Modulus.io).

    Everything was working fine in the development environment. But when I try to deploy it to Heroku or Modulus, I run into a lot of problems with PORT and Express. Right now I'm trying to deploy to Heroku.

    The project is built on angular-seed, and I made a few changes to package.json and how the server starts in order for it to work with Heroku.

    Right now, the local server (localhost:5000) loads a static HTML page (index.html works fine), but none of the CSS or Javascript is being loaded to the page. Same thing with the deployed app on Heroku.

    Here are the changes I made to package.json (from the one provided in angular-seed):

    ...
    "scripts": {
      "start": "node web.js",
      ...
    "main": "web.js",
    ...
    

    Here is what web.js looks like:

    var express = require("express");
    var logfmt = require("logfmt");
    var app = express();
    
    app.use(logfmt.requestLogger());
    
    app.use(express.static(__dirname + '/app'));
    
    
    app.get('/', function(req, res) {
      //res.send('Hello World!');
      res.sendfile('./app/index.html');
    });
    
    var port = Number(process.env.PORT || 5000);
    app.listen(port, function() {
      console.log("Listening on " + port);
    });
    

    In the HTML index file,

    <!doctype html>
    <html lang="en" ng-app="myApp">
    <head>
      <meta charset="utf-8">
      <title>Title</title>
      <link rel="stylesheet" href="css/app.css"/>
    </head>
    
    <body> 
    ... 
      <script src="../bower_components/angular/angular.js"></script>
      <script src="../bower_components/angular-route/angular-route.js"></script>
      <script src="../bower_components/angular-sanitize/angular-sanitize.js"></script>
      <script src="../bower_components/angular-animate/angular-animate.js"></script>
      <script src="js/app.js"></script>
      <script src="js/services.js"></script>
      <script src="js/controllers.js"></script>
      <script src="js/filters.js"></script>
      <script src="js/directives.js"></script>
    </body>
    </html>
    

    I start the server using "foreman start" in the command prompt and it loads the local server just fine with the plain HTML. I've also tried using instead:

    app.configure(function() {
        app.use(express.static(__dirname + '/public')); 
        app.use(express.logger('dev')); 
        app.use(express.bodyParser());  
    });
    

    in web.js, but when I start the server, I get an error saying "TypeError: undefined is not a function" pointing at the period at "app.configure".

    The error in the console says:

    GET http://localhost:5000/bower_components/angular/angular.js 404 (Not Found) localhost/:22
    GET http://localhost:5000/bower_components/angular-route/angular-route.js 404 (Not Found) localhost/:23
    GET http://localhost:5000/bower_components/angular-sanitize/angular-sanitize.js 404 (Not Found) localhost/:24
    GET http://localhost:5000/bower_components/angular-animate/angular-animate.js 404 (Not Found) localhost/:25
    Uncaught ReferenceError: angular is not defined 
    ... etc
    

    I've been trying to Google a solution, but most of them are from a year ago which does not seem to work anymore. Any help is appreciated. Thanks!


    Followup error: Now I can't push it to Heroku. Everything works fine locally though. Here's terminal output when I try to push it to Heroku:

    Counting objects: 5, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 285 bytes | 0 bytes/s, done.
    Total 3 (delta 2), reused 0 (delta 0)
    To ssh://[email protected]/[...]
       a655423..98d78e4  master -> master
    user@ubuntu:~/directory$ git push heroku
    warning: push.default is unset; its implicit value is changing in
    Git 2.0 from 'matching' to 'simple'. To squelch this message
    and maintain the current behavior after the default changes, use:
    
      git config --global push.default matching
    
    To squelch this message and adopt the new behavior now, use:
    
      git config --global push.default simple
    
    See 'git help config' and search for 'push.default' for further information.
    (the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
    'current' instead of 'simple' if you sometimes use older versions of Git)
    
    Fetching repository, done.
    Counting objects: 5, done.
    Delta compression using up to 8 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 285 bytes | 0 bytes/s, done.
    Total 3 (delta 2), reused 0 (delta 0)
    
    -----> Node.js app detected
    
           PRO TIP: Specify a node version in package.json
           See https://devcenter.heroku.com/articles/nodejs-support
    
    -----> Defaulting to latest stable node: 0.10.21
    -----> Downloading and installing node
    -----> Restoring node_modules directory from cache
    -----> Pruning cached dependencies not specified in package.json
    -----> Node version changed since last build; rebuilding dependencies
    
           > [email protected] install /tmp/build_f31706d9-b302-4cdd-ae3e-cce981c1bf51/node_modules/karma/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws
           > (node-gyp rebuild 2> builderror.log) || (exit 0)
    
           make: Entering directory `/tmp/build_f31706d9-b302-4cdd-ae3e-cce981c1bf51/node_modules/karma/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build'
             CXX(target) Release/obj.target/bufferutil/src/bufferutil.o
             SOLINK_MODULE(target) Release/obj.target/bufferutil.node
             SOLINK_MODULE(target) Release/obj.target/bufferutil.node: Finished
             COPY Release/bufferutil.node
             CXX(target) Release/obj.target/validation/src/validation.o
             SOLINK_MODULE(target) Release/obj.target/validation.node
             SOLINK_MODULE(target) Release/obj.target/validation.node: Finished
             COPY Release/validation.node
           make: Leaving directory `/tmp/build_f31706d9-b302-4cdd-ae3e-cce981c1bf51/node_modules/karma/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build'
    
           > [email protected] install /tmp/build_f31706d9-b302-4cdd-ae3e-cce981c1bf51/node_modules/karma-phantomjs-launcher/node_modules/phantomjs
           > node install.js
    
           Downloading http://cdn.bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2
           Saving to /tmp/phantomjs/phantomjs-1.9.7-linux-x86_64.tar.bz2
           Receiving...
           Error requesting archive.
           Status: 403
           Request options: {
             "protocol": "http:",
             "slashes": true,
             "auth": null,
             "host": "cdn.bitbucket.org",
             "port": null,
             "hostname": "cdn.bitbucket.org",
             "hash": null,
             "search": null,
             "query": null,
             "pathname": "/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2",
             "path": "/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2",
             "href": "http://cdn.bitbucket.org/ariya/phantomjs/downloads/phantomjs-1.9.7-linux-x86_64.tar.bz2"
           }
           Response headers: {
             "content-type": "text/html",
             "content-length": "14134",
             "connection": "keep-alive",
             "date": "Sat, 24 May 2014 00:28:20 GMT",
             "last-modified": "Sat, 24 May 2014 00:08:24 GMT",
             "etag": "\"999f4f548bfffe25245dc29e49c57e9c\"",
             "accept-ranges": "bytes",
             "server": "AmazonS3",
             "age": "49096",
             "x-cache": "Hit from cloudfront",
             "via": "1.1 7718496b82dfc64dff52dbb3d7f07f3b.cloudfront.net (CloudFront)",
             "x-amz-cf-id": "kA4IYvDWX-l2HNW8EzztjY9STY96Ns0vsZDWTUaloDmJTnwJakcDIg=="
           }
           Make sure your network and proxy settings are correct.
           npm ERR! weird error 1
           npm ERR! not ok code 0
    
     !     Push rejected, failed to compile Node.js app
    

    Followup Error 2: Okay, that fixed the problem of not being able to push to Heroku. So now I can push changes to Heroku, but the AngularJS and CSS are still not displaying on the Heroku domain. I checked the console on the domain, which says:

    GET http://myapp.herokuapp.com/bower_components/angular-sanitize/angular-sanitize.js 404 (Not Found) lit-inlet-8601.herokuapp.com/:24
    GET http://myapp.herokuapp.com/bower_components/angular-animate/angular-animate.js 404 (Not Found) lit-inlet-8601.herokuapp.com/:25
    Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to:
    Error: [$injector:modulerr] Failed to instantiate module ngAnimate due to:
    Error: [$injector:nomod] Module 'ngAnimate' is not available! You either misspelled the modul...<omitted>...1) angular.js:78
    

    This is strange because it works fine locally. On the inspect element Sources tab, it seems to be missing some directories (namely, angular-animate and angular-sanitize). I tried running both "heroku run bower install angular-sanitize" and "heroku run bower install angular-animate" in the terminal but it didn't fix the problem.

    "foreman start" and "npm start" both start the server locally and everything displays as it should.

    My index.html file is under the app_name/app/ directory and web.js is located in the app_name directory. I haven't changed any of the scripts to load Angular in the index.html file, so it still looks as listed above.

    My app.js file which is located in app_name/app/js should be listing the dependencies correctly:

    angular.module('myApp', [
      'ngAnimate',
      'ngSanitize',
      'ngRoute',
      'myApp.filters',
      'myApp.services',
      'myApp.directives',
      'myApp.controllers'
    ])...
    

    I am not sure what could be causing this. Any help is appreciated. Thanks!

    • mscdex
      mscdex almost 10 years
      app.configure() was removed in Express 4, as was all middleware except express.static (they are all separate modules now). What does your directory structure look like (project and public)?
  • user2669464
    user2669464 almost 10 years
    This line fixed the Javascript and CSS loading on the local page. But now I can't seem to push it to Heroku. I tested it with and without and line and it definitely seems to be coming from that addition. I edited the original question to include the output Any idea how to fix that?
  • user2669464
    user2669464 almost 10 years
    Thanks for all of your help so far. I'm getting closer to my goal, but there seems to be another problem now (they just never stop). I've updated the original question to include the new error. If you can shed any light on this, I'd be grateful. Thanks!
  • Nitin
    Nitin over 9 years
    @PeterLyons Thanks a million times.. You saved my life.
  • Braelyn B
    Braelyn B almost 4 years
    Your dist folder should definitely be ignored. And your bower_components folder is almost certainly better off ignored as well. Both of these are generated when building, so they shouldn't ever need to be pulled from source control