question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Beyond SPAs — all app types support. (SSR, MPA, Static Website, Backend-Only, ...)

See original GitHub issue

The zero-config usage of Parcel creates an SPA.

For many applications an SPA doesn’t work out. (Because of search engines, social sharing, and performance.)

The Problem

The main problem of our current tools is that they support only one app type. For example for React:

  • create-react-app, Parcel, and webpack create an SPA.
  • Next.js creates an SSR app (or a static website).
  • Gatsby creates a static website.

By choosing one of these tools you are essentially choosing an app type and locking yourself into that app type. This means that before choosing one of these tools you have to research about what “SPA”, “SSR”, and “static website” mean and what the differences between them are. And that before even having started writing one line of code.

Even worse is that, most often than not, it’s not possible to predict which app type is the right one before having created and battle-tested a first prototype.

Strictly speaking, saying that Parcel and Webpack create an SPA is not true. But creating app types other than SPAs (e.g. an SSR app) is very difficult with Parcel/Webpack alone.

A Solution

From a user pespective, it would be neat to be able to use Parcel to easily create all kinds of app types. (SSR, MPA, Static Rendering, etc.) Basically having Parcel support all app types with (almost)-zero-config.

I can see that this would bring many problems from the perspective of Parcel’s code architectural design. And Parcel would be less do-one-thing-do-it-well.

But, now that Parcel v2’s core is small, maybe all app type support could be implemented as a suit of plugins instead of creeping all app type support into Parcel’s core.

The best UI for all app type support I’ve designed so far is centered around:

  • Page configs
  • Render functions
  • Server middleware

Page configs:

// A page config

// Also works with any other isomorphic view library such as Vue
import React from 'react';

export default {
  route: '/hello/:name',
  view: ({name}) => (
    <div>
      Hello {name}, welcome.
    </div>
  ),

  // By default, an SPA is built:
  renderToDom: true,
  renderToHtml: false,

  /* To add SSR:
  renderToHtml: true,
  */

  /* For Static Rendering:
  renderToHtml: true,
  renderHtmlAtBuildTime: true,
  */

  /* To remove browser-side JavaScript:
  renderToDom: false,
  */
};

Render functions:

// DOM Render

// This DOM render is for React but any kind of render can be written
// for Vue, Preact, React Native Web, etc.

import React from 'react';
import ReactDOM from 'react-dom';

export default domRender;

async function domRender({page, initialProps, CONTAINER_ID}) {
  ReactDOM.hydrate(
    React.createElement(page.view, initialProps),
    document.getElementById(CONTAINER_ID)
  );
}
// HTML Render

// This HTML render is for React but any kind of render can be written
// for Vue, Preact, React Native Web, etc.

const React = require('react');
const ReactDOMServer = require('react-dom/server');

module.exports = htmlRender;

async function htmlRender({page, initialProps}) {
  const html = (
    ReactDOMServer.renderToStaticMarkup(
      React.createElement(page.view, initialProps)
    )
  );

  return html;
}

Server middleware:

const express = require('express');
const parcel = require('@parcel/server');

const app = express();

// The `parcel` middleware serves your pages.
app.use(parcel);

// When the backend is a Node.js server, a middleware is super convenient.
// There are many reasons for that and I can elaborate more if you want.

To add SSR to a page you’d simply set renderToHtml: true. A static website can be built by setting renderHtmlAtBuildTime: true to all page configs. Browser-side JavaScript can be removed by setting renderToDom: true (super important from a mobile performance perspective). And so on and so forth. All app types are supported that way. This also intoduces new app types that aren’t widespread (yet).

Not only does this design support all app types, but it also allows to easily switch from one app type to another. It would be super neat to have a (almost-)zero-config way to switch between app types. So that the user doesn’t have to research what “SPA” or “SSR” mean before writing his first prototype. He can start coding and take care of the right app type later.

As far as I can see, this design could be a sweat spot between ease of use and flexibility.

The design can be used with any isomorphic view library. (With isomorphic view library I mean a library that can render views to HTML as well as to the DOM.)

Is supporting all app types something Parcel would be interested in?

I’m asking because I suspect that supporting all app types will need changes in Parcel’s design, such as support for different targets for different entries.

It seems that a server middleware as shown above could be implemented as a reporter plugin. Instead of re-writing the dev server from scratch, maybe code from the current dev server could be re-used.

I’m busy at the moment but I’ll further dig into all that and into the Parcel plugin APIs later.

I’ve said it many times already, but again, thanks for zero-config. It’s wonderful to be able to quickly build an app without unnecessarily loosing time on infrastructure.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
DeMoorJaspercommented, Sep 1, 2019

@brillout awesome, I always thought Next.js was heading that way with their framework. But anyway that’s off topic for Parcel.

About my experiment with blazingly-ssr I’ll probably be rewriting it again once Parcel 2 is a bit more stable, not sure if I’d turn it into a production ready tool though (probably more an experiment to showcase the posibilities of Parcel 2). Anyway I’d also be up for any collaboration on that, hit me up on twitter for that as this issue is probably off-topic for the Parcel repo.

1reaction
brilloutcommented, Sep 1, 2019

@DeMoorJasper

I understand that feasbibility is a concern from your perspective. But note that:

  • My tool focuses only on building pages. Nothing more, nothing less; its scope is much smaller than for example Gatsby.
  • It’s already used in production.
  • It has some rough edges but these are mostly (>90%) related to Webpack.
  • I took great care of having a simple design that lowers developing work by an order of magnitude.
  • Whether to support all-app-types is mostly a design question, it only marginally increases the number of LOCs.

It’s not like effort for my tool = effort for Gatsby + effort CRA + effort Next.js. Not at all — my tool is only a page builder.

To give an order of magnitue of how small the tool is:

  • Core: ~1k LOC.
  • Plugins: ~2k LOC.
  • Helpers: ~7k LOC.

The core contains the logic for all-app-types support. The plugins are about integrations with various third-party libraries (path-to-regex for server-side routing, middlewares for express/koa/hapi, etc.)

What’s most interesting here is that out of 7k helpers, 5.5k is about managing the Webpack compilations. The Webpack API is far from great and it’s been a huge pain to build the tool on top of Webpack.

This means that more than half of the codebase is because of Webpack’s shortcomings. And all complex code are all related to this code. The rest of the codebase, including core, is actually fairly straightforward.

My hope here is that using Parcel instead of Webpack would cut my codebase size by up to two. It will then be easy to maintain my tool once/if it’s widely adpoted. E.g. the #3302 ticket will considerably help me.

Also I don’t want to compete here. I would actually very much welcome frameworks such as Next.js to use my tool. If they switch to parcel, they might as well use my parcel plugin(s) that I will implement. (If I implement my tool as Parcel plugin(s)).

Btw. I’ve seen your POC blazingly — I’d be up to collaborate.

@DeMoorJasper @Banou26 @devongovett

To me, this ticket is not about whether my tool will succeed. Where I may fail someone else may succeed.

This ticket is about this: as a Parcel community, do we want all-app-types support?

I will be writing more about the various benefits of all-app-types support in the coming weeks.

It’s not only about SSR and SPA. It’s also about new app types. For example what I call “Backend First App”: an app that is rendered to good old plain HTML (using React/Vue as HTML template engine). Almost everything is rendered to HTML and only a couple of interactive views are rendered to the DOM. This is wonderful for websites that are mostly about content, for example an online newspaper. Great mobile performance (since much less browser-side JavaScript), great SEO (since all content is rendered to HTML), interactive views, and fast dev speed (using React/Vue as HTML template engine is vastly simpler).

As far as I can see, all-app-types support will be obvious in the future. Just like it has become obvious that zero-config is the way to go for web app bundlers.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Beyond SPAs - alternative architectures for your PWA
First, I'm going to be covering what I like to call "Multi Page Apps", or "MPAs". MPA is a fancy name for the...
Read more >
SPAs and Server Side Rendering: A Must, or a Maybe?
Pros and cons of using Server-side rendering (SSR) to build your single-page applications (SPA). In this blog we will discuss the benefits ...
Read more >
Understanding Rendering in Web Apps: SPA vs MPA
While many have equated CSR with SPAs and SSR with MPAs, they are treaded as patterns which can be applied in either rendering...
Read more >
Comparing SPAs to SSG and SSR - Fauna
An in-depth comparison of the three strategies to JavaScript app ... Page Apps (SPA), Server Side Rendered Sites (SSR), and Static Site ......
Read more >
Server Side Rendering - Single SPA
In the context of single page applications (SPAs), server-side rendering (SSR) refers to dynamic generation of the HTML page that is sent from...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found