Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: compatibility with latest versions of React and Next #55

Merged
merged 29 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
25008c6
refactor(server.tsx): organize imports, remove some anys, adapt types
Aug 3, 2023
1b92401
chore: update non-critical deps
Aug 3, 2023
71d5d1a
test: move client and server tests in different folders with their ow…
Aug 4, 2023
a7e38a0
chore: update react packages and their types, add ts-node for jest ts…
Aug 4, 2023
c245e23
refactor: use renderToPipeableStream instead of deprecated renderToNo…
Aug 4, 2023
f011e29
chore: update deps, add exports field in package.json, update eslint …
Aug 10, 2023
cdb303a
fix(createIncludeElement): fix react hydration error
Aug 10, 2023
d844a66
test: adapt and fix tests
Aug 10, 2023
42a0e84
docs(WIP): add express and next + express example
Aug 10, 2023
9fba89c
docs(examples/express): cleanup, formating, improve setup, add compose
Aug 11, 2023
b7bd742
docs(examples/next): formating, fixed next version
Aug 11, 2023
d888d6a
refactor(lib): make browser detection bundler agnostic
Aug 11, 2023
49fd7a0
chore(lib): add missing exports in package.json, add dist and yarn-er…
Aug 11, 2023
9570f2f
docs(readme): adapt examples, update and add links, add line breaks
Aug 11, 2023
ff9cf72
refactor(lib): bring back original createIncludeElement behavior
Aug 15, 2023
014e843
chore: update prettier and eslint config and scripts, format/fix, upd…
Aug 15, 2023
cebd391
refactor: review fixes
Aug 17, 2023
2bd766d
refactor: more review fixes
Aug 17, 2023
fe76b95
chore: cleanup default.vcl configs and fix varnish compose images ver…
Sep 5, 2023
569522d
docs: add readme to express example, update next and main readme
Sep 5, 2023
c933f03
docs: improve examples readme
Sep 5, 2023
d4da2c0
chore(examples): update deps
Sep 6, 2023
5fe117d
refactor(lib): don't escape attributes as react do it by itself now
Sep 6, 2023
60f53d7
refactor(express): use default export for App and improve server html
Sep 6, 2023
e587da0
Fix some style issues in README.md
dunglas Jan 3, 2024
1a0179c
Update compose.yaml
dunglas Jan 3, 2024
9bcb5a1
EOF in default.vcl
dunglas Jan 3, 2024
828fbf5
Update compose.yaml
dunglas Jan 3, 2024
18b55ed
Fix indentation in default.vcl
dunglas Jan 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"prettier"
"prettier",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/lib
/node_modules
node_modules
/coverage
26,435 changes: 26,435 additions & 0 deletions examples/express/built/app.js

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions examples/express/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
23 changes: 23 additions & 0 deletions examples/express/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"author": "Kévin Dunglas",
"dependencies": {
"express": "^4.18.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-esi": "file:../../"
},
"description": "An example project to demonstrate usage of ESI with Express",
"devDependencies": {
"@vitejs/plugin-react": "^4.0.4",
"vite": "^4.4.8"
},
"license": "MIT",
"main": "index.js",
"name": "esi-express-example",
"repository": "https://github.com/dunglas/react-esi/examples/express",
"scripts": {
"dev": "vite",
"server": "node src/server.mjs"
},
"version": "1.0.0"
}
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
34 changes: 34 additions & 0 deletions examples/express/src/components/MyFragment.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// components/MyFragment.js
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
import React from 'react';

export default class MyFragment extends React.Component {
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
render() {
return (
<section>
<h1>A fragment that can have its own TTL</h1>

<div>{this.props.greeting /* access to the props as usual */}</div>
<div>{this.props.dataFromAnAPI}</div>
</section>
);
}

static async getInitialProps({ props, res }) {
return new Promise(resolve => {
if (res) {
// Set a TTL for this fragment
res.set('Cache-Control', 's-maxage=60, max-age=30');
}

// Simulate a delay (call to a remote service such as a web API)
setTimeout(
() =>
resolve({
...props, // Props coming from index.js, passed through the internal URL
dataFromAnAPI: 'Hello there'
}),
2000
);
});
}
}
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 5 additions & 0 deletions examples/express/src/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";
import { hydrateRoot } from "react-dom/client";
import { App } from "./pages/App";

hydrateRoot(document.getElementById("root"), <App />);
15 changes: 15 additions & 0 deletions examples/express/src/pages/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// pages/index.js
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
import React from 'react';
import withESI from 'react-esi/lib/withESI';
import MyFragment from '../components/MyFragment';

const MyFragmentESI = withESI(MyFragment, 'MyFragment');
// The second parameter is an unique ID identifying this fragment.
// If you use different instances of the same component, use a different ID per instance.

export const App = () => (
<div>
<h1>React ESI demo app</h1>
<MyFragmentESI greeting="Hello!" />
</div>
);
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
46 changes: 46 additions & 0 deletions examples/express/src/server.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// server.js
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
import express from "express";
import { path, serveFragment } from "react-esi/lib/server";
import * as ReactDOMServer from 'react-dom/server';
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
import { App } from "./pages/App";
import React from "react";

const server = express();
server.use((req, res, next) => {
// Send the Surrogate-Control header to announce ESI support to proxies (optional with Varnish, depending of your config)
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
res.set("Surrogate-Control", 'content="ESI/1.0"');
next();
});

server.get('/', (req, res) => {
const app = ReactDOMServer.renderToString(<App />);

const html = `
<html lang="en">
<head>
<script src="app.js" async defer></script>
</head>
<body>
<div id="root">${app}</div>
</body>
</html>
`
res.send(html);
})

// "path" default to /_fragment, change it using the REACT_ESI_PATH env var
server.get(path, (req, res) => {
return serveFragment(
req,
res,
// "fragmentID" is the second parameter passed to the "WithESI" HOC, the root component used for this fragment must be returned
(fragmentID) => require(`./components/${fragmentID}`).default
);
});

// ...
// Other Express routes come here

server.use(express.static("./built"));

server.listen(8080);
16 changes: 16 additions & 0 deletions examples/express/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
optimizeDeps: {
include: ['react-esi'],
},
build: {
commonjsOptions: {
include: [/react-esi/, /node_modules/],
},
},
// define: {'process.env': process.env}
})
43 changes: 43 additions & 0 deletions examples/express/yarn-error.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Arguments:
J3m5 marked this conversation as resolved.
Show resolved Hide resolved
/home/jeremy/.asdf/installs/nodejs/18.16.1/bin/node /home/jeremy/.cache/node/corepack/yarn/1.22.19/bin/yarn.js install

PATH:
/home/jeremy/.asdf/plugins/nodejs/shims:/home/jeremy/.asdf/installs/nodejs/18.16.1/bin:/home/jeremy/.local/share/pnpm:/home/jeremy/.asdf/shims:/home/jeremy/.asdf/bin:/home/jeremy/.local/bin:/home/jeremy/.local/share/pnpm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

Yarn version:
1.22.19

Node version:
18.16.1

Platform:
linux x64

Trace:
Error: ENOENT: no such file or directory, stat '/home/jeremy/dev/tilleuls/interne/react-esi/examples/express/node_modules/react-esi'

npm manifest:
{
"author": "Kévin Dunglas",
"dependencies": {
"react-esi": "link: ../../lib"
},
"description": "An example project to demonstrate usage of ESI with Express",
"license": "MIT",
"main": "index.js",
"name": "esi-express-example",
"repository": "https://github.com/dunglas/react-esi/examples/express",
"version": "1.0.0"
}

yarn manifest:
No manifest

Lockfile:
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


"react-esi@link:lib":
version "0.0.0"
uid ""
Loading