diff --git a/client/package.json b/client/package.json
index 1acdd43..7eaf34a 100644
--- a/client/package.json
+++ b/client/package.json
@@ -5,25 +5,27 @@
"description": "tech tools hosted on cloudflare worker",
"main": "index.js",
"scripts": {
- "build": "npm run compilehbs && npm run transpilehbs && rm src/*-original.js",
- "compilehbs": "handlebars -e hbs -f src/pages-original.js src/views/pages/ && handlebars -e hbs -p -f src/partials-original.js src/views/partials/",
+ "build": "webpack",
"deploy": "wrangler deploy src/index.js",
"prepare": "husky",
- "start": "wrangler dev src/index.js",
- "test": "echo \"Error: no test specified\" && exit 1",
- "transpilehbs": "hbs-import-transpile src/pages-original.js > assets/pages.js && hbs-import-transpile src/partials-original.js > assets/partials.js"
+ "start": "wrangler dev src/index.js"
},
- "type": "module",
"author": "",
"license": "ISC",
"devDependencies": {
- "hbs-import-transpile": "^1.0.4"
+ "@babel/core": "^7.24.8",
+ "@babel/preset-env": "^7.24.8",
+ "@babel/preset-react": "^7.24.7",
+ "babel-loader": "^9.1.3",
+ "webpack": "^5.93.0",
+ "webpack-cli": "^5.1.4"
},
"dependencies": {
+ "@cloudflare/kv-asset-handler": "^0.3.4",
"buffer": "^6.0.3",
- "handlebars": "^4.7.8",
- "hbs-async-render": "^1.0.1",
"itty-router": "^2.6.6",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
"serverless-cloudflare-workers": "^1.2.0"
}
}
diff --git a/client/src/App.js b/client/src/App.js
new file mode 100644
index 0000000..6b7e81f
--- /dev/null
+++ b/client/src/App.js
@@ -0,0 +1,16 @@
+import React, { useState } from 'react';
+
+function App() {
+ const [count, setCount] = useState(0);
+
+ return (
+
+
Hello, Cloudflare Workers!
+
This is a basic React page deployed on Cloudflare Workers.
+
Count: {count}
+
+
+ );
+}
+
+export default App;
diff --git a/client/src/index.js b/client/src/index.js
index fda9fb6..735ecda 100644
--- a/client/src/index.js
+++ b/client/src/index.js
@@ -1,29 +1,56 @@
-import { Router } from 'itty-router'
-import { base64Handler, postHandler, rootHandler } from './routers'
-import { registerHBHelper } from './utils/hbsAsyncHelper.js'
-import '../assets/pages.js';
-import '../assets/partials.js';
+import { Router } from 'itty-router';
+import { getAssetFromKV } from '@cloudflare/kv-asset-handler';
-// Register HB
-registerHBHelper();
-
-// Create a new router
const router = Router();
-router.get("/", rootHandler);
-router.get("/base64/:text", base64Handler);
-router.post("/post", postHandler);
-/**
- * This is the last route we define, it will match anything that hasn't hit a route we've defined
- * above, therefore it's useful as a 404 (and avoids us hitting worker exceptions, so make sure
- * to include it!).
-*/
-router.all("*", () => new Response("404, not found!", { status: 404 }));
+// Serve the React app
+router.get('/', async () => {
+ // const html = ReactDOMServer.renderToString();
+ return new Response(`
+
+
+
+
+ React App on Cloudflare Workers
+
+
+
+
+
+
+
+
+ `, {
+ headers: {
+ 'Content-Type': 'text/html',
+ },
+ });
+});
-/**
- * This snippet ties our worker to the router we defined above, all incoming requests
- * are passed to the router where your routes are called and the response is sent.
-*/
-addEventListener('fetch', (e) => {
- e.respondWith(router.handle(e.request))
+// Respond to fetch events with the router
+addEventListener('fetch', event => {
+ // Pass the entire event object to handleAssetRequest function
+ event.respondWith(handleAssetRequest(event));
});
+
+async function handleAssetRequest(event) {
+ // Extract the request from the event
+ const request = event.request;
+
+ // Check if the request is for bundle.js
+ if (request.url.endsWith('/bundle.js') || request.url.endsWith('/favicon.ico')) {
+ // Serve the bundle.js file from KV storage
+ try {
+ // Pass the entire event object to getAssetFromKV
+ return await getAssetFromKV(event);
+ } catch (e) {
+ return new Response(`Bundle not found: ${e.message}`, {
+ status: 404,
+ statusText: 'Not Found',
+ });
+ }
+ }
+
+ // For any other requests, handle them with the router
+ return router.handle(request);
+}
diff --git a/client/src/main.js b/client/src/main.js
new file mode 100644
index 0000000..3ee9c5d
--- /dev/null
+++ b/client/src/main.js
@@ -0,0 +1,6 @@
+import App from './App';
+import { createRoot } from 'react-dom/client';
+
+// Render your React component instead
+const root = createRoot(document.getElementById('root'));
+root.render();
diff --git a/client/webpack.config.js b/client/webpack.config.js
new file mode 100644
index 0000000..1227552
--- /dev/null
+++ b/client/webpack.config.js
@@ -0,0 +1,24 @@
+const path = require('path');
+
+module.exports = {
+ mode: 'production',
+ entry: './src/main.js',
+ output: {
+ filename: 'bundle.js',
+ path: path.resolve(__dirname, 'dist'),
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: {
+ loader: 'babel-loader',
+ options: {
+ presets: ['@babel/preset-env', '@babel/preset-react'],
+ },
+ },
+ },
+ ],
+ },
+};
diff --git a/client/wrangler.toml b/client/wrangler.toml
index 52d77b7..f0d3b68 100644
--- a/client/wrangler.toml
+++ b/client/wrangler.toml
@@ -2,11 +2,14 @@ name = "tech"
account_id = "**********"
workers_dev = true
compatibility_date = "2024-07-11"
+main = "index.js"
+
+[site]
+bucket = "./dist"
+
+[build]
+command = "npm run build"
[route]
pattern = "**********"
custom_domain = true
-
-[build]
-command="npm run build"
-watch_dir="views/"
\ No newline at end of file