Pedro Cattori · @pcattori

Legendary DX

The Quest for

Part I

                   

<Link to="the past"/>

1: File Server 🗡️

🤩

Browser

📚

html, css, js

🫥

📚

🫥

📚

📚

🫥

📚

📚

🤩

📚

2: Build + Watch 🗡️

📁

Source code

ESM

📁

Source code

ESM

📁

Source code

🤓

Compiler

🫥

🤓

📁

🤓

📁

🫥

📚

🫥

📚

🤓

📁

📚

🫥

📚

📚

🤓

📁

🤩

📚

🤓

📁

🤩

📚

✍️

🤓

📁

👀

📁

🤩

📚

✍️

✍️

🤓

📁

🤩

📚

✍️

✍️

🤓

📁

🤩

📚

✍️

✍️

3: Live Reload 🗡️

🤩

📚

✍️

🤓

📁

👀

📁

🤩

📚

✍️

✍️

🤓

📁

🤩

📚

✍️

✍️

🔁

🤩

📚

🤓

📁

🤓

📁

🔁

✍️

✍️

🔁

📚

🤓

📁

🤓

📁

✍️

✍️

🫥

📚

🤓

📁

🤓

📁

📚

✍️

✍️

🫥

📚

🤓

📁

🤓

📁

📚

🤩

📚

🤓

📁

🤓

📁

✍️

4: HMR 🗡️

🤠

hot-swap.js

🤠

hot-swap.js
(aka HMR runtime)

🫥

🤓

📁

🤓

📁

🫥

📚

🤠

🫥

📚

🤓

📁

📚

🤠

🤠

🫥

📚

📚

🤓

📁

🤠

🤠

🤩

📚

🤓

📁

🤠

🤠

🤩

📚

✍️

🤓

📁

🤠

🤠

👀

📁

🤩

📚

✍️

✍️

🤠

🤠

🤓

📁

🤩

📚

✍️

✍️

✍️

🤠

🤠

🤩

📚

🤓

📁

🤓

📁

✍️

✍️

✍️

🤠

🤠

🤩

📚

🤓

📁

🤓

📁

✍️

✍️

✍️

🔁

🤠

🤩

📚

🤓

📁

🤓

📁

✍️

✍️

✍️

🤠

🤠

DEMO #1

Tears of the Server

Part II

                   

😎

App Server

📙

server.js

🤓

🫥

📁

🤓

🫥

📁

📚

📙

🤠

🤓

🫥

📁

📚

📙

🤠

🏃‍♂️

📙

🤓

🫥

📁

📚

📙

🤠

🏃‍♂️

📙

🤓

🫥

📁

📚

📙

🤠

😎

localhost:3000

🤓

🫥

📁

📚

📙

🤠

😎

🤓

🫥

📁

📚

📙

🤠

😎

📚

🤠

🤓

🫥

📁

📚

📙

🤠

😎

📚

🤠

{"place": "world"}

🤓

🫥

📁

📚

📙

🤠

😎

📚

🤠

{"place": "world"}

🤓

🤩

📁

📚

📙

🤠

😎

🤠

🌇

{"place": "world"}
import { json } from "@remix-run/node"
import { useLoaderData } from "@remix-run/react"

export let loader = () => {
  return json({ place: "world" })
}

export default Component() {
  let { place } = useLoaderData<typeof loader>()
  return (
    <main>
      <h1>Hey there, Remix Conf 👋</h1>
      <h2>And hello, {place}!</h2>
    </main>
  )
}

✍️

import { json } from "@remix-run/node"
import { useLoaderData } from "@remix-run/react"

export let loader = () => {
  return json({ place: "world" })
}

export default Component() {
  let { place } = useLoaderData<typeof loader>()
  return (
    <main>
      <h1>Hey there, friends 👋</h1>
      <h2>And hello, {place}!</h2>
    </main>
  )
}

✍️

import { json } from "@remix-run/node"
import { useLoaderData } from "@remix-run/react"

export let loader = () => {
  return json({ location: "Salt Lake City" })
}

export default Component() {
  let { place } = useLoaderData<typeof loader>()
  return (
    <main>
      <h1>Hey there, friends 👋</h1>
      <h2>And hello, {place}!</h2>
    </main>
  )
}

✍️

import { json } from "@remix-run/node"
import { useLoaderData } from "@remix-run/react"

export let loader = () => {
  return json({ location: "Salt Lake City" })
}

export default Component() {
  let { location } = useLoaderData<typeof loader>()
  return (
    <main>
      <h1>Hey there, friends 👋</h1>
      <h2>And hello, {location}!</h2>
    </main>
  )
}

✍️

SAVE

✍️

import { json } from "@remix-run/node"
import { useLoaderData } from "@remix-run/react"

export let loader = () => {
  return json({ location: "Salt Lake City" })
}

export default Component() {
  let { location } = useLoaderData<typeof loader>()
  return (
    <main>
      <h1>Hey there, friends 👋</h1>
      <h2>And hello, {location}!</h2>
    </main>
  )
}

🤓

🤩

📁

📚

📙

🤠

😎

🤠

🌇

✍️

{"place": "world"}

👀

🤩

📁

📚

📙

🤠

😎

🤠

🌇

✍️

✍️

✍️

{"place": "world"}

🤓

🤩

📁

📚

📙

🤠

😎

🤠

🌇

✍️

✍️

✍️

✍️

{"place": "world"}

🤓

🤩

📁

📚

📙

🤠

😎

🤠

🌇

✍️

✍️

✍️

✍️

{"place": "world"}

🤓

🤩

📁

📚

📙

🤠

😎

🔁

🌇

✍️

✍️

✍️

✍️

{"place": "world"}

🤓

🤯

📁

📚

📙

🤠

😎

🤠

✍️

✍️

✍️

✍️

{"place": "world"}
let { location } =

Demo #2

🤓

😎

🥸

?

🥸

!=

😎

🥸

!=

😎

🐞

🐛

🥸

!=

😎

🐞

🐛

🐰

🐆

🥸

!=

😎

🥸

~=

😎

🥸

~=

😎

🥸

~=

😎

💡

💡

🤓

👂

📣

😎

"Ready!"

Part III

A               between Worlds

fetch

🤓

🤩

📁

😎

🤓

🤩

📁

😎

💪

🤓

🫥

📁

📚

📙

🤠

🤓

🫥

📁

📚

📙

🤠

📙

🏃‍♂️

🤓

🫥

📁

📚

📙

🤠

📙

🏃‍♂️

🤓

🫥

📁

📚

📙

🤠

😎

🤠

📚

🤓

🫥

📁

📚

📙

🤠

😎

🤠

📚

🤓

🫥

📁

📚

📙

🤠

😎

🤠

📚

📚

🤓

🫥

📁

📚

📙

🤠

😎

🤠

📚

📚

🤓

🤩

📁

📚

📙

🤠

😎

🤠

📚

🤓

🤩

📁

📚

📙

🤠

😎

🤠

📚

✍️

👀

🤩

📁

📚

📙

🤠

😎

🤠

📚

✍️

✍️

✍️

🤓

🤩

📁

📚

📙

🤠

😎

🤠

📚

✍️

✍️

✍️

🤓

🤩

📁

📚

📙

🤠

😎

🤠

📚

✍️

✍️

✍️

👂

🤓

🤩

📁

📚

📙

🤠

👀

🤠

📚

✍️

✍️

✍️

👂

🤓

🤩

📁

📚

📙

🤠

💀

🤠

📚

✍️

✍️

✍️

👂

🤓

🤩

📁

📚

🤠

🏃‍♂️

🤠

📚

✍️

✍️

👂

✍️

📙

📙

✍️

🤓

🤩

📁

📚

🤠

😎

🤠

📚

✍️

✍️

👂

✍️

📙

✍️

🤓

🤩

📁

📚

🤠

😎

🤠

📚

✍️

✍️

👂

✍️

📙

✍️

🤓

🤩

📁

📚

🤠

😎

🤠

📚

✍️

✍️

✍️

📙

✍️

✍️

🤓

🤩

📁

📚

🤠

😎

🤠

📚

✍️

✍️

✍️

📙

✍️

✍️

🤓

🤩

📁

📚

🤠

😎

📚

✍️

✍️

✍️

📙

✍️

✍️

{"location": "world"}

🤓

🤩

📁

📚

🤠

😎

🔁

📚

✍️

✍️

✍️

📙

✍️

{"location": "world"}

✍️

🤓

🤩

📁

📚

🤠

😎

🔁

📚

✍️

✍️

✍️

📙

✍️

{"location": "world"}

✍️

🤓

🤩

📁

📚

🤠

😎

🤠

📚

✍️

✍️

✍️

📙

✍️

✍️

let { location } =
{"location": "world"}

Hot Data Revalidation

🔥

🔥

😎

💀

🏃‍♂️

😎

✍️

😎

💀

🏃‍♂️

😎

✍️

downtime

😎

💀

🏃‍♂️

😎

✍️

downtime

👎

Part IV

Ocarina of Downtime

😎

😎

✍️

💀

🏃‍♂️

🤠

hot-swap-server.js

😎

🤠

📙

😎

🤠

📙

✍️

😎

👀

📙

✍️

✍️

😎

🤠

📙

✍️

✍️

😎

🔁

📙

✍️

✍️

😎

🤠

📙

✍️

✍️

const BUILD_PATH = path.resolve(__dirname, "build");

function purgeRequireCache() {
  for (const key in require.cache) {
    if (key.startsWith(BUILD_DIR)) {
      delete require.cache[key];
    }
  }
}

const watcher = chokidar.watch(BUILD_PATH);

watcher.on("all", () => {
  // 1. purge require cache
  purgeRequireCache();
  // 2. load updated server build
  const build = require(BUILD_PATH);
  // 3. tell dev server that this app server is now ready
  broadcastDevReady(build);
});

let createDevRequestHandler = (req, res, next) => {
  return createRequestHandler({
    build: require(BUILD_DIR),
    mode: "development",
  })(req, res, next);
}
CJS
function createDevRequestHandler() {
  let devBuild = build;

  const watcher = chokidar.watch(BUILD_PATH, { ignoreInitial: true });
  watcher.on("all", async () => {
    // 1. purge require cache && load updated server build
    const stat = fs.statSync(BUILD_PATH);
    devBuild = import(BUILD_PATH + "?t=" + stat.mtimeMs);
    // 2. tell dev server that this app server is now ready
    broadcastDevReady(await devBuild);
  });

  return async (req, res, next) => {
    return createRequestHandler({
      build: await devBuild,
      mode: "development",
    })(req, res, next);
  };
}
ESM

🤓

🤩

😎

🤓

🤩

😎

🤓

🤩

😎

🤓

🤩

😎

🤓

🤩

😎

🤓

🤩

😎

https://remix.run/blog/remix-data-flow

🤓

🤩

😎

https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow

🤓

🤩

😎

🤓

🤩

😎

🤓

🤩

😎

Made with Slides.com