15

I'm new to Node but am enjoying myself so far. I was trying to move my node_modules (libraries) directory outside of the public 'webroot' and need advice and guidance.

I've setup my simple expressJS based Node project as follows:

/my_project
  /config
  /public          
     /node_modules
     server.js

I was wondering if there was any way I could have the /node_modules dir outside of my webroot and not break my application. I'm just so used to keeping the bare minimum in my publicly exposed webroot and don't feel right with the libs being in there. Call me old fashioned but that's how I'm used to doing stuff in the PHP and C# world.

If I setup the project as follows:

/my_project
  /config
  /node_modules
  /public          
     server.js

then it all goes wobbly and Node's require() magic breaks.

I've tried the following:

var express=require('../express'); which doesn't work either giving me the 'Cannot Find module' type error.

  1. Is what I'm asking even possible, if so then how?
  2. Are there any major risks with me having my libs in a webroot or have I missed something fundamental here with the way Node works.
  3. What do you guys do, what is best practice for production apps? May I have some examples of your production practices and why.
Jujhar Singh
  • 3,641
  • 5
  • 29
  • 38
  • `var express = require('../node_modules/express');` does seem to work. It does seem a bit clunky though. I'm still very much interested in what you thing is best practice. – Jujhar Singh Mar 20 '13 at 11:07
  • 2
    require('express') should still work. See [this handy post](http://www.bennadel.com/blog/2169-Where-Does-Node-js-And-Require-Look-For-Modules-.htm). Especially this part: "If the given module is not a core module, Node.js will then begin to search for a directory named, 'node_modules'. It will start in the current directory (relative to the currently-executing Javascript file in Node) and then work its way up the folder hierarchy, checking each level for a node_modules folder." So it seems your problem is somewhere else. – Andreas Hultgren Mar 20 '13 at 11:10
  • 2
    On a side-note, it's common practice in node to put files that can be accessed by clients in /public. server.js should probably not be. – Andreas Hultgren Mar 20 '13 at 11:11
  • You're right require() still works if node_modules is up one level. Turns out I was using the config library which is borked on npm for some reason. I'm still interested in best practice though so I'll leave the question open and see what responses come in. – Jujhar Singh Mar 20 '13 at 11:33
  • Question 3 is not a good fit for SO as it may have several correct answers. However I can't find a good answer on #2 already, so I'll post an answer on mainly that in a minute. – Andreas Hultgren Mar 20 '13 at 12:22
  • You SHOULD NOT store `server.js`, `node_modules`, or any of you server-side code in you `public` directory. – Leonid Beschastny Aug 13 '14 at 14:47

1 Answers1

8

1. Is it possible to have modules in a folder outside of the project

Yes.

2. Are there any major risks with having modules in a webroot?

Assuming that you by "webroot" mean in the root of the server or any folder outside of your project: yes. It is possible to install modules globally with npm using the g-flag: npm install -g express. This generally considered bad practice as different projects may depend on different versions of the same module. Installing locally allows different projects to have different versions.

If you're using version control and don't want to check in the external modules, a common (and standard in npm) pattern is to ignore ./node_modules and specify dependencies in a package.json file.

3. "What is best practice for production apps?"

Not a good fit for SO, but since I'm at it I'll give it a shot anyway. If you use grunt (a very popular task automation tool) you'll usually end up with a structure like this:

/my_project
  /node_modules
  /lib
    # actual project files
    /public
      # files that are meant to be sent to clients
  /test
  package.json # specifies dependencies, main script, version etc
  README.md # optional

This structure has the advantages of clearly separating core files, dependencies and any tests while keeping it all in the same folder.

Andreas Hultgren
  • 14,763
  • 4
  • 44
  • 48
  • Thanks Andreas, I'll give grunt a go. – Jujhar Singh Mar 20 '13 at 13:09
  • 1
    Couple of points to consider. If storing modules alongside an individual project, the file paths may end up breaking the 255 char limit on Windows. This was my main reason for storing them at a higher directory level, see here: http://stackoverflow.com/questions/13318364/how-to-deploy-node-js-application-with-deep-node-modules-structure-on-windows. Additionally there are downsides of not checking in your modules, an update to `imagemin` once broke my build process. http://stackoverflow.com/questions/11459475/should-i-check-in-node-modules-to-git-when-creating-a-node-js-app-on-heroku – Adam Marshall Apr 08 '14 at 09:09
  • 1
    @AdamMarshall Yes I suppose using `npm shrinkwrap` is a good a good practice alongside not checking in node_modules – Andreas Hultgren Apr 08 '14 at 10:03
  • 5
    "Is what I'm asking even possible, if so then how?" No "how" in the "Yes" answer – Stefan Anghel Jan 20 '16 at 11:29