Aurelia static + enhanced site generator


#1

I’m working on a project to build a fast, mostly static site using Metalsmith, backed by a git repository with editing using NetlifyCMS.

Eventually we’re going to want some front end framework working with that too. Server side rendering is great, but for most, build time rendering will suffice. This is horribly being referred to as “JAM stack” :man_facepalming:.

One of the difficulties with SSR is that pages need to be renderable in nodejs. With static site generation, pages are rendered once at build time so speed is less important. This means pages could be rendered in headless chrome which makes things much simpler.

For other frameworks there is Gatsbyjs, vuepress, etc and we need something similar for Aurelia.

How much of this is possible with vCurrent?
Can we piggyback off any existing projects?


#2

I also wanted something in Aurelia to write some doc site, but found none. I probably have to make a choice between vuepress and docusaurus, or roll out a customised Aurelia app with just enough features. But I am not interested enough to invest my time to build an alternative site builder in Aurelia.

It should be quite doable with vCurrent + SSR, if you are interested to build one. I like vuepress’s simplicity. If anyone did a good one in Aurelia, I am pretty sure @EisenbergEffect will migrate official Aurelia website to it. The current site-generator is not easy to use, and it’s not generic to be used on anything else rather than official Aurelia website.


#3

I’d love to see something like this. I wonder whether we should try to build it on vNext though. It should be much simpler. @timfish What is your timeframe for needing the front-end solution?


#4

Yes, I agree that it all looks a lot easier with vNext.

Timeframe is in the next few months but a purely static is simple without Aurelia. Eventually we’re going to want some search and filter features.

I see customers with websites where they are adding more and more data to their CMS and creating huge monolithic websites. Not only does this become a nightmare to maintain, it becomes very slow especially when queries can’t hit the CDN cache. If your data doesn’t update in realtime, a database is usually a hindrance. Once you demonstrate the speed of a static site with client side search they’ll be impressed.

Gatsbyjs is particularly interesting because it doesn’t just limit your input data to markdown files. It can pull data from other files and sources or a headless CMS and presents it as a GraphQL API.

In development you get a GraphQL server which you can use to design your queries:

And then in your component you export the query and it gets passed to the component as data:

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default ({ data }) => {
  return (
    <Layout>
      <div>
        <h1>My Site's Files</h1>
        <table>
          <tbody>
            {data.allFile.edges.map(({ node }, index) => (
              <tr key={index}>
                <td>{node.relativePath}</td>
                <td>{node.prettySize}</td>
                <td>{node.extension}</td>
                <td>{node.birthTime}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </Layout>
  )
}

export const query = graphql`
  query {
    allFile {
      edges {
        node {
          relativePath
          prettySize
          extension
          birthTime(fromNow: true)
        }
      }
    }
  }
`

There are also hooks to do extra things at build time, like build your search index, etc.

Because there are already dozens of non-react plugins, it would be a shame not to piggyback off their ecosystem but the core does seem pretty well tied to react.

I tried to clone the Gatsby repository to take a look at how easy it would be to swap out react but I was working on 3G yesterday so it never completed.

It looks like I could use @aurelia/jit-html-jsdom to render an Aurelia app at build time.

@EisenbergEffect, what work is left on vNext to be able to “enhance” a pre-rendered Aurelia app?


#5

The good news is that all of vNext runs brilliantly inside of Node. So doing any kind of static generation should be very simple and fast. In terms of the generation process, it definitely would be more about how you want to tie in the data sources. I’ve heard others say good things about Gatsby, so maybe we just take inspiration from that (making sure to attribute them for their ideas).

In terms of enhancing a pre-rendered app, there are a couple of ways that you could do that:

  • If your static site only renders the host aurelia elements (not all their inner views), then you can use progressive enhancement to light those up at runtime.
  • If your static site attempts to “run” Aurelia at static site generation time and actually render out all the views for the components along with evaluating their binding expressions and writing them to the DOM, then you would need the “pick up and continue” feature to let Aurelia take control of the already existing components once it landed in the browser.

Neither of these is exactly ready yet in vNext, in terms of the browser. Progressive enhancement shouldn’t be too difficult to add as it’s just a special scenario for the root component of JIT-mode vNext app. The “pick up and continue” is a bit more complicated depending on what approach is taken. The easy way, and what most frameworks do, is just to re-render the app again on the client side, swapping out the server-rendered bits for the client-rendered bits when they are ready. Usually there’s some input event caching and re-targeting that are done as part of that as well.

@fkleuver is our tech lead on vNext and he’s been working a lot on the templating runtime lately, so he probably has the best feel for how much work would go into each of these. We’ve done it for vCurrent already, and since vNext is superior in so many ways, I can’t imagine it being a terrible amount of work. For the browser-continue work, we could probably re-use most of our vCurrent library, just fixing it up to use the vNext APIs.