Meteor + Webpack: ES6 modules, hot-code-patching, fixes load order & more

@benoitt interesting, webpack:hot-load must be new huh?

One big question to me is whether it’s convenient to customize webpack however you want with that package, especially manage multiple webpack configs, as it’s important to have different configs for dev and production.

Also, does it use Webpack to bundle the server-side code as well? This is a major feature of meteor-webpack-react.

I won’t lie, I prefer to see Meteor become just another collection of npm packages to be required into a project rather than almost forcing you to use its package system and web server. So I’m trying to crusade against packages that perpetuate that dependency.

@SkinnyGeek1010 I’m definitely fine with using React 0.14, though I haven’t tried it yet. At the very least we could make it a branch for now.

And by the way everyone, I recently created a meteor-immutable-observer package for automatically updating Immutable.js collections from Mongo.Cursor.observe/observeChanges in an efficient way. It’s a very easy way to get performance gains with pure render components. I’m starting to use it with Redux in my own project. It’s in the early stages and may still have some kinks to work out, but feel free to give it a try!

1 Like

As far as getting Meteor collections into Redux, my approach has been to create the autoruns in a custom redux middleware in response to an INITIALIZE action. I also made it hot-reloadable; If you add new handlers to that custom middleware the hot reload handler dispatches a STOP action, which makes the middleware stop all the autoruns and subscriptions, then it loads the new middleware module, then it dispatches a new INITIALIZE action to start the new subscriptions.

@mattkrick if GraphQL or anything else is more handy than Meteor for client-server communication, I’m all ears :slight_smile: Meteor merely seems to be the most convenient tool for that I know of at the moment.

1 Like

A big pro for relay is the declarative nature so you don’t have to worry about under/over subscribing, which is kinda a pain-point with meteor’s current pub/sub (eg sub not ready or unused data sitting in minimongo) , but I haven’t learned enough about the flow to figure out any cons lurking beneath…

@jedwards @SkinnyGeek1010 have you guys seen this redux plugin for handling meteor data? https://www.npmjs.com/package/meteoredux

What do you think of its implementation?

Relay is nice but it’s not a turn key setup. I like how Meteor handles websockets, RPC methods, user accounts, and authorizing the RPC/publications, fibers, and DDP to DDP connections. This alone is non trivial to do in a prod. ready setup.

I’m not a fan of Meteor publication/subscribe system but it works better than REST. It just feels clunky when you have to update subscriptions and the publication feels limiting (often 2 pubs solve this).

Relay is also very flexible for an existing stack. However I imagine someone will make a library to abstract common things for greenfield apps. (like how Alt is substantially easier to use than vanilla flux).

There is this boilerplate that’s being developed now. I haven’t seen the newest GraphQL commits but it looks fun to play with. https://github.com/xpepermint/isomorphic-react-relay-boilerplate


> A big pro for relay is the declarative nature so you don't have to worry about under/over subscribing, which is kinda a pain-point with meteor's current pub/sub (eg sub not ready or unused data sitting in minimongo) , but I haven't learned enough about the flow to figure out any cons lurking beneath...

So Meteor’s subscription can be declarative if you set it up that way… tracker can watch a reactive dict/var for sub param data but it’s not very elegant.

I started to try and solve the over/under fetching in this project http://react-ive.meteor.com/ which is on github. That part is here:

https://github.com/AdamBrodzinski/react-ive-meteor/blob/master/both/components/Feed/FeedContainer.jsx#L24

Basically it just needs to walk to tree to find an object on statics but I didn’t have the time. This method at least puts it all in the view-controller and you can double check by manually walking down the tree and checking ‘propTypes’ to see what’s needed.

      // TODO have this component grab children's needed fields
      // from their statics object
      fieldsNeeded: {
        posts: {
          _id: true,
          desc: true,
          likeCount: true,
          commentCount: true,
          userName: true,
          createdAt: true,
          ownerId: true,
        },
        postComments: {
          _id: true,
          createdAt: true,
          username: true,
          desc: true,
          postId: true,
        }
      }
    };
  },
2 Likes

Ah, I didn’t see that! But yuck, I don’t like it. For me it’s coupling Redux with Meteor which increases surface area for bugs.

The worst part is that it’s producing side effects in the reducer :frowning: Those are supposed to be pure functions.

My personal fav. is to just fire an action when outside data changes. However @jedwards middleware sounds really interesting!

I have a flux helper here: https://github.com/AdamBrodzinski/meteor-flux-helpers
that allows you to just do this:

// partially applied functions that auto dispatch
trackCollection(Meteor.users, usersChanged);
trackCollection(Posts, postsChanged);
trackCollection(Comments, commentsChanged);

And then if you unpack that here’s what’s going on:

Tracker.autorun(computation => {
    var docs = Players.find({}).fetch();

    // ignore first empty run
    if (computation.firstRun) return;

    dispatch( playersChanged() )
  });

just tried the lazily loading components via React Router routes and it works! This is going to be huge! Not only does it lazily load components but it lazily evaluates the route definitions as well. This is going make apps so much smaller on initial load.

Wooo nice! I can’t wait to try it! Checkout the API docs in the react-router github page, there should be 1.0-RC docs that show how to pass in the history thing.

1 Like

meteoredux could be handy for some situations. But for the project I’m working on right now, it’s important to use immutables instead of plain JS objects, and sometimes I have to do more than just stick them straight into the state (for instance when a new view is created, I need to create local session state for it elsewhere in the redux state as well).

Thanks for the tip and wiki!

I got it somewhat working, it no longer complains about / not defined.
PS: I am actually using flow-router-ssr instead of flow-router.

This actually gives me a strange error.

import App from './components/App.jsx';

FlowRouter.route('/', {
  name: 'home',
  action: function (params, query) {
    ReactLayout.render(<App />);
  }
});

TypeError: Object [object Object] has no method ‘toUpperCase’ at autoGenerateWrapperClass (packages/node_modules/react/lib/ReactDefaultInjection.js:53:1)


Looks like it might be related to this issue, but it is already closed.

Any ideas? :smiley:

Some Thoughts:

After several hours playing around with this, I actually like like this idea very much. Will definitely try it on next project.
Wondering will this be officially implemented into Meteor.
This actually allows me to use npm packages in a much easier way while we can still have Meteor’s packages.
Tho, I am a little worry about the capabilities.

That’s actually a pretty common error that I get in React Native when the module is imported and the variable of the component is undefined. I’m hoping the change this to ‘React component not passed in’ or something like that.

I’m betting one of the imports are not getting pulled in properly. Does this happen on the client or server?

I also haven’t tried react-router SSR with the webpack config yet… want to try 1.0 soon :smile:

Wondering will this be officially implemented into Meteor.

Looks like they are watching it : https://github.com/meteor/meteor/issues/5117
I’m hoping they’ll switch to it and expose an optional config for people that need more options.

1 Like

As @SkinnyGeek1010 already mentioned, there reducers are not just pure functions that return new state, there is Meteor stuff inside of it you don’t want.

The flux-helpers package is pretty simple but worked for me so far. I have a isolated trackCollections helper with some store.dispatch methods that are run when a Mongo collection changes. The helper is run as an init call inside the Meteor.startup where you also render the root component for example.

I have to check @jedwards package, but right now I’m not using Immutable.js and don’t want to be forced doing so atm. So the flux-helpers package is a bit lightweight, but probably all you need to get the ball rolling anyway.

Overall I think there’s still a problem regarding local component state and just mutating that not using Redux for everything (only for app global actions or state changes you want to undo/redo/replay) but atm I’m fine with mixing both. I’ve read Elm had a way to store local component state also in the global store tree together with the app state (so you can essentially copy the whole state at any given time), but that’s possible with React at the moment.

1 Like

So looks like the guy that created React hot loader is deprecating React loader for React transform.

Edit: Oh pfftt… @rolf already mentioned it.

Since this is SSR, I actually created a routes.jsx and import it from both server and client.
This error seems to appear on both side.

If what the error meant by toUpperCase isn’t what it’s trying to address, I will take a look at imports not pulled in properly direction. Webpack is still very new to me, maybe it is just a silly config problem. :smiley:

Thanks for your reply!

No prob! There’s an alias to ‘app’ so you may want to reference the component as 'app/component/Foo' instead of using multiple dots (that can get confusing).

Let us know how it goes!

With 1.2 out, is there anything we should know and/or do differently when it comes to these boilerplate setups?

Shouldn’t change anything yet. It’s already using the babel-runtime and react-meteor-data that was previewed a while ago.

However, we now have the option of not loading Blaze at all and also to use a static html page. This would break any Blaze packages if you had them (I think). You can also eliminate jQuery if you’re not using that.

I would try to start with this (haven’t tried yet)

meteor-base             # Packages every Meteor app needs to have
static-html             # Render a non blaze HTML page
mongo                   # The database Meteor supports right now
tracker                 # Meteor's client-side reactive programming library
standard-minifiers      # JS/CSS minifiers run for production mode

# webpack deps
babel-runtime
react-meteor-data       # optional if you're using flux

# we don't need these if you're using webpack since it uses core-js to shim

#ecmascript              # Enable ECMAScript2015+ syntax in app code
#es5-shim                # ECMAScript 5 compatibility for older browsers.
2 Likes

@SkinnyGeek1010 do you think you can figure out how to get webpack:hot-reload to work with Jed’s setup? I’ve been trying to get it to work but I can’t massage the configuration correctly to get it to work.

1 Like

@SkinnyGeek1010 Finally got around to playing with Webpack in a new project and its amazing!! I’m totally sold. Meteor is in the stone age now. lol.

I just wish there were better tools for websockets and user authentication in webpack. Passport looks cool, but its way more work than what Meteor provides you. Honestly, those are the only two things holding me back from ditching Meteor altogether. It really bugs me how React Native hasn’t been integrated into Meteor yet. That should be top priority for MDG in my opinion. Meteor is starting to lag. I wanted to use the react-svg-loader in my Meteor project and I couldn’t. Thats super lame.

One of these days, someone is going to build the meteor tools ontop of webpack and they’ll be way more powerful…

1 Like

You know you can use webpack with Meteor right? :smiley: It basically build it like a normal JS app and then you drop the app bundle in a Meteor folder. Then you assume Meteor globals exist in your webpack code. It’s still a bit of a hack though :frowning:

Passport looks cool, but its way more work than what Meteor provides you.

Yea i’ve needed to do some custom projects and the only efficient way is to spend a night building your own boilerplate then you can git clone a new project with hello world auth/routes/db/crud. Luckily I haven’t had to do this much.

It really bugs me how React Native hasn’t been integrated into Meteor yet. That should be top priority for MDG in my opinion.

+1… It should be really easy (relative) too, they just need to polyfill some events and things that are DOM specific (ready events).

One of these days, someone is going to build the meteor tools ontop of webpack and they’ll be way more powerful…

Yea i’m hoping this doesn’t happen either. With Falcor and GraphQL nipping at Meteor’s toes it’s only some time before a framework abstracts all the ‘boilerplate’ work that they both have (both are working on websocket support).

@SkinnyGeek1010 RethinkDB is working on built-in support for both Falcor and GraphQL

1 Like