A Different Router API
However, I was thinking about a way to simplify its use for most users. Here’s a common pattern you’ll see when using it:
This is just the routes isolated in their own file. It makes it easy to reason about the layout of your app’s pages. But it seems like a lot of typing to set up these special
Route components that just link you over to your actual React components. What if we didn’t have to do that?
Neat! How do we do something like that? Instead of wrapping the component inside of a
Route, the component is created as a router component explicitly:
Why would that be better? One of the more non-obvious features of react-router is that it passes lots of useful props to the Route components, such as
this.props.params. However, the component has no guarantees that it’s being used in a route. Practically speaking, that isn’t going to be a problem because you’re in complete control of your code and it would be a weird pattern to expect route props and then not use that component in a route. However, being explicit about your code’s expectations are always a good thing.
In addition, you could potentially access things like
params even when your component isn’t being used directly as a route. That information could be passed down via
this.context and accessed by any child node under a route.
Of course, this doesn’t take into account more advanced use cases, such as asynchronous routes, but it could be an interesting pattern to explore for simple use cases.
I’ve written a lot of Rails code. I still do. Ruby is a great language for backend systems and Rails makes it exceedingly simple and terse to whip up a full-featured REST API in no time. I recently tried to do the same in Node and it was like pulling teeth. There was a lot of DIY setup and fiddling just to get things working. Gross. I know things like Adonis exist to make this better, so hopefully its popularity will grow over time.
But one fixable part of the problem was how much space was wasted on explicitly defining imports in every file. Look at the examples above and notice how nearly half the code is imports. This is something Rails solves with a fantastic autoloader so you never have to
A third of the code gone, but even better, we don’t have to edit the code in two places to add another route: once for the import, once for the route itself.
How would one implement something like this? One way might be a plugin to Babel to look up undefined variables and add in import statements to the code dynamically. You might also override on a per-path basis with a
.autoload file, which would let the autoloader know to only search in our route components path. In a Redux
combineReducers instance, it would have it autoload from the path to your reducer functions.
This last one is a little more self-serving. I’ve been (slowly) working on building out more of Webpack Preset. One of the things I don’t like about webpack (and why I always preferred Gulp to Grunt) is its use of a configuration object instead of a configuration API. (Even better, it could offer both!) So, most of my presets end up doing some funky object manipulation and have a lot of redundant code between them.
What I plan on building out in more detail is a configuration API to webpack. Jason Quense has already experimented with this a bit, and I will probably end up poaching bits of it (with credit, of course!). But my thoughts are to make this a separate library so anyone can use it.
One of the most complex parts of it will be allowing us to serialize the constructed config into a
webpack.config.js file. How best should you convert a plugin back to a
new webpack.optimize.OccurenceOrderPlugin() statement? I’m not 100% sure how, but it could be pretty interesting to find out!
Also published on Medium.