Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the best practices for structuring a large Meteor app with many HTML template files? [closed]

Tags:

meteor

As in the unofficial meteor faq, I think it pretty much explains how to structure a large app:

Where should I put my files?

The example apps in meteor are very simple, and don’t provide much insight. Here’s my current thinking on the best way to do it: (any suggestions/improvements are very welcome!)

lib/                       # <- any common code for client/server.
lib/environment.js         # <- general configuration
lib/methods.js             # <- Meteor.method definitions
lib/external               # <- common code from someone else
## Note that js files in lib folders are loaded before other js files.

collections/               # <- definitions of collections and methods on them (could be models/)

client/lib                 # <- client specific libraries (also loaded first)
client/lib/environment.js  # <- configuration of any client side packages
client/lib/helpers         # <- any helpers (handlebars or otherwise) that are used often in view files

client/application.js      # <- subscriptions, basic Meteor.startup code.
client/index.html          # <- toplevel html
client/index.js            # <- and its JS
client/views/<page>.html   # <- the templates specific to a single page
client/views/<page>.js     # <- and the JS to hook it up
client/views/<type>/       # <- if you find you have a lot of views of the same object type
client/stylesheets/        # <- css / styl / less files

server/publications.js     # <- Meteor.publish definitions
server/lib/environment.js  # <- configuration of server side packages

public/                    # <- static files, such as images, that are served directly.

tests/                     # <- unit test files (won't be loaded on client or server)

For larger applications, discrete functionality can be broken up into sub-directories which are themselves organized using the same pattern. The idea here is that eventually module of functionality could be factored out into a separate smart package, and ideally, shared around.

feature-foo/               # <- all functionality related to feature 'foo'
feature-foo/lib/           # <- common code
feature-foo/models/        # <- model definitions
feature-foo/client/        # <- files only sent to the client
feature-foo/server/        # <- files only available on the server

Find out more: Unofficial Meteor FAQ


I agree with yagooar, but instead of:

client/application.js

Use:

client/main.js

main.* files are loaded last. This will help ensure that you do not have any load order issues. See the Meteor documentation, http://docs.meteor.com/#structuringyourapp, for more details.


Meteor was designed so you structure your app pretty much any way you want to. So if you don't like your structure, you can just move a file to a new directory, or even split one file into many pieces, and to Meteor its pretty much all the same. Just note the special treatment of client, server, and public directories as specified in the main documentation page: http://docs.meteor.com/.

Just lumping everything together in one HTML fill will certainly not emerge as a best practice.

Here's an example of one possible structure: in one of my apps, a discussion forum, I organize by module or "page type" (home, forum, topic, comment), putting .css, .html, and .js file for each page type together in one directory. I also have a "base" module, which contains common .css and .js code and the master template, which uses {{renderPage}} to render one of the other modules depending on the router.

my_app/
    lib/
        router.js
    client/
        base/
            base.html
            base.js
            base.css
        home/
            home.html
            home.js
            home.css
        forum/
            forum.html
            forum.js
            forum.css
        topic/
            topic.html
            topic.js
            topic.css
        comment/
            comment.html
            comment.js
            comment.css

You could also organize by function

my_app/
    lib/
        router.js
    templates/
        base.html
        home.html
        forum.html
        topic.html
        comment.html
    js/
        base.js
        home.js
        forum.js
        topic.js
        comment.js
    css/
        base.css
        home.css
        forum.css
        topic.css
        comment.css

I hope some more specific best practice structures and naming conventions do emerge though.


Lump it all together! From the docs:

> HTML files in a Meteor application are treated quite a bit differently
> from a server-side framework. Meteor scans all the HTML files in your
> directory for three top-level elements: <head>, <body>, and
> <template>. The head and body sections are seperately concatenated
> into a single head and body, which are transmitted to the client on
> initial page load.
> 
> Template sections, on the other hand, are converted into JavaScript
> functions, available under the Template namespace. It's a really
> convenient way to ship HTML templates to the client. See the templates
> section for more.

For everybody who's Googling on this topic:

The em command line tool (by EventedMind, the guys behind the Iron Router) is very helpful when rigging a new Meteor App. It will create a nice file/folder structure. If you already work on an app and want to re-organize it, just set up a new project with em and you can use it for inspiration.

See: https://github.com/EventedMind/em

And here: https://stackoverflow.com/questions/17509551/what-is-the-best-way-to-organize-templates-in-meteor-js


I think the file structure from the Discover Meteor Book is really good and a solid start.

/app: 
 /client
   main.html
   main.js
 /server 
 /public
 /lib
 /collections
  • Code in the /server directory only runs on the server.
  • Code in the /client directory only runs on the client.
  • Everything else runs on both the client and server.
  • Files in /lib are loaded before anything else.
  • Any main.* file is loaded after everything else.
  • Your static assets (fonts, images, etc.) go in the /public directory.

Create packages

Of course not everything fits in this approach, but in large apps you'll have a lot of functionalities that can be isolated. Anything separable and reusable fits in packages, the rest goes in the usual directory structure, as mentioned in other answers. Even if you don't make packages to avoid the overhead, structuring the code in a modular manner is a good idea (see these suggestions)

Meteor allows a fine-grained control over how you load your files (loading order, where: client/server/both) and what the package exports.

I especially find very handy the easy way to share the logic between the related files. Say, for example, you wanna make some util function and use in different files. You just make it "global" (without the var) and Meteor will wrap it in the namespace of the package, so it will not pollute the global namespace

Here's the official doc