Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ pnpm-lock.yaml
package-lock.json
yarn.lock
server
src/entry.deno.tsx
44 changes: 44 additions & 0 deletions .github/workflows/deploy-to-deno.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Deploy to Azure Static Web Apps

on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened, closed]
branches:
- main

permissions:
id-token: write # Needed for auth with Deno Deploy
contents: read

jobs:
publish:
runs-on: ubuntu-latest
name: Build and Deploy to Deno Deploy
steps:
- name: Checkout
uses: actions/checkout@v3

- uses: pnpm/[email protected]

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
cache: "pnpm"
registry-url: https://registry.npmjs.org/

- name: Install NPM Dependencies
run: pnpm install --frozen-lockfile

- name: Build
run: pnpm run build.deno

- name: Upload to Deno Deploy
uses: denoland/deployctl@v1
with:
project: "qwik-todos"
root: "server"
entrypoint: "entry.deno.js"
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ There are three backends available:

The app is deployed to Azure and Cloudflare:

- Azure Static Web Apps with Azure Tables: https://qwik-todos-azure.meeow.xyz/
- Cloudflare Pages with Cloudflare D1: https://qwik-todos-cloudflare.meeow.xyz/
- Azure Static Web Apps with Azure Tables: https://ashy-coast-09da7ba03.2.azurestaticapps.net/
- Cloudflare Pages with Cloudflare D1: https://qwik-todos.pages.dev/
- Deno Deploy: https://qwik-todos.deno.dev/

There are also different versions for comparison:
There are also versions built with other technologies for comparison:

- [htmx](https://htmx.org/) with [Quarkus](https://quarkus.dev) backend: https://github.com/derkoe/quarkus-hotwire-todos
- [htmx](https://htmx.org/) with [Quarkus](https://quarkus.dev) backend: https://github.com/derkoe/quarkus-htmx-todos
- [Hotwire](https://hotwire.dev/) with [Quarkus](https://quarkus.dev) backend: https://github.com/derkoe/quarkus-hotwire-todos
- [Remix](https://remix.run/): https://github.com/derkoe/remix-todos
- [Phonix](https://www.phoenixframework.org/) with LiveView: https://github.com/derkoe/phoenix-todos
18 changes: 18 additions & 0 deletions adapters/deno/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { denoServerAdapter } from '@builder.io/qwik-city/adapters/deno-server/vite';
import { extendConfig } from '@builder.io/qwik-city/vite';
import baseConfig from '../../vite.config';

export default extendConfig(baseConfig, () => {
return {
build: {
ssr: true,
rollupOptions: {
input: ['src/entry.deno.tsx', '@qwik-city-plan'],
},
minify: false,
},
plugins: [
denoServerAdapter(),
],
};
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
"build": "echo 'Run build.azure or build.cloudflare' && false",
"build.azure": "npm-run-all build.client build.server.azure --parallel lint fmt.check build.types",
"build.cloudflare": "npm-run-all build.client build.server.cloudflare --parallel lint fmt.check build.types",
"build.deno": "npm-run-all build.client build.server.deno --parallel lint fmt.check build.types",
"build.client": "vite build",
"build.preview": "vite build --ssr src/entry.preview.tsx",
"build.server.azure": "vite build -c adapters/azure-swa/vite.config.ts",
"build.server.cloudflare": "vite build -c adapters/cloudflare-pages/vite.config.ts",
"build.server.deno": "vite build -c adapters/deno/vite.config.ts",
"build.types": "tsc --incremental --noEmit",
"dev": "vite --mode ssr",
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
Expand All @@ -22,6 +24,7 @@
"preview": "qwik build preview && vite preview --open",
"serve.azure": "swa start",
"serve.cloudflare": "wrangler pages dev ./dist --persist",
"serve.deno": "deno run --allow-net --allow-read --allow-env server/entry.deno.js",
"start": "vite --open --mode ssr",
"qwik": "qwik"
},
Expand Down
63 changes: 63 additions & 0 deletions src/entry.deno.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* WHAT IS THIS FILE?
*
* It's the entry point for the Deno HTTP server when building for production.
*
* Learn more about the Deno integration here:
* - https://qwik.builder.io/docs/deployments/deno/
* - https://deno.com/manual/examples/http_server
*
*/
import { createQwikCity } from "@builder.io/qwik-city/middleware/deno";
import qwikCityPlan from "@qwik-city-plan";
import { manifest } from "@qwik-client-manifest";
import render from "./entry.ssr";

// Create the Qwik City Deno middleware
const { router, notFound, staticFile } = createQwikCity({
render,
qwikCityPlan,
manifest,
});

// Allow for dynamic port
const port = Number(Deno.env.get("PORT") ?? 8080);

// Start the Deno server
const server = Deno.listen({ port });

/* eslint-disable */
console.log(`Server started: http://localhost:${port}/`);

// https://deno.com/manual/examples/http_server
// Connections to the server will be yielded up as an async iterable.
for await (const conn of server) {
serveHttp(conn);
}

async function serveHttp(conn: any) {
const httpConn = Deno.serveHttp(conn);

// Each request sent over the HTTP connection will be yielded as an
// async iterator from the HTTP connection.
for await (const requestEvent of httpConn) {
const staticResponse = await staticFile(requestEvent.request);
if (staticResponse) {
// Serve static file
requestEvent.respondWith(staticResponse);
continue;
}

// Server-side render this request with Qwik City
const qwikCityResponse = await router(requestEvent.request);
if (qwikCityResponse) {
requestEvent.respondWith(qwikCityResponse);
continue;
}

// Path not found
requestEvent.respondWith(notFound(requestEvent.request));
}
}

declare const Deno: any;
7 changes: 5 additions & 2 deletions src/model/todo-service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { createTodoService as createD1TodoService } from "./todo-service-d1";
import { mockTodoService } from "./todo-service-mock";

declare interface EnvGetter {
get(key: string): string | undefined;
}

export async function getTodoService(env: EnvGetter) {
const todoDatabase: D1Database | undefined = env.get("TODO_DB") as any;
if (todoDatabase && typeof todoDatabase.prepare === "function") {
return (await import("./todo-service-d1")).createTodoService(todoDatabase);
return createD1TodoService(todoDatabase);
} else if (
env.get("STORAGE_ACCOUNT_NAME") &&
env.get("STORAGE_ACCOUNT_KEY")
Expand All @@ -17,6 +20,6 @@ export async function getTodoService(env: EnvGetter) {
storageAccountKey
);
} else {
return (await import("./todo-service-mock")).mockTodoService;
return mockTodoService;
}
}
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
}
},
"files": ["./.eslintrc.cjs"],
"include": ["src"]
"include": ["src"],
"exclude": ["src/entry.deno.tsx"]
}