The worst problems you’ll find building an Isomorphic Application (pt. 2)
So here we’re again. This article is the second part of an articles series that I’m writing about my pain of building a complex and exciting application using an isomorphic Javascript code.
You can find the part 1 here at this link:
I would write all “First Researches Problems” in details in this part 2, but I decided to split the Node “Problems” to a third part because its size (it is not that big, but I don’t think long texts are productive).
And let’s move on to what matters:
Detailed First Researches Problems
If you well remember, those are the topics and the bolded items are those we gonna discuss here:
- How to properly fetch information in both sides, server and client, with the same code;
- How to do not fetch things on client when we already did on server;
- How to make sure that we gonna have HTML markup for crawlers understand us;
- How to run ES6 full features on NodeJS (in part 3);
- (spoiler alert) Then you find how to run ES6 features on NodeJS, but it is not recommended for production for its memory consume, then what? (in part 3)
How to properly fetch information in both sides, server and client, with the same code
And let me explain why. Consider these two points:
- If you just bring the markup without content and fetch data on client, how do crawlers will know about your content?
- If you already fetched data through server, why fetch again on client? You’ll only increase your server bills and make your user experience worst.
If you’re using Redux with some Virtual DOM technology, I strongly recommend you to read this post:
If you change every React word for <your_virtual_dom_lib> and abstract properly, you’ll get the same results.
In a nutshell, I did this:
- consider that you have one
preloaded_state
object; - in the server you will fetch information and save everything at
preloaded_state
; - from server through your markup you’ll inject above your Javascript something like this (represented inside a template string):
`window.__STATE__ = ${preloaded_state};`
- only few parts of your code won’t be shared, so at client you to get
preloaded_state
to create your store:
const store = window.__STATE__;
After that you can configure your store
properly following Redux docs. :)
Now we need to talk about fetching information one time only, which takes us to the next topic.
How to do not fetch things on client when we already did on server
Now I have store
on client and it’s information already fetched, but I’m using the same code for server and client and when client comes, it’ll fetch everything again, such a dummy this client guy, right?
This is what happened in a timeline:
- I decided to create a function called
shouldFetchAction
to check if I had an empty object or not, and use it when necessary. Sounds good, but imagine that when browsing the application through different products the data won’t update becauseshouldFetchAction
will check empty objects only and anything else; - Then chaos, a few moments thinking, 2 lap meetings (I named lap meeting when I walk around the company having meetings, you should do it) with one developer, 3 lap meetings with my P.O. (which is a tech guy also) until get some ideas to solve this issue;
- What if I mark my request? Could I
.push()
arequestedOrigin
object to my requests and map their origin? I think someone will say it’s a bad practice, but since I’m creating on top of something so new and with short time, I need to make things at least safe and then improve the methods. I could prove it’s safe and the team worked in this implementation.
I’m using a lib called Axios, which works really well with both server and client requests and it has this transformResponse
function that I can do some magic there. I checked where this request was coming from and marked with ['s']
in case of server and ['s', 'c']
in case of being available to make the request again from the client.
Inside my Redux actions I updated the requestedOrigin
Object properly to having ['s', 'c']
sending it properly to the store.
I’m still researching about alternative ways to do it and comparing. If you’re reading this and could get a better solution, please share with me commenting here if you like. ❤
How to make sure that we gonna have HTML markup for crawlers understand us
This is a topic that I can go through with 2 approaches.
1- I talk a lot about Virtual DOM, its engine and etc; or
I make it simple and just say to you that if you search in Google for “<your_lib_name> server side rendering” you gonna find almost everything you need.
If you’re using React, renderToString()
React function will solve the problem which will make a lot for you on NodeJS side. And it’s simple as it should be. You require
your component to your server side markup file and do something like this:
var App = require('./components/App.js');
var renderToString = require('react').renderToString;...function renderHTML() {
renderToString(
<App />
);
}...
If you’re using VueJS, I found this link which can help you out:
And if you have more suggestions, please comment about it, I’m even considering use Vue for my next project and knowledge is always awesome to share! :)
Now if you need to provide data from server, remember that post I shared at the beginning? Go for it.
HINT:
If you’re using .jsx
syntax for React components, you’ll need more extra magic for NodeJS understands what is happening inside that code, at part 3 I’ll show a little bit more about it.
Part 3 and 4 are coming :)
I’m already writing part 3 and 4 of this series and the rest will appear while the work is being done with this series.
- Part 3: Detailed First Research Problems (continuation);
- Part 4: Interface Design Patterns Importance.
Endings
I hope you liked it and if you did, please share, comment below anything that helps to improve the content or doubts. You can also reach me out on Twitter, I’ll be happy to answer and chat about Javascript or software design. :)
Thanks!