I am using static-site-generator-webpack-plugin [0] on a client project now and it has been fantastic. I have one json file full of all the data of the site and then a bunch of components that render it in various ways. I've got translations in several languages plus the components can use React-Intl to get text, dates, etc. in the right format for the locale.
The experience has been fantastic compared to other static site generators (very limited control over display of content) or CMSes (too indirect for what is basically simple logic, especially around internationalization).
It was a bit fiddly getting everything set up so that React, React Router, React Intl, and Static Site Generator all played nicely together. But after about a day of banging my head on that, it's just worked ever since and been a dream.
If I could ask for one improvement: right now the build first runs the code through Babel and then runs that through WebPack. Problem is, if parts of the Babel build fail, there's no error reporting, and instead I get a WebPack-stage error about some file not being available. I then have to manually run the file through Babel to see that there's a simple syntax error.
I'm using pretty much the same setup, and the only trouble I have is that simple React exceptions can cause webpack-dev-server to terminate. It's not the end of the world, just kind of annoying to have to restart the dev server if I misspelled a variable!
I'm not sure if this is the same problem you've encountered, but if you find a solution I'm definitely interested. :)
This is a pretty neat approach to building a static site, and it reminds me that a couple months ago I was experimenting with building a static site generator in Clojure. Which makes me think – is there any reason something like this couldn't be done with Clojurescript and Reagent? I've been itching to try out both of those but haven't come up with a good project for it.
The hard part might be routing, since there doesn't seem to be a robust solution for doing that in Reagent yet. I found https://github.com/ghedamat/reagent-react-router but it hasn't been updated in months and the author calls it "very very alpha."
I've been using reagent with re-frame[1]. Routing just uses goog.events and goog.history to listen for navigation events, secretary[1] to define routes, which update the state rendered by your components. The code is here: https://github.com/Day8/re-frame-template/blob/master/src/le...
What is the argument for going completely static? Static as in not using React on the client, not as in static files.
It seems (to me), that it would be useful--in addition to the static html--load React on the client and from that point navigate with push state and small static (JSON?) files. It might perform better if your blog has a lot more interactivity. Although, here I can definitely see that as being fluff.
This doesn't make sense. You can still generate all of the HTML with react tags for SEO. The difference, is you can still use React in the client after page load.
I played around with building something similar. The problem becomes that you have to send down twice the amount of data for the page - the statically rendered html generated from your data and then the data itself so that when the React components mount their props/state match the statically generated html.
A few of the flux implementations have the concept of "rehydrating" state (serializing and deserializing the stores), which does allow the client side to reuse the data and keeps the component from refetching the data.
A useful pattern I discovered was fetching just what is necessary to render the page on the server. Then pass the state to the window object through a script tag and recover the data on the client side and rehydrate. Any additional data (or potentially slow returning), I fetch client side via `componentDidMount` [0] which isn't called on the server. This way, I can get a loading screen up as quickly as possible with a few elements custom to the user.
I should note that even thought the flux library I was using, flummox [1], works great for this, I can't recommend it as in the month and a half I was working on my project they've decided to quit and recommend a different library, so I'm not sure what to recommend now (the frustration I feel over this quick turnaround is an entirely separate topic, though).
Depending on the kind of content t you have, that's hardly an issue. I've built a big site like this, and gzip does an extremely good job at filtering out duplicate data. Check the source of http://viva.vlaanderen/
when you view the source of your page, you see that very little of the dehydrated state is used to build your initial markup.
The entire rendered source is 142K. I isolated the actual markup, and it weighs in at 31K.
In other words, your dehydrated state is 4x bigger than your html rendering. And that's not including your 750K main.js file that also gets downloaded.
That's almost 1MB of downloads (not including images and stylesheets) just to "app-ify" your 31K of markup. I tend to agree, it's not a problem. Or perhaps, it's not one of the biggest problems. But it's not "hardly an issue" either.
The easy fix for that is to send the data asynchronously in a separate request. It takes a little longer for the page to go "live", but the static part is functional quicker.
A harder fix is to walk the static DOM to inflate your store. It shouldn't be too hard since you can add hints to the DOM to guide your parser.
I like the idea of React. However, Mixing HTML in your javascript is a very bad thing. You are mixing presentation with logic, and i always try to prevent that. Keep your logic away from your templates. I think its doable with react, but most people dont do it... Can somebody explain me why?
This sentiment is an artifact of javascript being used to add functionality to an existing document, which is still a very useful case for javascript, and it seems people are dismissing it, which is a shame.
When you're building an application, something like the atom text editor, or the youtube video player — something interactive and ostensibly not a document — the segregation of markup and javascript is artificial. Yes, it's a good idea to keep your presentation separate from your logic (although religious devotion to this idea is unnecessary, it's just an abstraction that's useful has stood the test of time, not holy law), but your javascript view code is just as much a part of the presentation as the markup.
In response to a sibling comment, you claim "you dont want to mix the 'structure' of your UI with the behaviour". The fact that your views have a "structure" to begin with is again an artifact of the web's original intention of hosting documents rather than applications. The structure of your view is actually an implementation detail (a concept that's formalized by the Shadow DOM standard in the WebComponents proposal), and separating it out from your view code implies otherwise.
I hear this complaint a lot about JSX but what you have to understand is that it is actually way better than using a template language.
If you're also against things like Handlebars, ERB, Smarty, etc then fine... but otherwise this doesn't hold up.
Why? Because all template languages must be compiled to the host language to work. Handlebars ends up as JS functions (and really ugly and messy ones I might add) for example.
This is fine if, for some reason, you're in 2001 and handing off all templating to designers who know nothing about code and just have to put HTML in a template with the right variables... but it's a very very janky practice.
JSX just says "well, why bother when you can do it in the right place in the first place?" Template languages have logic so why not just use JS and correctly encapsulate the logic in a View?
Answer? No good reason to not do that... so it's a net win.
React is a view layer, so a good React component is all presentation and doesn't contain any business logic. The only logic in a React component is presentation logic, which belongs together with your presentation structure and your presentation style, IMO.
I like this answer, however, its still not sufficient. Because you dont want to mix the "structure" of your UI with the behaviour of it. But in very dynamic apps behaviour = structure. So in that case React makes sense.
However, i dove into web components with Polymer, and it seems that this is the "official" direction of components in the future web... It also doesnt try to mix HTML with JavaScript. In fact in the future there will be more langauges than javascript since there will be a bytecode for the browser. Having your app written in React poses a real problem when you want to switch your logic to a different programming language.
> you dont want to mix the "structure" of your UI with the behaviour of it.
And you don't have to with React. But you can do this kind of mess with any templating langauge - it's not a React issue, it's a bad programming issue.
> Having your app written in React poses a real problem when you want to switch your logic to a different programming language.
It really shouldn't. It's a View layer and the JSX part will be (practically) HTML still so it'll be really easy to port. The rest of the view logic would have to be ported no-matter what you use to decorate it.
I think that kind of thinking is really suitable for the JS world of a few years back. If you're just using vanilla JS + DOM API, it can be pretty messy to include HTML in your JS. However React's setState handles DOM changes and rendering, so it's less of a pain. So in answer to your question of why people don't, I think it's because they're not viewing this as a problem anymore.
The experience has been fantastic compared to other static site generators (very limited control over display of content) or CMSes (too indirect for what is basically simple logic, especially around internationalization).
It was a bit fiddly getting everything set up so that React, React Router, React Intl, and Static Site Generator all played nicely together. But after about a day of banging my head on that, it's just worked ever since and been a dream.
If I could ask for one improvement: right now the build first runs the code through Babel and then runs that through WebPack. Problem is, if parts of the Babel build fail, there's no error reporting, and instead I get a WebPack-stage error about some file not being available. I then have to manually run the file through Babel to see that there's a simple syntax error.
[0] https://github.com/markdalgleish/static-site-generator-webpa...