Skip to content

Commit

Permalink
Almost have static rendering working
Browse files Browse the repository at this point in the history
  • Loading branch information
nhooyr committed Feb 2, 2020
1 parent fd54e44 commit d19c49a
Show file tree
Hide file tree
Showing 16 changed files with 1,192 additions and 932 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
out
coverage
node_modules
**/out
**/coverage
**/node_modules
4 changes: 3 additions & 1 deletion jest/config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
module.exports = {
collectCoverage: true,
moduleNameMapper: {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest/filemock.js",
"\\.(css|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
"<rootDir>/jest/filemock.js",
},
rootDir: "..",
transformIgnorePatterns: ["node_modules/(?!(navi-scripts)/)"],
}
23 changes: 12 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,31 @@
"private": true,
"scripts": {
"dev": "webpack-dev-server",
"prod": "webpack --mode production",
"prod": "webpack --mode production && yarn gen-static",
"gen-static": "GEN_STATIC=1 webpack --mode development && node src/genStatic/out/index.js",
"fmt": "make -f ./ci/Makefile fmt",
"lint": "make -f ./ci/Makefile lint",
"fix": "make -f ./ci/Makefile fix",
"test": "make -f ./ci/Makefile test",
"ci": "make -f ./ci/Makefile"
},
"devDependencies": {
"@babel/core": "^7.7.2",
"@babel/core": "^7.8.4",
"@babel/plugin-proposal-class-properties": "^7.7.0",
"@babel/preset-env": "^7.7.1",
"@babel/preset-env": "^7.8.4",
"@babel/preset-react": "^7.7.0",
"@babel/preset-typescript": "^7.7.2",
"@emotion/babel-preset-css-prop": "^10.0.23",
"@emotion/core": "^10.0.22",
"@svgr/webpack": "^5.0.1",
"@types/copy-webpack-plugin": "^5.0.0",
"@types/html-webpack-plugin": "^3.2.1",
"@types/jest": "^24.0.22",
"@types/html-webpack-plugin": "^3.2.2",
"@types/jest": "^25.1.1",
"@types/mini-css-extract-plugin": "^0.9.0",
"@types/react": "^16.9.11",
"@types/react-dom": "^16.9.4",
"@types/react-syntax-highlighter": "^11.0.3",
"@types/webpack-dev-server": "^3.4.0",
"@types/webpack-dev-server": "^3.10.0",
"@typescript-eslint/eslint-plugin": "^2.6.1",
"@typescript-eslint/parser": "^2.6.1",
"babel-loader": "^8.0.6",
Expand All @@ -35,14 +36,14 @@
"core-js": "3",
"css-loader": "^3.2.0",
"eslint": "^6.6.0",
"eslint-config-prettier": "^6.5.0",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-emotion": "^10.0.14",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.16.0",
"eslint-plugin-react": "^7.18.1",
"eslint-plugin-react-hooks": "^2.2.0",
"fork-ts-checker-webpack-plugin": "^3.1.0",
"fork-ts-checker-webpack-plugin": "^4.0.3",
"html-webpack-plugin": "^3.2.0",
"jest": "^24.9.0",
"jest": "^25.1.0",
"mini-css-extract-plugin": "^0.9.0",
"navi": "^0.14.0",
"prettier": "^1.19.1",
Expand All @@ -63,7 +64,7 @@
"typescript": "^3.7.2",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
"webpack-dev-server": "^3.10.2"
},
"resolutions": {
"vfile-message": "^2.0.0"
Expand Down
13 changes: 0 additions & 13 deletions public/index.html

This file was deleted.

4 changes: 2 additions & 2 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import Router, { routes } from "./Router"

it("renders without crashing", (): void => {
window.scroll = () => {
return
}
const div = document.createElement("div")
ReactDOM.render(<App />, div)
ReactDOM.render(<Router routes={routes} />, div)
ReactDOM.unmountComponentAtNode(div)
})
46 changes: 13 additions & 33 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,14 @@
import { css } from "@emotion/core"
import { lazy, mount, route } from "navi"
import React, { Suspense } from "react"
import { NotFoundBoundary, Router, View } from "react-navi"
import { NotFoundBoundary, View } from "react-navi"
import NotFound from "./components/404"
import Header from "./components/Header"
import Loading from "./components/Loading"
import { NotFound } from "./components/404"
import PostHeader from "./components/PostHeader"
import ScrollMemory from "./components/ScrollMemory"
import Home from "./Home"
import posts from "./posts"

const routes: { [path: string]: any } = {
"/": route({
view: <Home />,
}),
}

posts.forEach((p, i) => {
routes[p.meta.path] = lazy(async () => {
const Body = (await posts[i].body()).default
return route({
view: (
<>
<PostHeader {...p.meta} />
<Body />
</>
),
})
})
})

export default function App() {
return (
<Router routes={mount(routes)}>
<>
<ScrollMemory />
<Loading />
<div
Expand All @@ -57,13 +33,17 @@ export default function App() {
}
`}
>
<Suspense fallback={null}>
<NotFoundBoundary render={NotFound}>
<View disableScrolling />
</NotFoundBoundary>
</Suspense>
{typeof window !== "undefined" ? (
<Suspense fallback={null}>
<NotFoundBoundary render={NotFound}>
<View disableScrolling />
</NotFoundBoundary>
</Suspense>
) : (
<View disableScrolling />
)}
</main>
</div>
</Router>
</>
)
}
41 changes: 41 additions & 0 deletions src/Router.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { default as Navi, lazy, mount, route } from "navi"
import React from "react"
import * as ReactNavi from "react-navi"
import App from "./App"
import PostHeader from "./components/PostHeader"
import Home from "./Home"
import posts from "./posts"

export default function Router(props: { navigation?: Navi.Navigation; routes?: Navi.Matcher<{}> }) {
return (
<ReactNavi.Router {...props}>
<App />
</ReactNavi.Router>
)
}

function genRoutes() {
const routes: { [path: string]: any } = {
"/": route({
view: <Home />,
}),
}

posts.forEach((p, i) => {
routes[p.meta.path] = lazy(async () => {
const Body = (await posts[i].body()).default
return route({
view: (
<>
<PostHeader {...p.meta} />
<Body />
</>
),
})
})
})

return routes
}

export const routes = mount(genRoutes())
2 changes: 1 addition & 1 deletion src/components/404.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { css } from "@emotion/core"
import React from "react"
import H1 from "./H1"

export function NotFound() {
export default function NotFound() {
return (
<div
css={css`
Expand Down
39 changes: 39 additions & 0 deletions src/genStatic/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as fs from "fs"
import * as Navi from "navi"
import * as React from "react"
import ReactDOMServer from "react-dom/server"
import Router, { routes } from "../Router"

async function renderPageToString(path: string) {
const navigation = Navi.createMemoryNavigation({
routes: routes,
url: Navi.createURLDescriptor(path),
})

const route = await navigation.getRoute()

const rootHTML = ReactDOMServer.renderToString(<Router navigation={navigation} />)

let indexHTML = fs.readFileSync("out/index.html").toString()
indexHTML = indexHTML.replace(`<div id="root"></div>`, `<div id="root">${rootHTML}</div>`)
if (route.title) {
indexHTML = indexHTML.replace(`<title>nhooyr.io</title>`, `<title>${route.title}</title>`)
}
return indexHTML
}

async function main() {
const crawledRoutes = await Navi.crawl({
routes: routes,
})
for (const p of crawledRoutes.paths) {
const staticHTML = await renderPageToString(p)
let fileName = p.slice(1)
if (fileName === "") {
fileName = "index"
}
fs.writeFileSync(`out/${fileName}.html`, staticHTML)
}
}

main()
12 changes: 12 additions & 0 deletions src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>nhooyr.io</title>
<meta name="viewport" content="width=device-width" />
<link rel="shortcut icon" href="favicon.png" />
</head>
<body>
<div id="root"></div>
</body>
</html>
21 changes: 15 additions & 6 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import * as Navi from "navi"
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import "sanitize.css"
import "sanitize.css/forms.css"
import "sanitize.css/typography.css"
import Router, { routes } from "./Router"

// https://alxgbsn.co.uk/2011/10/17/enable-css-active-pseudo-styles-in-mobile-safari/
document.body.ontouchstart = () => null
async function main() {
// https://alxgbsn.co.uk/2011/10/17/enable-css-active-pseudo-styles-in-mobile-safari/
document.body.ontouchstart = () => null

const root = document.createElement("div")
document.body.appendChild(root)
ReactDOM.render(<App />, root)
const navigation = Navi.createBrowserNavigation({ routes })
// Ensures the current route is fully loaded to avoid flashes.
await navigation.getRoute()

const renderer = process.env.NODE_ENV === "production" ? ReactDOM.hydrate : ReactDOM.render

renderer(<Router navigation={navigation} />, document.getElementById("root"))
}

main()
7 changes: 6 additions & 1 deletion src/posts/1-TimeToGiveBack.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import React from "react"
import Link from "../components/Link"
import P from "../components/P"

export default function BeginningMyBlog() {
return (
<>
<P>Hi, I'm Anmol. I go by nhooyr on the internet. I'm a software engineer from Toronto.</P>
<P>
I'm fairly young as far as experienced software engineers go
The last three years of my life have been the most wonderful and unexpected. In I dropped out of high school in
Grade 12 to take a full time software engineering position at <Link href="https://coder.com">Coder</Link>. I
went from dropping out of high school in Grade 12 to becoming a senior software engineer at{" "}
<Link href="https://coder.com">Coder</Link>. In the 3 I'm a fully self taught engineer, never went to school for
software.
</P>
</>
)
Expand Down
16 changes: 8 additions & 8 deletions src/posts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ export function formatDate(date: Date) {
}

const index: Array<Post> = [
// {
// meta: {
// title: "Why nhooyr?",
// path: "/why-nhooyr",
// publishDate: new Date("Feb 9, 2020"),
// },
// body: () => import("./2-WhyNhooyr"),
// },
{
meta: {
title: "Why nhooyr?",
path: "/why-nhooyr",
publishDate: new Date("Feb 9, 2020"),
},
body: () => import("./2-WhyNhooyr"),
},
{
meta: {
title: "Time To Give Back",
Expand Down
File renamed without changes.
20 changes: 13 additions & 7 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import MiniCssExtractPlugin from "mini-css-extract-plugin"
import path from "path"
import webpack from "webpack"

export default (env: {}, argv: { mode: string }): webpack.Configuration => {
export default (env: {}, argv: { mode: string }) => {
const dev = argv.mode !== "production"
const genStatic = process.env.GEN_STATIC && process.env.GEN_STATIC !== ""

return {
const config: webpack.Configuration = {
entry: "./src/index.tsx",
module: {
rules: [
Expand Down Expand Up @@ -51,11 +52,7 @@ export default (env: {}, argv: { mode: string }): webpack.Configuration => {
new CleanWebpackPlugin(),
new ForkTsCheckerWebpackPlugin(),
new HtmlWebpackPlugin({
title: "nhooyr.io",
meta: {
viewport: "width=device-width",
},
favicon: "public/favicon.png",
template: "./src/index.html",
}),
new CopyPlugin([{ from: "public/", to: "." }]),
new MiniCssExtractPlugin({
Expand All @@ -71,4 +68,13 @@ export default (env: {}, argv: { mode: string }): webpack.Configuration => {
writeToDisk: true,
},
}

if (genStatic) {
config.target = "node"
config.entry = "./src/genStatic/index.tsx"
config.output!.path = path.resolve("src/genStatic/out")
config.output!.filename = "index.js"
}

return config
}
Loading

0 comments on commit d19c49a

Please sign in to comment.