Coder Social home page Coder Social logo

Comments (15)

ffxsam avatar ffxsam commented on April 28, 2024 1

Hey David!

The boilerplate includes an empty feature skeleton, but the example branch has no features. It looks like your approach evolved after branching the example off. Just curious what your initial thinking is here. Are you borrowing from Mantra's approach to file structure?

Correct, the example code is not using the feature structure yet, as I'm still testing it in real-world applications before I decide if it's a flop or not. :) And no, I'm not borrowing from Mantra. I just had this idea that if I'm working on a large application, and Feature XYZ is giving me problems, it might be easier to dive into the code if everything related to XYZ is in /features/XYZ.

Lastly, any particular reason you eschewed the Meteor guide's recommendation of using a root import directory?

I feel it's a bridge as people who are used to the "globals everywhere" model of 1.2 move into 1.3 and get used to import/export. I have a feeling MDG will eventually make everything 100% explicit imports. Plus, my folder hierarchies are deep enough as it is, I didn't want to introduce yet another level!

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

Thanks for the clarifications.

Since I'm just getting into Meteor now (awesome timing, no? πŸ˜‰ ), the magical, globals-everywhere approach feels way too loosey-goosey for me, so I rather liked that MDG is counseling avoiding it. I get the same feeling as you that they'll move towards an import-only approach in future versions.

And btw, didn't meant to suggest you were following Mantra's philosophical approach, just the abstract notion of modularizing features. I put some good time into exploring Mantra over the last couple weeks, and in the end it seems too constraining for the sort of projects I am entertaining with Meteor.

I am still a bit fuzzy on how the modular approach in your currentβ€”wip, I get it πŸ˜„β€”boilerplate will work with the separation between server and client; If the entire features directory is located in the root client folder, doesn't that mean all the server-specific code will get incorporated into the client as well? As a Meteor greenhorn, am I missing some important detail?

from ffx-meteor-react-boilerplate.

ffxsam avatar ffxsam commented on April 28, 2024

Since I'm just getting into Meteor now (awesome timing, no? πŸ˜‰ ),

Ha! "Pardon our dust.."

And btw, didn't meant to suggest you were following Mantra's philosophical approach, just the abstract notion of modularizing features.

Yeah, I think I understood that. I just meant that I didn't get the idea from themβ€”just my own private brainstorming sessions. :)

My boilerplate, while evolving, can be considered complete and usable. But now I see what you're asking, about separation. The idea is to put client, lib, and server folders within features. E.g.:

features
β”œβ”€β”€ Admin
β”‚Β Β  β”œβ”€β”€ client
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ components
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ AddEditOrgDialog.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ AddEditUserDialog.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ OrgList.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ OrgManager.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ OrgManager.scss
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ OrgMemberList.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ OrgMemberList.scss
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ OrgUserManager.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ UserList.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ UserManager.js
β”‚Β Β  β”‚Β Β  β”‚Β Β  └── UserManager.scss
β”‚Β Β  β”‚Β Β  └── containers
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ OrgManagerContainer.js
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ OrgUserManagerContainer.js
β”‚Β Β  β”‚Β Β      └── UserManagerContainer.js
β”‚Β Β  └── lib
β”‚Β Β      β”œβ”€β”€ methods.js
β”‚Β Β      β”œβ”€β”€ organisations.js
β”‚Β Β      └── users.js
...

And certainly not all features will even use a lib or server folder, but the option is there. For example, I might have a /features/Billing/server folder to hold private Stripe-related stuff.

Hope that clears things up!

I've also moved away from JS styles to using BEM. IMO, JS styles fall apart when you want to share common stylings among several components. I started defining object literals in other places and importing them to access styles, and it felt clunky to me. I believe CSS Modules will eventually be the landing point for React, and I think using BEM will lead to a smoother transition to that down the road. I see that Mantra took quite the opposite stance and officially recommends JS styles. :) But of course, there is no right or wrong! Use what works for you, but always keep an eye out for what other people are coming up with. This landscape is constantly evolving.

PS: I'll update the example app to use BEM when I get some free time.

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

And certainly not all features will even use a lib or server folder, but the option is there. For example, I might have a /features/Billing/server folder to hold private Stripe-related stuff.

Hope that clears things up!

Generally, the idea of features makes perfect sense. But I'm still not understanding why I'd want (potentially sensitive) server-related code to reside in a subdirectory of the client folder. That means it will get incorporated into the client code, right? Even if it is dormant, it'll still be compiled in, no?

I've also moved away from JS styles to using BEM.

Yeah, that was the first thing to go as I started playing with the example branch. πŸ˜ƒ Inline styles in javascript are a fabulous idea if I want my designers' heads to explode before they hand in resignation letters!

Otherwise, my deviations from your direction so far are slight. I was already intending to use Astronomy, so was pleased to see that already in there; React and redux were on my hit-list too, so very nice. I decoupled the Redux Provider component from the layout, so I can keep alternate layouts DRY. I'm on the fence between react-komposer and react-mixin; And I'm toying with the idea of trialing react-router in place of flow-router.

from ffx-meteor-react-boilerplate.

ffxsam avatar ffxsam commented on April 28, 2024

But I'm still not understanding why I'd want (potentially sensitive) server-related code to reside in a subdirectory of the client folder

It wouldn't. The structure goes like this:

features
└── Billing
    β”œβ”€β”€ client
    β”œβ”€β”€ lib
    └── server

And I'm toying with the idea of trialing react-router in place of flow-router.

Me too, actually. Since you're not supposed to have reactive data or serious business logic in Flow Router, I'm not seeing the advantage of it anymore over React Router, which is far less verbose. But I'm still mulling over the idea of moving.

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

Thanks for the quick responses!

It wouldn't. The structure goes like this:

Oh geez, I was misreading that structure in my tree view... heh. Even so, I thought any folder other than imports gets included in the build. If it's at the root, then its contents will get included in both client and server...

From the meteor guide (1.3):

Meteor will eagerly load any files outside of imports/ in the application

No?

from ffx-meteor-react-boilerplate.

ffxsam avatar ffxsam commented on April 28, 2024

Correct. But.. quoting myself way above:

I feel [the imports folder is] a bridge as people who are used to the "globals everywhere" model of 1.2 move into 1.3 and get used to import/export. I have a feeling MDG will eventually make everything 100% explicit imports. Plus, my folder hierarchies are deep enough as it is, I didn't want to introduce yet another level!

Just personal preference.

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

Oh, I forgot: On the router, one other change, which I cribbed from @tomRedox's simpleCRM, and really like:

  // Set group for authenticated users
  const authenticatedRoutes = FlowRouter.group({
    name: 'authenticated',
    triggersEnter: [function(context, redirect) {
      // Redirect unauthed users to login page
      if (!Meteor.loggingIn() && !Meteor.userId()) {
        console.log('not authorized');
        redirect('/login');
      }
    }]
  });

  // --- PUBLIC ROUTES ---
  FlowRouter.route('/register', {
    name: 'users.new',
    action() {
      mount(MainLayoutCtx, {
        content: () => (<NewUser />)
      });
    }
  });

  FlowRouter.route('/login', {
    name: 'users.login',
    action() {
      mount(MainLayoutCtx, {
        content: () => (<Login />)
      });
    }
  });

  // --- AUTHENTICATED ROUTES ---
  authenticatedRoutes.route('/logout', {
    name: 'users.logout',
    action() {
      Meteor.logout();
      FlowRouter.go('/');
    }
  });

  authenticatedRoutes.route('/', {
    name: 'items.list',
    action() {
      mount(MainLayoutCtx, {
        content: () => (<EntryList />)
      });
    }
  });

...

I haven't looked closely enough at react-router to know how to implement the same so elegantly.

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

Correct. But.. quoting myself way above:

I feel [the imports folder is] a bridge as people who are used to the "globals everywhere" model of 1.2 move into 1.3 and get used to import/export. I have a feeling MDG will eventually make everything 100% explicit imports. Plus, my folder hierarchies are deep enough as it is, I didn't want to introduce yet another level!

Just personal preference.

Not to beat a dead horse, I just want to understand. In the here-and-now, this method means those files in the server directory will get incorporated on client and server, which seems wasteful of memory and bandwidth, and potentially a security issue. Or... πŸ’‘ Does Meteor exclude files from a "server" directory at any place in the hierarchy?

from ffx-meteor-react-boilerplate.

ffxsam avatar ffxsam commented on April 28, 2024

Yeah, I like how React Router is just a handful of nested React components. Much shorter. But I don't know what the equivalent of FlowRouter.go() is in React Router. I use that quite a bit.

    triggersEnter: [function(context, redirect) {
      // Redirect unauthed users to login page
      if (!Meteor.loggingIn() && !Meteor.userId()) {
        console.log('not authorized');
        redirect('/login');
      }
    }]

I've seen many people recommend against this pattern, of handling authentication in Flow Router. I used to do this too. Instead, it's recommended that you handle auth and redirection in your React components.

Not to beat a dead horse, I just want to understand. In the here-and-now, this method means those files in the server directory will get incorporated on client and server, which seems wasteful of memory and bandwidth, and potentially a security issue.

imports has nothing to do with the separation of client and server. Anything inside imports is simply not globalized, that's all. But by not using imports, that doesn't really mean that code inside the server folder is bleeding out into client. So there's no concern of security. I'm just saving myself potential hassle of refactoring everything if/when MDG later decides everything will be explicit loading, and the imports folder will become obsolete.

from ffx-meteor-react-boilerplate.

ffxsam avatar ffxsam commented on April 28, 2024

Now if you're just talking about the build tool and efficiency.. maybe that's something to consider. I don't know. I'm gonna keep beating the drum for the removal of lazy loading.. hopefully MDG will consider it. :) I'm not really a fan, but there's no way they could just remove it in 1.3. All the projects that rely on just using magical globals would break, and it would be disaster.

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

So, I did indeed have a fundamental misunderstanding of Meteor's build logic. I just tried including a simple console.log in a feature/x/server directory, and sure enough that is not built into the client. So any server directory, anywhere in the file hierarchy, is omitted from the client build. (And likewise for client dirs. omitted from server builds) That's excellent, and now the modular approach makes so much more sense, and aligns with my existing practices outside of Meteor. I kept getting tripped up thinking I had no choice but to use the root-level server directory if I wanted to isolate code. I'm in complete agreement with your approach thenβ€”lay down a structure now that "lives with" the magical globals, but code with explicit imports as preferred and in anticipation of the day that's the requirement. I don't see a major issue with the build efficiency at this point, but will keep that thought in the back of my mind.

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

Yeah, I like how React Router is just a handful of nested React components. Much shorter. But I don't know what the equivalent of FlowRouter.go() is in React Router. I use that quite a bit.

From the react-router tutorial docs:

// Repos.js
import { browserHistory } from 'react-router'

// ...
  handleSubmit(event) {
    // ...
    const path = `/repos/${userName}/${repo}`
    browserHistory.push(path)
  },
// ...

or...

export default React.createClass({

  // ask for `router` from context
  contextTypes: {
    router: React.PropTypes.object
  },

  // ...

  handleSubmit(event) {
    // ...
    this.context.router.push(path)
  },

  // ..
})

I've seen many people recommend against this pattern, of handling authentication in Flow Router. I used to do this too. Instead, it's recommended that you handle auth and redirection in your React components.

Huh, OK, thinking about it now, that starts to make sense. It's a paradigm-shift from my work with other frameworks, but it does rather make sense in React. (No need to worry about round-trips to a server for routing, the view-controller approach with React, etc.) My instinct then is to handle auth in the layout component (where we're also inserting the Redux Provider) and permissions in subsequent modules/features. This makes even more sense with react-router's nested routes, helping to keep permissions logic DRY.

from ffx-meteor-react-boilerplate.

dtwist avatar dtwist commented on April 28, 2024

Quoting myself:

My instinct then is to handle auth in the layout component (where we're also inserting the Redux Provider)

On second thought, that works in flow-router, where the layout decorates the route's component, but not in react-router, where (I guess) auth would have to be handled further down the hierarchy, along with permissions. 😞 Must go read and ponder more…

from ffx-meteor-react-boilerplate.

ffxsam avatar ffxsam commented on April 28, 2024

Good luck. :)

from ffx-meteor-react-boilerplate.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.