Search code examples
node.jsexpresshandlebars.js

How to use a .js file outside of the public folder in Node Express App?


I am new to node express and would like some help to get below resolved.

Below is my project structure for Node express Application

Folder structure:

1

Below is my app.js code

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 index = 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', 'hbs');

// 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('/', index);
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 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;

I have a controller.js file which currently resides in the public folder (see folder structure)

I have an index.hbs file which uses the controller.js (code shown below)

<!DOCTYPE html>
<html  ng-app="test">
  <head>
    <title>{{title}}</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-route.min.js"></script>
      <script src="controller.js"></script>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body ng-app="test">
  {{{body}}}
  <!--
  <div ng-view></div>
  -->
  </body>
</html>

When I run the application this works fine.

I need to remove the controller.js file from public folder and dump it in the controller folder (see folder structure image) and then when I run the program I get the below error,

GET http://localhost:3000/controller.js 404 (Not Found)

I have changed my <script src="controller.js"></script> in index.hbs file so many ways so that I can run it without any errors but without luck.

Any suggestions would be much appreciated.


Solution

  • You have to serve everything that you want to reference in HTML.

    So you can move your code to some other directory and serve it as well, you can move it to another server, but you cannot move it to any place that is not served at all or otherwise you will not be able to load it in HTML.

    All client-side JavaScript code must be available for the client to download or it won't work. So it is not only OK to have it in a public directory - it is necessary. Of course you may want to serve it only to some of the clients but you have to serve it to anyone who gets the HTML that uses it and there is pretty much no way around it.