Search code examples
node.jstheorydirectory-structureserverside-javascriptfile-structure

How to structure Models and Views in NodeJS?


I am writing a NodeJS based server- and client-side JavaScript application. I have Controllers, Models, Views and Presenters. The problem I am facing is that some parts of the code need to be only server-side, some client-side and some both.

For example, Controllers are pure server-side thing for me so they should not be available client-side. Presenters, on the other hand, are pure client-side thing so should be available in client-side.

Take a look at my current bad structure:

project\
project\public\index.js
project\public\images\
project\protected\controllers\
project\protected\models\
project\protected\views\
project\protected\presenters\

The problem I face is that public folder is the document root and protected is outside of the document root. I need to be able to use Views in both client- and server-side. So, my Views can't be in protected. The same applies to models and tons of other things. I need to be able to access them client-side too.

I am starting to think I have to put the entire structure under document root with the exception of some configuration file. Is this what I should do? Are there any problems with this approach? I am asking because most web frameworks (Django, Zend Framework) work the way that the framework is outside of the document root.


Solution

  • My github structure (out-dated)

    -- Main level
    project\
    -- Your main app. Keep light
    project\app.js
    -- All your configuration, development/production setups
    project\app-configure
    -- Your server-side controllers/routing. Keep light
    project\controllers\
    -- Any WebSocket specific code.
    project\socket-io\
    -- Server side test
    project\test\
    -- Your public folder. Client side can access these files.   
    -- Serve this folder as static content
    project\public\
    -- I keep my backbone collections here. Used on both server & client
    project\public\collections
    -- public css files
    project\public\css
    -- public js files. Including a main.js to bootstrap the router
    project\public\js
    -- public models used on both server & client.
    project\public\models
    -- client side router, used to router hashbang urls. Can use same routing
    -- logic as the server. This is virtually a second set of controllers around
    -- All your models
    project\public\routers\
    -- public tests. QUnit based
    project\public\test\
    -- View files
    project\public\views
    -- Templates used to render HTML. Used on client & server
    project\public\views\templates
    -- Backbone view files. Used to code up interaction, and business logic
    -- This uses templates to render HTML and DOM events to handle interaction
    project\public\views\backbone-views
    

    This is based on express and backbone. Controllers are express-controllers public\routers are client-side routing using davis

    Basically because the MVC is so heavily re-used across client and server, the only thing that's not public are server-side tests and the server-side controllers. As well as the configuration settings and any socket-io based code.

    My advice is simple anything that's used in both goes in \public\

    Because MVC re-use on both the client and the server is a new thing, there aren't any examples you can look at. Apart from hunting for big open source node.js websites on github.