I'm on Meteor 1.5, now what?

I was on Meteor 1.3.5.1, and just upgraded to 1.5 without much of a hitch. I’ve done nothing else but run meteor update.

Now what? I’m trying to convert my application from the old way, 1.2 days, to the new way, React/Redux/Dynamic Importing and ES6.

What are the steps I take to visualize what is loaded on the client? What do I need to do in terms of import statements that will allow me to “dynamically” load (for now) Blaze templates (and other stuff)?

The following is a collation of what I’ve found so far:

  • Read the 1.5 announcement.

  • Read the 1.5 release notes.

  • Read the 1.5 Meteor guide.

  • Read about Promises and async/await in Meteor, AND Using Promises on the Client in Meteor.

  • Blog article on Dynamic imports in Meteor 1.5.

  • Watch Ben Newman on Dynamic import in Meteor 1.5 Beta.

  • Watch Lukasz Jagodzinski on Meteor 1.5 Dynamic Module Imports.

  • Listen to Transmission Ep 18: Meteor 1.5 & Migrating Atmospher Packages to NPM.

  • Chrom 59’s new Code Coverage can help show how much code is used vs how much is loaded.

  • do I now install the bundle-visulizer and the standard-minifier-js package?

  • It seems one cannot import server to client or client to server, even under the imports directory? How then does the client import publish functions or metoer.methods?

  • Are there plans for a new “todos” example app based on Metoer 1.5?

  • Is it true that import modules are singltons on the client (complient with ES7), and NOT singltons on the server (Nodejs style)?

  • What is the meteor-node-stubs lib?

  • Worth reading about Peer npm dependencies

  • It seems like a good Idea to review this Bundle Optimization post

  • Check out the comment thread on migrating to 1.5

  • Looks like I should install the reify lib in order to get nest imports?

  • If you’re using a non-dockerized version of mup, this lib works with 1.5

  • Looks like Google’s Lighthouse can help you figure out how to optimize your site’s performance.

  • Should I upgrade from the old FlowRouter to FlowRouter extra to get dynamic import features? It seems vinilla FlowRouter also works with dynamic imports out of the box.

  • What are the strategies for spreading dynamically imports throughout your app (I only want the client to get what they’ve asked for and what is needed and nothing more)?

  • What is the best way to take out all the “Meteor packages” that use to be included by default, for example Moment.js/Underscore/JQuery/XmlBuilder, and add them back again as npm packages?

  • Any tips on adding Reactjs/Redux to my project and have it run side-by-side with Blaze for the time being? I want to take my application screen by screen and convert it over to React.

Also, a big thank you to MDG for allowing for such a smooth update from 1.3 to 1.5, impressive.

8 Likes

I personally would avoid adding Redux unless it’s really needed. Few things that come to mind when using React with Meteor:

1- If you need quick prototyping of your react component with data from Meteor you can use ultimatejs:tracker-react, it works really well and your react component will behave like a blaze template with regards to reactivity

2- If you’ve complex component, then it’s better to create a HOC for subscriptions and methods, and then pass the data to a dumb child component, you can have both in the same file


export default createContainer(
  props => {
    const subscriptions = [Meteor.subscribe('posts', { limit: limit.get() })];
    const subscriptionsReady = subscriptions.every(subscription =>
      subscription.ready()
    );

     ....
return {
      subscriptionsLoading: !subscriptionsReady,
      records: cursor && cursor.fetch(),
      count: cursor && cursor.count()
    };
}, 
  class NewsFeed extends Component {
    ...
   render..
  }

or you can have them in different files similar to the Meteor react tutorial. The reason why it’s better to move the data fetching logic outside of the components is because with multiple subscriptions and method calls, your component internal logic will get polluted with all the data fetching and subscription lifecycle and state management logic which is meteor specific, so decoupling those will simplify your code and will make your components reusable even across platforms.

3- I avoided redux, meteor Session, and any global variables (Any to Any relationships) unless absolutely needed. If you design your react components hierarchies right, you can just follow the patterns listed [here] (http://andrewhfarmer.com/component-communication/) and with Parent to Child, Child to Parent, Sibling to Sibling relationships most of the cases would be covered.

4- I’ve used React Router V3 to keep my view layer in sync with the rest of the react community, it worked really well. However I now need to upgrade to the new version which apparently is a complete rewrite, sigh. I honestly still don’t know, despite reading multiple posts on react router v4, what pain points the authors were solving that required a complete rewrite! so I’m not to eager to recommend it until I try the new version.

Finally I want to say Meteor/React is the most pleasant stack I’ve worked with thus far. I really enjoy Meteor RPC methods calls and subscriptions, Meteor also handles all the build and configuration work for me, so I can focus on growing the business logic and views with react.

I hope that helps!

4 Likes

@alawi it really does help, thank you!

1 Like

I used to hate redux. I typically add it now though since I have the hang of it. There’s typically going to be a place where you need it-- but some uber simple apps may be able to avoid it. Meteor + Apollo + Redux is perfect for pretty complex UIs. Now with 1.5 dynamic imports, you can speed things up if you have a huge code base. And with apollo you can do some really advanced query/caching stuff.

2 Likes

Maybe check out the meteor chef’s boilerplate and try to move your 1.2 app into that structure. TLDR: put everything in the import folder.

You make them (Redux/Apollo) sound like a must have for most apps, which is my none expert opinion, is a bit extreme. Redux and Apollo are currently early in the early stages of the hype cycle, they’re the new trend. One gives you huge flexibly in your API and other gives a global state for you client side. However I think that those tools should be added incrementally and only when you have enough complexity to justify that addition.

Meteor RPC methods are just javascript functions, it’s very simple to start with and require no additional syntax to learn, and React components has internal state and a lot of medium size apps don’t require a global state for client side. And dynamic imports has no dependency on Apollo or Redux.

I’ve seen apps with few components and API calls using Redux or Flex, and in my opinion it did nothing more than adding complexity to the code base.

But maybe I’m wrong, I don’t have much experience in them yet, I’ll play more with those tools and perhaps then I’d change my mind, initially I also hated React but now I’m wondering how did I get anything done without it :smiley:

2 Likes

Just to add to the Redux conversation, I wrote a complex data analytics app with and without redux. I found that in design you should decide wether redux is a “good fit”. In simple apps maybe not. When designing your react component tree you will see branches forming and as soon as you need data transfer between branches, especially deeply nested - redux is king. In such a case trying to prevent rendering on some props to improve performance is n never ending rabbit hole and in my opinion an anti-pattern. Redux simplifies this problem. Thus on a complex app I found with redux I can write components that only receives props which they need to render, and not include props which is needed for child components down the component tree branch (which often results in performance issues).

2 Likes

Got it, so during design phase, if we’ve a deeply nested components branches with data being shared between the low level components within those branches then Redux (or other global client state management) would make sense.

But again that is the case of Any to Any Relationship as mentioned in this article.

I guess this scenario will come often when you’ve multiple complex components within the same page and their state (or one of their descendants) are dependent on the changes of some other component within another branch on the same page. But for that case we can just have a helper class that wraps a Meteor session object within the context of that page, can’t we? why do we need to force the entire client app into a single state object when we’ve just a page with this complexity?

Furthermore, Meteor comes with a reactive client side storage (minimongo), with some helper classes you can easily create a reactive immutable global state management solution, then why do we need to add redux to a Meteor app specifically when we’ve all the leg work done? after all some people did build complex Blaze apps without redux.

I’m asking to learn if I’m missing something here, I’m sure there is value in redux given it’s adoption, but just keeping some healthy skepticism given how many hyped JS libraries popup everyday!

2 Likes

Yeah, seriously. Redux is one of those things that has a pretty steep learning curve and the cost to benefit ratio has an inverse relationship to how complex your app actually is. Until you’re sure you need it, stick to React’s built in state manager or something just as simple.

1 Like

If you’re not going to use redux, at least use immutable.js to store your application state. So much nicer not having to worry about if data is stale or fresh, etc.

1 Like

Thank you for that @peter I’ll try immutable.js out.

You can build a great app without redux or apollo. But if you do know how to use redux and apollo well, it’s hard to live without them. Once you need to share state across multiple components, it’s really nice to have redux. For instance if you have a component with a list of cards and a component with filters (checkboxes, sliders, etc)-- it is amazingly simple to use redux to store the local filters and access those variables in the card list component, then pass those filter variables into a graphql query as params You could do this using meteor session variables, you could do a string query in the url, there are lots of things you could do.

I hated redux, but now it’s just (1) create an ACTION_TYPE const, (2) create an action function, (3) catch said action in a reducer and update the state object accordingly. Boom. Done. Then I can fire that off or access the variable anywhere with connect()().

I thought both were hype, but now I like them. I basically hate everything and write it off as hype until I learn it lol.

4 Likes

Thanks @a.com for sharing the example. I’ll definitely give both a try.

If my understanding is correct, they both can be incrementally added. Thus I can experiment with them along with my existing code base and evaluate them more objectivity.

1 month later, care to give an update? Would be curious to know how you fared (or are faring). I’m starting to look into what it’ll take for us to leverage dynamic imports as well. We’re already using React.

2 Likes

To be completely honest, I stopped dead in my tracks after the initial load times floored my application. I must not be “doing it right” because it was abysmal. There are scarce few examples on best practices, so I decided to punt until the community catches up and I see solid, deep examples and best practices floating around here.

Ah, that’s disheartening! I tried updating our application to Meteor 1.5 and it’s currently crashing when we use createContainer from the react-meteor-data package. So much for a painless migration!