Alternate file structure

I find the recommended file structure at https://guide.meteor.com/structure.html#example-app-structure to be the opposite of elegant. I do not want to have two directories called client and two called server. I don’t want two index.js and two main.js . I want a structure that will make sense to someone viewing the tree who has never used meteor before.

So, is there a way to turn off autoloading and make all of my app behave like the imports directory? Or define my entry points for client and server side, a package.json or something?

1 Like

There is a flaw in your thinking pattern. Yes. Typically applications have just one index.js / main.js. However, those are almost never full stack applications. If they are full stack, it usually means that the index.js contains a serverside script that eventually somewhere loads the clientside script that on its turn loads the index.js file for the clientside. This means that the clientside entry point is pretty much hidden which makes it actually more difficult to understand.

Yes there is something to say about the structure. Meteor’s earlier versions required files to be structured in a certain way to provide a certain load order. However since 1.3’s import functionality became available, this way of working became obsolete. Right now you can choose. Every file in the import directory is being ignored until you explicitly import them. In the root directory it might require you to have 2 files: server.js and client.js. However those 2 files usually never come alone, so Meteor recommends it to be a folder with a main.js.

Keep in mind that a package.json only lives on the serverside. This means that there would be no way to provide an entry point in any form for the clientside files! I think Meteor’s recommended structure is as elegant as it can get. Its both useful and clear to any developer and newbie that flies by.

That doesn’t mean however that you can’t create your own file structure!

I’m always thinking about this stuff and tell myself:

Does me not being used to it make it less elegant, unusable, ugly, weird, less efficient? If the answer is no then I basically have to deal with it until i’m used to it.

I think that’s a legitimate ask.

1 Like

I think that’s a legitimate ask.

Hmm I got caught up on the first paragraph and missed that important detail. You’re right. Sorry about that. :slight_smile:

1 Like

Hi, welcome to Meteor.

May I make the suggestion, that if you’re here never having seen Meteor before, it should be confusing. I’ve been studying Meteor for about 2 years now. It’s a steep curve.

The /client and /server folders are not optional.

There are calls that are allowed on the client, and calls explicitly allowed on the server.

If you’re learning Meteor, you don’t have to worry about security. It comes with AutoPublish, so you can just start writing to the DB.

Let me say it once again, try NOT to fight against the way Meteor does things. Instead, empty your mind and learn it anew; it will pay you dividends in the end.

I mean, I had assumed the imports directory was a temporary kludge while transitioning to modules and it would be gone soon, but we’re on the eve of 1.5 now so I’m wondering what the plan is for that and whether there’s a way to get a simpler file structure.

I refactored my project (which I’ve frequently had to upgrade to track meteor since I started it in April 2014, simpler times) to match the 1.3 guide. One thing I tried to simplify the structure is instead of the recommended entry point files:

/server/main.js
/client/main.js

, I used /client.js and /main.js as entry points. I think I used to do it that way for small apps. It doesn’t seem to work the way it used to though, I guess client.js and main.js are no longer treated as special file names so they seem to run on both the server and the client in less wrapped in if isServer , and also my imports from /client.js to /imports/client/index.js are failing and I’m not sure why – perhaps it’s only happening when client.js is run on the server and /imports/client is not accessible.

So yeah, I guess the answer is that I’m stuck with the ugly file structure. I hope there’s more flexibility in future releases.

PS - In retrospect, my initial post seems whiny and I should have led with the question. Nevertheless, @cloudspider and @SkyRooms, you guys sure are quick to reach for the pedantry! Reminds me of this: https://github.com/meteor/meteor/issues/7424

You’re right @foobarbecue. In some occasions we might be a bit defensive when it comes to negative attitudes towards Meteor. Its not a personal thing though. The defensive attitude originates from a couple of topics both on this forum and talks that I had with other developers. Its mostly an aggressive ‘no’ towards Meteor while they either didn’t take time to investigate what problems Meteor solves or because they stumbled upon some kind of generic issue that any developer in any system would face.

I’m not talking about people that come here with questions or concerns regarding Meteor’s design choices or roadmap (which was in retrospect also your case)

Just a small comment on the closed github issue

You’re right, Installing a Meteor distribution in your home directory is the relevant part of the message. Something factual like meteor installation not found before that would be fine. But get rid of the weirdly condescending unprofessional exclamation of noob-courtship.

Besides the tone of voice used in that last sentence. As an experienced Meteor developer I still like that message. Its personal, its welcoming and friendly. I don’t care if it shows in my command line multiple times. Its not happening during ‘build and deploy on my servers, because when following the docs you will read “For custom production deployments its best to user Meteor’s build tool”’. This is essentially converting meteor to be a Node app which removes the need to remove Meteor on your servers avoiding the “weirdly condescending unprofessional exclamation of noob-courtship”.

Btw is noop-courtship a bad thing? I love noobs as long as they admit :wink:

Last but not least. As a developer working for a lot of stakeholders in bigger project I can tell you why this triggered @abernix and made him give a somewhat annoyed reply. As developers we get a lot of comments about texts that are shown to users (from MDG and Meteor contributor perspective we are in fact users). Most of these text are carefully crafted with a certain goal in mind. In this case Abernix shares that goal clearly, but a bit sarcastically:

I’m pretty sure the next message after that is Installing a Meteor distribution in your home directory which aside from the formalities of Meteor trying to be polite and get you excited, is really the relevant part.

Its a hint

None the less, I hope we’re good and again. Sorry for the tone of voice if it seemed to come over as offensive. Just here to help and clear answers with context and motivation. :slight_smile:

I am refreshing my Meteor skills doing the new tutorial and have related question:

Now tutorial suggests putting

import '../imports/api/tasks.js';

in client/main.js and the same string in server/main.js

I have seen at https://github.com/Differential/meteor-boilerplate structure which is IMHO more neat:

folder both
which has underlying folders:

accounts
collections
controllers
router

As I have checked ‘both’ folder (and any other folder outside client/server) still works both on the client and on the server and it may be a good configuration to see everything, which is both client/server side in one place. Don’t copy yourself, isn’t it?

P.S. New fresh boilerplates, anyone? :slight_smile:

I have seen at https://github.com/Differential/meteor-boilerplate structure which is IMHO more neat:

I’ve used that one for a while. It works great for smaller apps or bigger apps < 1.3, after that I started experiencing some downsides, especially in combination with schema’s and load ordering. For example, I wanted to decouple my collection loading from schema loading and schema attaching. This required me to put them to subfolders etc.

Another format that I like is domain based. Everything related to the same problem domain should be put in the same folder:

For example everything related to an article (1 domain):

imports/article
imports/article/methods
imports/article/collections
imports/article/collections/article.js
imports/article/collections/author.js
imports/article/collections/category.js
imports/article/ui/components
imports/article/ui/components/article.js
imports/article/ui/components/comment.js
imports/article/ui/pages
imports/article/ui/layouts
imports/article/server/publications
imports/article/server/methods
imports/article/server/config.js
imports/article/main.js
etc...

My root would look like:

/client/router.js
/client/main.js
/server/main.js

Very self contained and perhaps even a candidate for a generic package

1 Like

I would even say ‘imports’ directory can be replaced by something more elegant like ‘components’, more descriptive. For me imports directory would mean true ‘imports’ from somewhere else.

I agree. The reasoning behind ‘imports’ is the way meteor handles file loading. Putting it in the imports directory will not load them unless specifically ‘imported’ from another file. In my case that would be server/main.js loading the imports/article/server.js file

I really like the modules/domain based file structure. It’s very similar to the old package-based approach with an index.js at the module-root just like the old package.js :slight_smile: . I use a very similar one in all my bigger projects and found that it scales much better than the one from the guide for example. For a smaller one it might be overkill, but as the project grows you’ll want to keep together what belongs together in terms of functionality. Also, it’s really easy to add/remove features.

One thing though, when you put your components and other client side stuff outside of a client folder you’ll loose the nicety of fast client reloads. To fix this, I re-added a client folder within my imports so that the structure is e.g. /imports/articles/client/ui/components/...' or /imports/articles/client/redux/, which assumes that you don’t need any of that stuff on the server (no SSR).

1 Like

One thing though, when you put your components and other client side stuff outside of a client folder you’ll loose the nicety of fast client reloads. To fix this, I re-added a client folder within my imports so that the structure is e.g. /imports/articles/client/ui/components/…’ or

I did exactly the same, but didnt want to obfuscate the file structure that would be ideal to me, not taking into account that bug :joy:

1 Like

So, what is your ratio between imports/both directory? I suspect that for most scenarios 80% of the code is in the imports folder?

I understand that current directory structure is written aka ‘convention over configuration’ but probably making it explicit in one of the future versions would help a lot. Simple configuration file like this would replace any need for long docs and would make the configuration easy (I am not writing it like JSON but as rough draft, backslash is for bullet escaping purposes):

/* client, server

client client

server server

imports lazy-load

clients/main.js client-entry

server/man.js server-entry

it seems similar to Apache configuration and is self-descriptive

Then instead of lengthy confusing documentation it would be sufficient to write:

Build program follows set of 6 rules using 5 variables (see above). Everything else is recommendations.

Maybe they are currently hardcoded and maybe such configuration even exists somewhere hidden inside Meteor build system.

BTW, are these 6 rules the only ones used by build tool in Meteor 1.4. Or have I missed something?

Then instead of lengthy confusing documentation it would be sufficient to write:

That’s exactly why docs.meteor.com exists. The file structure recommendation though exists in guide.meteor.com. Here are the 2 direct links relevant to this particular topic:

BTW, are these 6 rules the only ones used by build tool in Meteor 1.4. Or have I missed something?

Not really for as far as I know. Just keep in mind that everything outside of the imports folder practically works like it worked in <1.3. Nothing is set in stone. They are purely recommendations. On the guide they are detailed and opinionated recommendations, because that what’s proven to work in most cases

Wrong. They are entirely optional: as are any and all of the special folders.

It’s better to think of Meteor’s folder conventions as opt-in configuration, rather than mandated requirement.

1 Like

Doesn’t not using client/ and server/ cause issues with the file watcher though? So that it restarts the server even when client files are modified.

Correct: I never said there wouldn’t be consequences :wink:

However, if I’m writing a server-only application I don’t need a client/ folder. Similarly, a client-only application doesn’t need a server/ folder. If I’m writing a package-based application, all client and server splitting is done at the package level, so neither client/ nor server/ folders are needed.

One of the reasons I love Meteor is that it’s possible to balance requirements with architecture and structure. As long as you understand what the consequences are, the code can be structured in many ways and it works absolutely predictably.

Of course, that’s also why people struggle. With great power comes great responsibility. If you don’t take the responsibility to understand Meteor (and there’s a lot to get to grips with) you’ll never get the best from it.

2 Likes

Yes! Definatley for DEVELOPMENT stage apps! Which I have to say is super annoying the larger your app becomes… the longer it takes to recompile. I’ve just gotten ‘better’ at coding so things work better in general but still, sucks.

But on Production, you don’t get this sort of hot push behavior unless you’re doing a build update.

Welcome to Meteor… yeesh.