kadirahq / mantra

Mantra - An Application Architecture for Meteor

Home Page:https://kadirahq.github.io/mantra/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What about directory structure?

achtan opened this issue · comments

Will be Mantra opinionated about directory structure?

Hope this is answered :)

Yes is it, sort of :)
Many developers use type-based structure:

actions/
    | articleActions.js
    | commentActions.js
components/
    | article.jsx
    | comment.jsx

imho better is feature-based structure:

comments/
    | comment.js
    | commentActions.js
articles/
    | article.jsx
    | articleActions.jsx

and I'm afraid that Mantra will use first approach and that's kind of worries me :/

That's something we need to figure out first. We'll go with 1 for now.
We will have a module system, where you could keep actions, UI components and the containers in a single folder.
You can even distribute them via NPM.

But that's not coming with the initial draft. We'll have it.

+1 for the feature-based structure. I think it's a better way of laying out larger projects, and more in line with the react methodology of grouping feature based code together.

@arunoda you can maybe reopen this issue to get more opinions from people

@achtan That's a good idea.

Feature-based 👍
This reminds me about Uncle Bob's talks where he says about that architecture should reflect intent like a blueprint of a church/library, you see it and you already know what it is about. You open a source-code folder, sees post/, comment/, author/ and category/ you already knows it's about a Blog.

+1 for Feature based.

commented

+1 for Feature based

+1 I think it'll be easier to understand logic & testing flow if everything is feature-based

+1 for Featured based.

Agreed. Feature-based is probably better for scalability. I used to use a type-based structure, but an app quickly grows in size and you end up having these huge folders filled with many many files.

I'm looking to work on the module system.
Guys any ideas? @achtan gives us a one solution.

So here's my idea.

In a module, we can have it's own

  • Actions
  • Components
  • Containers

But only containers and components can be only view to the outside. (Or do we need actions too?)
We can only export one container from a each module or many.

If it's a one module we can have a directory structure like this:

* actions.js
* component.jsx
* container.js
* index.js
* tests
    - actions.js
    - component.js
    - container.js

Otherwise, thing will get a bit complicated. What do you think?

One issue that I've had in virtually every framework is how difficult it can be to stay organized when grouping code into single file compartments (e.g., 'actions.js'). My favorite solution to this so far is to turn those files into directories, and inside the directories house a file for each instance.

Taking actions as an example, rather than adding all of the actions for the module into a single file, I would have an actions directory, and each action itself would get a file inside of this directory. This makes it easy to find code you're looking for, makes each file less complicated, and clearly spells out the requirements of each action via imports (if imports are used rather than a global namespace, which seems to be Meteor's preference).

With this in mind, my ideal module would be laid out as follows:

* actions/
    * action1.js
    * action2.js
    * ...
* components/
    * component1.jsx
    * component2.jsx
    * ...
* containers/
    * ...
* tests/
    * actions.js
    * component.js
    * container.js
* index.js

The tests directory is kind of up in the air. I feel like it should be broken down, but I don't know enough about the proposed testing structure and usage to recommend if it should be or not for this use case.

Very similar to the two above comments, I have a idea writing in this Gist: https://gist.github.com/minfawang/12ca72ac36260426e46b

Within each module/feature, I have "containers, components, actions ...", but rather than just name them as "container.js", "component.jsx", etc, I put them into separate sub-directories. Then each sub-directory has the "index.js" that exports the files/functions/object/anything dependent by other files/modules. So we could still do something like import { addTodo } from 'TodoApp/client/actions'

commented

+1 for the feature based structure recommended by natecox.

@natecox and @minfawang your proposals are type-based in context of module...

@arunoda agree with you, that's a good direction!
btw: but i think we can also export some of the actions if it is necessary. For example if you have cart module in eshop maybe you will need some actions to by accessible in other modules or so...

@achtan Yeah! That's a good one. May be there are some modules, which only have actions.

There is one thing I need to clarify.
We won't have a server directory inside this

We need to make sure client and server are two separate things. But it's okay to have method_stubs like this.

@achtan Oh my bad.. Sorry for not reading the post carefully. Now I see your point.

I think both approaches have its own advantages. For the "one module" approach proposed by @arunoda I think the root directory can get cumbersome when the app grows to a large scale.

I feel actually my approach could be thought as feature and type combined based if you separate modules based on features. Currently I separate modules as different code splitting points. You can think of a module as one big feature or a set of small features.

@achtan This was within the given context of 'structure inside a module'. If you assume that modules are based on features, than this would definitely be feature based rather than type based.

Type based would be

*components
    * Todo
    * Different Todo
* actions
    * Todo
    * Different Todo

where we're suggesting

* Todo
    * components/
        * ...
    * actions/
        * ...
* Different Todo
    * components/ 
        * ...
    * actions/
        * ...

@arunoda One thing I noticed while reading the spec is that the suggestion is to put all of your components inside the client/ directory. How are you handling server side rendering for SEO in this context? I've always had to provide my components via lib/ to make them accessible for SSR.

With larger apps, things tend to get complicated very fast. Files get bloated quickly, and I always feel like I want to make many smaller components rather than fewer larger ones.

What do you guys think about modules with sub-modules approach?

- ChatModule
    | component.js
    | actions.js
    | container.js
    - ChatMsgsArea/
        | component.js
        | actions.js
        | container.js
    - ChatInputArea/
        | component.js
        | actions.js
        | container.js

- SettingsModule
    | component.js
    | actions.js
    | container.js
    - GeneralSettings/
        | component.js
        | actions.js
        | container.js
    - AdvancedSettings/
        | component.js
        | actions.js
        | container.js

@adrianmc I think we should limit to a single level of modules. Otherwise, we'll have a lot of nested modules and very hard to deal with.

@adrianmc I feel like submodules make it too easy to violate the single responsibility principle.

@natecox if you isolate this one:

* Todo
    * components/
        * ... // what will be here? todoList.js, addTodoForm.js
    * actions/
        * ... // and here? fetchTodos.js, addTodo.js

it is type base structure inside module because you separating code by type

maybe a good question would by "what is the 'Module' and what you / I / everyone think under that term"

@natecox Actually, that's a decision of Meteor's current 1.3's layout system let's talk about SSR here.
See: #11

@achtan You're right, if you look at only the inside of the structure it would be type based, but that's kind of a moot point in my opinion given the context here is what to do after you've grouped your code by feature.

I view it this way: I break my project (the entire working site) into modules (specific features of the site), and then the modules themselves into types.

From your earlier post, you're essentially doing the same thing, referencing

comments/
    | comment.js
    | commentActions.js
articles/
    | article.jsx
    | articleActions.jsx

Where 'Action' could be defined as a type as well. I'm just going a step further and making them a directory to make each file single purpose and less verbose.

@achtan @natecox let's deal with that first.

What is a module

  • In mantra, we've different types of files. They are usually components, containers, actions.
  • With a module we try to group above types of files by the application features.
  • We may be able to distribute these modules via NPM possibly.
  • We can import files and different modules each other.
  • I think it's better to have a single layer of modules. Nested modules always make it hard to reason and one way to break the simplicity of the app.
  • Since we don't have versions of modules (no we don't have it) it's safe to avoid nested modules.
  • Modules can read from the application context. But they can't write into that.

@natecox but I see your point!
lets talk about some real-world example: eshop + blog
so now we can say that eshop is an module and also the blog

eshopModule/
    | config/ 
    | lib/
    | *not sure how to name this dir* /
        | cart /
            | actions.js
            | component.js
        | goodsList /
            | actions.js
            | compnent.js
    | main.js
blogModule/
    | config/ 
    | lib/
    | *not sure how to name this dir* /
        | article /
            | actions.js
            | component.js
        | articlesList /
            | actions.js
            | compnent.js
    | main.js

i don't see the point to spliting eshopModule/**/cart/actions.js into subdir... if you have too much actions in it, its probably too big feature and you should split into several smaller

@achtan I think what you've got there is kind of enforcing submodules. Maybe moving things up a level would help:

cart/
    | components/
        | CartItem.jsx
        | CartList.jsx
        | PaymentMethod.jsx
    | actions/
        | cart-management.js
        | checkout.js
    | config.js
    | main.js
inventory/
    | components/
        | SundryItem.jsx
        | SundriesList.jsx
    | actions/
        | inventory.js
        | restock.js
    | config.js
    | main.js
blog/
    | components/
        | Article.jsx
        | ArticleList.jsx
    | actions/
        | article-crud.js
    | config.js
    | main.js

I absolutely think that components should be split up. By design React already has a fairly complicated structure, because you're inherently grouping together design and functionality (which is great, but increases code in one location). In my experience, it's much easier to work with components if they're limited to a single component per file.

Maintaining convention between component structure and action structure encourages that single purpose principle's usage, which is a positive to me. However, I see the argument as well that there shouldn't' be all that much in actions by design, so I could take it either way.

As another example, here's what I have that make up a logical "modules/features" - currently scattered across many directories:

  • React components: 1 jsx file per component - I have different types of components:
    • non-UI: data fetching, theming, etc.
    • UI stateful (that maintain internal UI state, like a form that is not yet submitted)
    • UI stateless (fully prop-driven)
  • I have switched to inline styles, so styling is in my jsx files but if we also use css/sass, we also have these files
  • Meteor "models": 1 file per model, inside it:
    • collection definition: Posts = new Mongo.Collection('posts');
    • schema: Posts.attachSchema(...); from collection2 / simple-schema
    • helpers: Posts.helpers(...); from collections-helpers
  • database modifier scripts
    • migrations from collection2-migrations
    • database init scripts, to perform initial load from file or other sources
  • pub/sub: publication in server/, subscription in client/
  • files: in private/ (for data loading for example) or public/ (images, pdf documents, etc.)
  • module specific library of utility objects/functions

And what I would leave out of modules:

  • routing
  • init script calling the module init scripts in the right order
  • global app layout (assembling components from the module and passing them props and context)
  • configuration/settings

I'm wondering how Mantra will handle the server/client stuff - any idea yet? Should it be a new Github issue?

@xavierpriour Mantra sees both client and server as a two separate places. Have a look at the spec and the sample app.

@achtan Good discussion so far. I'm heading to bed and will check on this again in the morning (it's like 3am here).

@arunoda
Seems like there's some good community involvement incoming. You should consider getting a slack group opened for this project, or some other alternative.

@natecox I don't like chat systems since whole communication get lost and not public. Let's try to keep it here. If we need more, I'll create a discourse server.

@arunoda ok, sorry I had missed it. Should a Mantra module be able to contain both server and client code? Or is it just client-side?

@xavierpriour Just client side. We need to separate the server. That's the future specially with stuffs like React Native, GraphQL (declaritive way to defining data) and more reasons to tell :)

@arunoda oh ok - mind if I update the spec on Modules to make it explicit they're client-side only?

@arunoda will there be a way to use mantra/modules in packages? on big project you want to bundle feature based functionality, this means client and server code in case of meteor.

@xavierpriour it's not only modules but everything. Yeah. Send me a PR.

@appinteractive That's the whole point in this thread. We are collecting ideas. But that's only for the client.
Modules can be distributed via NPM. (not via Atmosphere)

@arunoda I thought I heard this a few places, but is Meteor (and/or Mantra) not recommending Atmosphere at all anymore, and switching everything to NPM? I'm assuming so, but wanted to confirm so I can start preparing for that.

Yes. Atmosphere will die sooner or later. It's not a bad thing. It will
take a time to happen.

That's why we are staying out of it.
On 2016 ජන 12, අඟහ at ප.ව. 8.45 Mark Shust notifications@github.com wrote:

@arunoda https://github.com/arunoda I thought I heard this a few
places, but is Meteor (and/or Mantra) not recommending Atmosphere at all
anymore, and switching everything to NPM? I'm assuming so, but wanted to
confirm so I can start preparing for that.


Reply to this email directly or view it on GitHub
#3 (comment).

commented

@arunoda thank you for Mantra, another great community contribution!

As to the directory structure and module separation I adopted this pattern pattern in Meteor when using kickstart-hugeapp. This boilerplate has "modules" folder and each subfolder can contain its own separate client and server directories. It's pretty neat.

But my understanding is that in Mantra we need to keep the server separate, is that correct?

@makstr That's what's I'm planning to do without the server part.

@arunoda what's your thought on modules which needs client and server code? For example, they need to define a Meteor.method in the server:

cart/
    | client/
      | components/
          | CartItem.jsx
          | CartList.jsx
          | PaymentMethod.jsx
      | actions/
          | cart-management.js
          | checkout.js
      | config.js
      | main.js
    | server/
      | cart-methods.js

@luisherranz we really need to keep server code away from here.
If we need to get latency compensation support, we can define the method stub here on the client like this.
See: https://github.com/mantrajs/mantra-sample-blog-app/tree/master/client/configs/method_stubs

If needed, you can put these methods on a common directory and import on both client and the server.
But for Mantra it's just a configuration.

Ok, so you mean Mantra needs a root client and a root server folder and those can't be mixed up inside modules, is that right?

Exactly.
I'm working on a new update to the spec the module system and some other improvements. Will publish it on monday.

@luisherranz If you are confused about this decision. It has a reason. Mantra believe in isomorphic concepts/modules rather isomorphic apps. May be it's a good topic for a blog post :)

Kudos @arunoda and the @kadirahq team... like others I've also been suffering from the current disarray and it's awesome to be able to start the year on this positive note.

+1 for feature directory structure, +1 for discourse over slack (if needed)

Personally I'd love one level of nesting for modules (or at least, allow subdirectories per feature inside of a module). That's pretty similar to current practice for big projects , i.e. 1 meteor package per feature. I'm thinking long term, where, say we have an npm blog module, and the module has directories per feature/view (say blog/index, blog/admin, blog/composer).

@arunoda (cc: @luisherranz), can you explain more why you'd like server code separate? (sorry, you posted the above as I was writing this but I still don't get it - but maybe i'll wait for the blog post)

It's great to keep all related code within a single module directory, and if we're aiming for modules that could potentially be re-distributable on npm, it would be great to have a single module that handles everything. i.e. npm i --save mantra-blog and it just works, this is one of the things I loved most about the Meteor ecosystem. Otherwise what would you suggest? Two npm packages for this?

@arunoda don't worry, thanks.

@gadicc yes, I think the npm packages structure should go on the spec.

@gadicc I could give write more on this. But here's a summery. I don't believe in isomorphic apps. It's just a shortcut.

Mobile experience and Web experience are two different things. So, we always need multiple apps. Even if you go with the cordova path, using two apps makes it easy to work with your project in the long run.

You won't have any hijacks for both web and mobile. You'll re-use what you can use in both places (via modules)


So, this concept give us many client apps(cordove, web, react-native) and a single server. That's why we are not sharing server side code with the client. But method stubs is a different things. It's a configuration for Meteor's optimistic updates system. When you are using GraphQL with your app this makes a lot of sense. Meteor will be all GraphQL by end of 2017.
That's why I want to make Mantra ready for that. (I'm done with re-writing apps)

I'll write more on the blog post.

Thanks, looking forward to the blog post! It's a different way of thinking in the Meteor world, but I'm also done with re-writing apps and value your insight.

@natecox ok I changed my mind! I agree with your proposal: #3 (comment)

is't better that way :)

Okay guys, sees like now we've solid way to model Mantra modules. (I'm open to a better name for this, since module is used for individual files as well).

Here's how it works.

  • On the top level, we'll have a directory structure as usual. That's to put whole app specific stuff.
  • Then we've a modules directory where we can group code feature wise.
  • We can't have submodules.
  • We can ship modules via NPM
  • You can't add items to the application context inside a Module. That means, module uses what application already provided. Let's say you are using a collection called Posts inside the module, then the app should provide it on the application configuration. Module should use it. But it should not create it.
    If we are distributing this over NPM, we need to provide a list of dependencies we are looking for in order to use this module.
    (We can do this automatically and verify modules once we've the mantra-linter)

I use to use Laravel, it support module call workbench.
👍 module for mantra.

Why are the library directories within the client and server called libraries rather than libs? Is it to avoid issues with Meteor's load strategy? If it isn't it seems more sensible to me to use the same term when the things are similar – otherwise I end up wondering what is different between libs and libraries.

My two cents:
I think the current one is good already. Although when feature-based structure is good, it is not good if you want to create reusable react stateless components. Especially if you use something like Brad Frost's Atomic Design.

I also like the modular structure... what I have in mind though (and I am practicing it in 2 of my projects) is this (I added Brad Frost's Atomic Design idea):

project-directory/
| app/
|    | app-1/
|    |      | client/
|    |      |       | app-1-module-1/
|    |      |       |    | actions/
|    |      |       |    | components/ # reusable react stateless components specific only to app-1
|    |      |       |    |      | atoms/
|    |      |       |    |      | molecules/
|    |      |       |    |      | organisms/
|    |      |       |    |      | templates/
|    |      |       |    | configs/
|    |      |       |    |      | pages/ # I didn't put all routes in routes.js,
|    |      |       |    |      |        # I import them from files inside pages/
|    |      |       |    |      | route.js
|    |      |       |    |      | context.js
|    |      |       |    | containers/
|    |      |       |    | main.js
|    |      |       | app-1-module-2/ # same structure as app-1/client/app-1-module-1
|    |      | lib/ # this is app specific already
|    |      |    | collections/ # all meteor collection parts used in this app are put here
|    |      | server/ # this is app specific already
|    |      |    | fixtures/ # all initial data are put here
|    |      |    | methods/ # all CRUD methods are here
|    |      |    | publications/ # all publications are here
|    | app-2/ # same structure as app-1
| lib/
     | client/ # same structure as app-1/client,
     |     |   # but the idea is that all components are used by all apps above
     |     | general-module/ # this is where I put all general components...
     |                       # just like app-1/client/app-1-module-1
     | lib/ # same as app-1/lib
     | server/ # same as app-1/server

I extended the idea where you can also "install" app with specific modules. You can also install just the general-module which is used by all apps... What do you guys think?

I have my sample idea in this project: https://github.com/tjmonsi/project-sarai

Hi guys, here's the module structure on Mantra. I haven't put it to the spec. I thought it's a good idea to put it here first. See: https://github.com/mantrajs/mantra-sample-blog-app/tree/mantra-modules

Here it is:

  • Basically, now we must put all out client code inside a module except for some configs like routes and context.
  • It's designed it a way that, you can distribute the module via NPM.
  • It also come with a new library, which wraps all the mantra related packages and some utilities.
  • Now we use imports directory, it's a way to support SSR in the future.

What do you think?

I like the imports directory. But i'm a bit wishy washy about feature-based
modules/components. That would mean the same component is only limited for
that feature and cannot be used for a different purpose (like if it is a
post, but can also be used as a blog.. Or even a news article)

For example i have a component which is a headline:
Title
Gist
Read more..

It can be used as a small component as a list of headlines (like in a blog
landing page or home page) or a news alert at the banner...

I feel that feature based should be the containers (content design)...
While the component based should be the components (template/layout design)

On Fri, 22 Jan 2016 18:36 Arunoda Susiripala notifications@github.com
wrote:

Hi guys, here's the module structure on Mantra. I haven't put it to the
spec. I thought it's a good idea to put it here first. See:
https://github.com/mantrajs/mantra-sample-blog-app/tree/mantra-modules

Here it is:

What do you think?


Reply to this email directly or view it on GitHub
#3 (comment).

@tjmonsi It's feature based. Modules are feature based.
It's exactly as we discussed here. You can put group modules by features.

You can use containers, components and actions between modules each other.

@arunoda, big fan of the mantra-modules branch, looking good! 👍

Ill try a different approach but in a modules way as well... But lets
see... :)

On Fri, 22 Jan 2016 20:10 smeijer notifications@github.com wrote:

@arunoda https://github.com/arunoda, big fan of the mantra-modules
branch, looking good! [image: 👍]


Reply to this email directly or view it on GitHub
#3 (comment).

Structure looks good to me. I wish there were a more intuitive way of providing the client information for SSR without having to throw everything into imports/, but I guess it's not much different than having to throw it all in lib/.

@arunoda good work on the modular structure. I really like it. Yet, I do not understand where the server code gets imported. Does it get imported somehow automatically by meteor? There are no explicit imports. Coming from webpack world it seems a bit confusing. Thanks!

@natecox has a one little difference. When when put it lib it always runs on the server. There are some apps who don't use SSR and they may use some code specific to clients.

So, when we put them to lib those get executed. But by putting them to imports does not. That's the only reason.

@tomitrescak In Meteor everything in the server got imported (or places outside imports). Let's see what we can do for that as well.

@tomitrescak everything in the client also gets imported, if they aren't placed inside imports directory. See http://docs.meteor.com/#/full/structuringyourapp

@arunoda and everyone, I did a modified structure of Mantra to test my point

  • making a npm-module-able generalized stateless ui components list,
  • an npm-module-able generalized posts and comments modules (to get the data),
  • and a developer-created containers to match the data got from posts and comments modules to the generalized stateless ui components

I would like to get your opinions about it: https://github.com/tjmonsi/mantra-atomic-structure-suggestion

Guys,

We are finalizing the module system and now it's almost ready. But, we need to figure out a decision regarding routes. Could you have a look at this?

See: mantrajs/mantra-sample-blog-app#24

@arunoda Could you explain why you prefer to restrict Mantra modules to being client side only? It seems to me that a “module per feature” model would benefit from Meteor-like “universal” modules.

In the future, there won't be any server code we need to manage. (Or we don't need to).
We can simply use some GraphQL queries for that.

So, mixing server and client code together is a really bad idea.
And I'm strictly opposed to universal apps.

I disagree in that I see some value in modules being able to define some client and server logic. A central argument in your article against “universal apps” is against “single codebase that runs everywhere” which is really not my point here. Similarly I could agree with “mixing server and client code together is a really bad idea”, but this is easily solved by putting code for different targets in different files.

So maybe we don’t have the same definition of a module, but for me it is important that they are able to send emails, define new GraphQL mutations, or start backgrounds tasks, all of which happen on the server. I can go into more details if the examples I’m giving aren’t clear (and if you have some time you can take a quick look into a description of my desired plugin system for Wekan).

I always though about universal apps as client code running everywhere. Is clarifying to read about universal apps as code shared between client and server too, seeing them mixed and loaded twice (in the browser and in the Node) was something that really bugged me on my way learning Meteor.

On the other hand, I think that this is one of the Meteor core ideas. If I start to think in server and client code separated, glued by something like GraphQL I don't know why I even will be using Meteor instead of a Node/Express solution like Relay or my own.

Splitting server and client code and not thinking universally isn't Meteor-counter productive? Why to use Meteor if you will be avoiding Meteor features?

@leocavalcante this is a core principle of mantra, so it will never change. I do think it was one of Meteor's core ideas, but I think even MDG is moving away from this practice as it doesn't work in the long term.

Think of React/frontend as just the view layer, as it is. Then Meteor/server as the backend/API that is called. The two aren't and really shouldn't be related. Arunoda's article on this sums it up pretty nicely. It's a different way & a change to what we've been taught with Meteor. And if you don't like it, you don't have to follow it :)

Thanks @markoshust
Splitting client from server code is what I've doing a long before Meteor (I guess everybody did/does), going back to this way of thinking isn't a problem at all. I was just confused about using Meteor and coding "against" its ideas, but as you emphasized, it was how MDG thought and things are changing.

i'm kinda agree with @mquandalle

I think for me, if you are creating something that will be put in the
modules folder inside the client folder, then i have to agree that we
should just put client code in there and not mix it with server code.

If you are going to put the modules folder inside the import, then i guess
it would be best to have both the client and server in the modules folder
PROVIDED that you want to create "mini-apps" or "mini-plugins" that you can
just install and use either from the client or from the server.

And from there, you can publish it to npm, which is akin to just putting
the folder inside the imports/modules to npm_modules. By just using npm
install, you can "install" a module or plugin (may it be fully client like
reusable react ui components, or fully server like a full feature api with
database management, or a feature that has a client component and server
api)... Then just use import {needed} from 'installedmodule';

On Tue, 2 Feb 2016 04:49 David Ďurika notifications@github.com wrote:

i'm kinda agree with @mquandalle https://github.com/mquandalle


Reply to this email directly or view it on GitHub
#3 (comment).

I really don't like this idea of separating client code from server code when we are dealing with JS 😬 This reminds me so much of bad practices: code rewriting, mixed responsibility, team shouting match, project management euphoria... This clearly defeats the whole purpose of using a common language on the server as well as on every clients. Yerk.

For dealing with different targets and bringing more stuff on the table for capable devices, we should use coding/design patters. AOP, for instance or simple directive.

There's not 1k flavors per device for each Linux kernel release. Though you can install it on almost every iot, smartphone, computer, server, grid and even fridge. They are using simple pragma and macro. Just like we can do it with UglifyJS or SweetJS.

@pem with respect, most of the problems you're addressing are almost certainly the result of tightly coupling the server with the client.

By drawing a distinction between the code which operates the server, and the code which powers the client, you are actually allowing for a much greater freedom of mobility in your code, and dramatically reducing boilerplate code and rewrites on large projects. You are allowing yourself the freedom to have your server power your web app, native apps, et cetera without bloating each client's install with the specific needs of a release candidate.

Meteor has always had a clear distinction between client and server at this point, which was muddled only by documentation. For example: Meteor.method definitions are the clear domain of the server, and are designed to be executed in blocks that the client never sees, but rather the client is given a separate API call for accessing them.

What mantra is doing is drawing a clear philosophical distinction, rather than simply a technical one.

@natecox Meteor.methods are for the client & the server. This is the core principle of optimistic UI 😉

And nope, this is not an issue with tight coupling. On the contrary. Splitting client and server code is like claiming that HTML / JS and CSS have been created for avoiding coupling. In the end, we all know where it ends. That the core essence of React 😄

I strongly prefer the isomorphic approach where you develop a use case from end to end. It's far clearer. For instance, I can tell you that being able to make a whole payment process in a single module is amazingly productive and clear. It would be mumbo jumbo splitting into modules for the client A, the client B, the server, the shared parts... blablabla.

@pem What you're describing is monolithic, rather than isomorphic. Isomorphism simply describes that all of the app assets are written in a single language.

The dichotomy here is between modularity and monolithism. I would content that writing monolithic apps decreases clarity, understanding and therefor productivity by eschewing the single purpose principle. Instead of focusing on doing a single thing and doing it well, you're focusing on doing everything in the same spot. This leads to unrelated code being colocated, a more complicated structure and less ease in perusing code.

How this comes up in the code itself is a grab-bag. I feel that a strong separation of client and server is a good thing, but I also think it can be represented in multiple ways. A strong feature-oriented modularity in the total app itself goes a long ways, and I personally feel that including a server/ directory inside of that module isn't the end of the world.

As a side note: Meteor.method called on the server and on the client are designed to do two different things: on the server it denotes an actual method and is responsible for hitting the database and so forth, while on the client it denotes a stub (a fictitious element that outputs what you think should happen and is clobbered by the server method which is what has actually happened). That's the definition of 'optimistic ui' and absolutely supports the notion of server/client separation at a fundamental level.

@natecox Well, it's a point of view. I strongly prefer the use case view. It's more natural for my flow of programming. The framework should make the effort of reusing, splitting, optimizing. We could just put stuff for orienting it like we do with Meteor.isClient / Meteor.isSever. In essence, my point of view is that a framework should value feature productivity over architecture for its user. While, under the hood, using strong patterns (especially the creational ones instead of the behavioral ones) for easing its extensibility.

@pem everyone is entitled to their point of view, of course. There's more than one way to do everything in programming. That being said, Mantra has clearly established itself in the camp of modular, non-universal, opinionated architecture.

It's probably not what everyone wants from Meteor, but just taking a look at this repo over the past several weeks I'm convinced that there are lots of us who agree with it and I wouldn't suggest that we change fundamentally to try to please everyone's point of view. There were a few things in the making that I didn't initially agree with either, but keeping an open mind and being willing to explore them I have generally reversed those opinions.

@PEM--, @natecox sum it up. Yes. We've more places to improve. But, we need to take some decisions where not everyone agrees.
That's the nature of an opinionated stack. It's for the greater good.

Hello Arunoda,
Thank you so much for such great work. Personally I am very excited
about this.
Looking forward to the tutorials on mantra and the courses. Roadmap
looks amazing!
Kind regards,
Angel
On 2/3/2016 at 5:20 AM, "Arunoda Susiripala" wrote:

@PEM-- @natecox sum it up. Yes. We've more places to improve. But, we

need to take some decisions where not everyone agrees.
That's the nature of an opinionated stack. It's for the greater good.

Reply to this email directly or view it on GitHub.

Hi all,

I'm happy to close this issue after some great work. Now we've a module system as we discuss.

Sorry @arunoda but I still can’t understand your reasoning about modules being unable to define features for the server. Your sample application for instance has a module called “comments”. On the client, the stub methods are defined inside the module whereas the corresponding real methods are defined in the global context outside the module on the server.

I would totally buy that this inconsistent architecture between the client and the server is due to some technical limitations of the Meteor bundler. Meteor indeed doesn’t offer much control about where we put files and I would agree that for now it is easier to put everything that is related to the server on a server/ directory and similarly for the client. However you are not saying that is a temporary organization motivated by technicals limitations, you are saying that this is the desired shape of the module system, and despite reading all your messages here and linked blog posts, I still don’t understand the arguments in favor of that.

@mquandalle Shall we open a new issue for this?

@arunoda do you have examples for how to distribute modules via npm?

@tonyxiao not yet public. Only think I'm finding hard to do it the CSS packaging. If that's done, we are good to go.

commented

Inline styling ? I like the "CSSmodules" specs...