Isomorphic JavaScript, let’s make it easier
medium.com
medium.com
What isn't answered here however is how it transfers this 'config' and the rest of the state and make it work in the browser. Does rill come with its own client-side router (that works nicely with React?) How does it serialise the state and send it down for the client resume?
Ultimately, the reason 'universal javascript' is hard is because everything's 'modular' so you can get more controller over each component and customise exactly how it works. While rill might be 90% for 90% of use cases, I can see something like this falling down once you start to build anything non-trivial.
Ultimately I found that when writing isomorphic SPA's the amount of code you "CAN" share is much more than what is unsharable, personally I am often able to share 90% or more of the front end code and just have to throw in a few "if (!process.browser)"'s to hide some mission critical stuff from the client.
With many isomorphic examples you will find you end up jumping through hoops to share code. Rill makes this part easy but that doesn't mean that absolutely everything can or should be shared.
The code hits a web api that sends out a batch of emails. Doing this from client side has an obvious set of problems, whereas had it been on server side one can assume a stricter use and thus have a simple security model.
``` if (!process.browser) app.use(require('./api')) ```
Where the api is your typical REST based api with JWT auth tokens. Then the shared client side part of the api communicates with the secure part through "fetch" which works isomorphically (in the browser it is an ajax request, in the server it is a local http request to itself) you should checkout @rill/fetcher for what I currently use. In Rill there is no issue with having "client only" or "server only" routes, the main benefit is that the api is the same no matter where you are working. Take for example "@rill/progress" which is a progress bar that only does work in the browser, or "@rill/compress" which only does anything on the server or "@rill/logger" which works on both (although with completely different implementations). The goal is certainly to encourage code sharing where possible but to also not get in the way. You can use Rill as a standalone server only app if you want, or even just as an in browser framework, it doesn't really matter.
As for my example with emails it is certainly not real world and I don't recommend having public access to an email api but the point was merely to demonstrate that all of the code could be abstracted to work in either place (even without rill).
The use-case which I think this does seem to solve very well is between dynamic and static rendering of web apps (especially when using react). The ability to bundle up routing and rendering and have it handled by the client if possible and the server if not is a great idea. Apart from this, I am not convinced that this framework solves any major problems, but does introduce a lot more magic (which is why I disliked meteor).
My personal setup has been to still separate my api (although still written in Rill) from all of this) which runs as an independent server. Then I have an isomorphic Rill instance communicate with that API. This way I still keep the important things separate.
We can handle it fine manually but we notice we are basically doing everything all over again in a next project and putting that in libs now to be open sourced (maybe someone can use it), however that is for C# and I'm now wondering if there is something like it for JS already ; we cannot be the only ones having these deja vu's with every project?
There are some other interesting frameworks that have come up while I was developing Rill such as https://github.com/catberry/catberry but I think (like many have said in this thread) that there is a fine balance to be had with isomorphic JavaScript. For example I really dislike meteor because I feel like I have little control. I like Rill because it is a perfectly capable backend framework, a perfectly capable front end framework and it all meshes together pretty well.
Otherwise, using the same language on the client and the server does not constitute an isomorphism.
Kthxbai!
If there is one thing you can do to annoy programmers though is to use the wrong terminology :p.
Sometimes I feel like I'm taking crazy pills because "universal" isn't and "isomorphic" is not only technically correct - it's absolutely accurate for the relationship between client and server side code.
First, "isomorphic" is a word that denotes a symmetric, relative relation between two separate things; Two things can be isomorphic to each other but one thing cannot be called "isomorphic" without specifying what other thing it is isomorphic to. That simply doesn't make sense.
Second, isomorphism is about those two things having the same conceptual structure, despite being different things. In math, this means that you can define a lossless two-way conversion between the things (you can start with an A, turn it into a B, and go back to an A, and you'll get the same A). In biology, the field the author took his definition from, isomorphic means that the things have a different ancestry but the same structure. This is literally the opposite of taking code and shimming or compiling it to allow it to run in multiple environments, as it would be taking a single common ancestor codebase and lossily changing its structure to allow it to run in multiple environments.
edit: Just realized you are the author. Now I feel silly for referring to you in the third person. In any case, I do want to say that despite any squabbling over terminology, you seem to be doing great work in putting out rill. Developing a full-blown application framework like this mostly on your own is no mean feat. My squabbling stands, though.
It's really not.
> Two things can be isomorphic to each other but one thing cannot called "isomorphic" without specifying what other thing it is isomorphic to.
Good thing we're talking about the relationship of client and server code then so we're not doing that then isn't it?
> isomorphism is about those two things having the same conceptual structure, despite being different things.
Yup, still perfectly on topic here with Client vs Server...
> In math...
Ah well, there's your problem. It's nothing to do with the mathematical definition of the term.
However, everyone knows what you're talking about when you say 'isomorphic javascript', so the pedantry doesn't really matter.
At it’s core Isomorphic JavaScript describes the relationship between the application that runs on the server and the one it serves to the client to run.
It's perfectly correct - because it's not describing the code it's describing the application(s) and the approach they take.
Isomorphic is 100% correct if you use the definition from biology, crystallography, sociology... etc etc. It's more technical of a term in one single field. In every other way it's a perfect description.
* Sociology: a similarity in the processes or structure.
* Crystallography: two structures closely similar in shape, formulation, and structure.
* Biology: a similarity of form or structure between organisms
All of these more closely describe a JavaScript application that lives on the client and server - because while they will be similar the likelihood of them having the complete same code (and therefore being universal is minimal.
Taken from crystallography, the JavaScript here is like the oxygen in silicon dioxide and in water. Same material, same physical properties, completely different structure and function depending on where it is.
Clearly you have yet to work on something that isn't just form validation and DOM rendering.
Everything you mentioned is achievable with Rill. I have found two simple ways to Isolate server only code in Rill.
1) Have two Rill servers, one with shared code and one without. Where the shared code server interacts with the isolated secure api from the other server.
2) Have one server that calls itself through http(s) requests where the api bits of the server and everything else you mention is hidden behind a "if (!process.browser)" statement. With browserify and other build tools you can have it automatically parse out any server side code. This is my preferred approach because I get to bundle all of the important parts of my app together while still having granular control over where things run.
That's all I'm trying to say here.
Call it what it really is: monolingual.
kthxbai!
-- Deleuze, as quoted in Sokal and Bricmont's "Fashionable Nonsense."
Misusing technical terms in order to fake a veneer of intellectual respectability should be called out every time.