feat: Add dev website (#4)

## Description

**What(what issue does this code solve/what feature does it add):**

Add a qwik project where we can add API(s) and a frontend which will be
used to review and deploy to AWS our docker containers for testing.

**How(how does it solve it):**

1. Initialise a qwik project at `apps/www` 

## Required Checklist:

- [ ] I have added any necessary documentation and comments in my code
(where appropriate)
- [ ] I have added tests to make sure my code runs in all contexts

## Further comments
This commit is contained in:
Wanjohi
2024-03-29 22:54:17 +03:00
committed by GitHub
parent 41350edf3e
commit e68e1018c3
31 changed files with 10244 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
{
"name": "qwik-project-name",
"scripts": {
"build": "qwik build",
"build.client": "vite build",
"build.preview": "vite build --ssr src/entry.preview.tsx",
"build.types": "tsc --incremental --noEmit",
"dev": "vite --mode ssr",
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
"fmt": "prettier --write .",
"fmt.check": "prettier --check .",
"lint": "eslint \"src/**/*.ts*\"",
"preview": "qwik build preview && vite preview --open",
"start": "vite --open --mode ssr",
"deploy": "echo 'Run \"npm run qwik add\" to install a server adapter'",
"qwik": "qwik"
},
"devDependencies": {
"@builder.io/qwik": "^1.5.1",
"@builder.io/qwik-city": "^1.5.1",
"@types/eslint": "^8.56.5",
"@types/node": "^20.11.24",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"eslint": "^8.57.0",
"eslint-plugin-qwik": "^1.5.1",
"prettier": "^3.2.5",
"typescript": "5.3.3",
"undici": "*",
"vite": "^5.1.4",
"vite-tsconfig-paths": "^4.2.1"
},
"trustedDependencies": [
"sharp"
],
"trustedDependencies-annotation": "Needed for bun to allow running install scripts",
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0",
"npm": ">=10.0.0",
"pnpm": ">=8.0.0",
"yarn": ">=3.0.0"
},
"engines-annotation": "Mostly required by sharp which needs a Node-API v9 compatible runtime",
"private": true,
"type": "module"
}

38
apps/www/.eslintignore Normal file
View File

@@ -0,0 +1,38 @@
**/*.log
**/.DS_Store
*.
.vscode/settings.json
.history
.yarn
bazel-*
bazel-bin
bazel-out
bazel-qwik
bazel-testlogs
dist
dist-dev
lib
lib-types
etc
external
node_modules
temp
tsc-out
tsdoc-metadata.json
target
output
rollup.config.js
build
.cache
.vscode
.rollup.cache
dist
tsconfig.tsbuildinfo
vite.config.ts
*.spec.tsx
*.spec.ts
.netlify
pnpm-lock.yaml
package-lock.json
yarn.lock
server

42
apps/www/.eslintrc.cjs Normal file
View File

@@ -0,0 +1,42 @@
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:qwik/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
tsconfigRootDir: __dirname,
project: ["./tsconfig.json"],
ecmaVersion: 2021,
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
plugins: ["@typescript-eslint"],
rules: {
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-this-alias": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"prefer-spread": "off",
"no-case-declarations": "off",
"no-console": "off",
"@typescript-eslint/no-unused-vars": ["warn"],
"@typescript-eslint/consistent-type-imports": "warn",
"@typescript-eslint/no-unnecessary-condition": "warn",
},
};

44
apps/www/.gitignore vendored Normal file
View File

@@ -0,0 +1,44 @@
# Build
/dist
/lib
/lib-types
/server
# Development
node_modules
*.local
# Cache
.cache
.mf
.rollup.cache
tsconfig.tsbuildinfo
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Editor
.vscode/*
!.vscode/launch.json
!.vscode/*.code-snippets
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# Yarn
.yarn/*
!.yarn/releases
# Vercel
.vercel

37
apps/www/.prettierignore Normal file
View File

@@ -0,0 +1,37 @@
**/*.log
**/.DS_Store
*.
.vscode/settings.json
.history
.yarn
bazel-*
bazel-bin
bazel-out
bazel-qwik
bazel-testlogs
dist
dist-dev
lib
lib-types
etc
external
node_modules
temp
tsc-out
tsdoc-metadata.json
target
output
rollup.config.js
build
.cache
.vscode
.rollup.cache
tsconfig.tsbuildinfo
vite.config.ts
*.spec.tsx
*.spec.ts
.netlify
pnpm-lock.yaml
package-lock.json
yarn.lock
server

3
apps/www/.prettierrc.js Normal file
View File

@@ -0,0 +1,3 @@
export default {
plugins: ['prettier-plugin-tailwindcss'],
}

24
apps/www/.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,24 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Chrome",
"request": "launch",
"type": "chrome",
"url": "http://localhost:5173",
"webRoot": "${workspaceFolder}"
},
{
"type": "node",
"name": "dev.debug",
"request": "launch",
"skipFiles": ["<node_internals>/**"],
"cwd": "${workspaceFolder}",
"program": "${workspaceFolder}/node_modules/vite/bin/vite.js",
"args": ["--mode", "ssr", "--force"]
}
]
}

View File

@@ -0,0 +1,36 @@
{
"onRequest": {
"scope": "javascriptreact,typescriptreact",
"prefix": "qonRequest",
"description": "onRequest function for a route index",
"body": [
"export const onRequest: RequestHandler = (request) => {",
" $0",
"};",
],
},
"loader$": {
"scope": "javascriptreact,typescriptreact",
"prefix": "qloader$",
"description": "loader$()",
"body": ["export const $1 = routeLoader$(() => {", " $0", "});"],
},
"action$": {
"scope": "javascriptreact,typescriptreact",
"prefix": "qaction$",
"description": "action$()",
"body": ["export const $1 = routeAction$((data) => {", " $0", "});"],
},
"Full Page": {
"scope": "javascriptreact,typescriptreact",
"prefix": "qpage",
"description": "Simple page component",
"body": [
"import { component$ } from '@builder.io/qwik';",
"",
"export default component$(() => {",
" $0",
"});",
],
},
}

78
apps/www/.vscode/qwik.code-snippets vendored Normal file
View File

@@ -0,0 +1,78 @@
{
"Qwik component (simple)": {
"scope": "javascriptreact,typescriptreact",
"prefix": "qcomponent$",
"description": "Simple Qwik component",
"body": [
"export const ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}} = component$(() => {",
" return <${2:div}>$4</$2>",
"});",
],
},
"Qwik component (props)": {
"scope": "typescriptreact",
"prefix": "qcomponent$ + props",
"description": "Qwik component w/ props",
"body": [
"export interface ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}}Props {",
" $2",
"}",
"",
"export const $1 = component$<$1Props>((props) => {",
" const ${2:count} = useSignal(0);",
" return (",
" <${3:div} on${4:Click}$={(ev) => {$5}}>",
" $6",
" </${3}>",
" );",
"});",
],
},
"Qwik signal": {
"scope": "javascriptreact,typescriptreact",
"prefix": "quseSignal",
"description": "useSignal() declaration",
"body": ["const ${1:foo} = useSignal($2);", "$0"],
},
"Qwik store": {
"scope": "javascriptreact,typescriptreact",
"prefix": "quseStore",
"description": "useStore() declaration",
"body": ["const ${1:state} = useStore({", " $2", "});", "$0"],
},
"$ hook": {
"scope": "javascriptreact,typescriptreact",
"prefix": "q$",
"description": "$() function hook",
"body": ["$(() => {", " $0", "});", ""],
},
"useVisibleTask": {
"scope": "javascriptreact,typescriptreact",
"prefix": "quseVisibleTask",
"description": "useVisibleTask$() function hook",
"body": ["useVisibleTask$(({ track }) => {", " $0", "});", ""],
},
"useTask": {
"scope": "javascriptreact,typescriptreact",
"prefix": "quseTask$",
"description": "useTask$() function hook",
"body": [
"useTask$(({ track }) => {",
" track(() => $1);",
" $0",
"});",
"",
],
},
"useResource": {
"scope": "javascriptreact,typescriptreact",
"prefix": "quseResource$",
"description": "useResource$() declaration",
"body": [
"const $1 = useResource$(({ track, cleanup }) => {",
" $0",
"});",
"",
],
},
}

109
apps/www/README.md Normal file
View File

@@ -0,0 +1,109 @@
# Qwik City App ⚡️
- [Qwik Docs](https://qwik.builder.io/)
- [Discord](https://qwik.builder.io/chat)
- [Qwik GitHub](https://github.com/BuilderIO/qwik)
- [@QwikDev](https://twitter.com/QwikDev)
- [Vite](https://vitejs.dev/)
---
## Project Structure
This project is using Qwik with [QwikCity](https://qwik.builder.io/qwikcity/overview/). QwikCity is just an extra set of tools on top of Qwik to make it easier to build a full site, including directory-based routing, layouts, and more.
Inside your project, you'll see the following directory structure:
```
├── public/
│ └── ...
└── src/
├── components/
│ └── ...
└── routes/
└── ...
```
- `src/routes`: Provides the directory-based routing, which can include a hierarchy of `layout.tsx` layout files, and an `index.tsx` file as the page. Additionally, `index.ts` files are endpoints. Please see the [routing docs](https://qwik.builder.io/qwikcity/routing/overview/) for more info.
- `src/components`: Recommended directory for components.
- `public`: Any static assets, like images, can be placed in the public directory. Please see the [Vite public directory](https://vitejs.dev/guide/assets.html#the-public-directory) for more info.
## Add Integrations and deployment
Use the `pnpm qwik add` command to add additional integrations. Some examples of integrations includes: Cloudflare, Netlify or Express Server, and the [Static Site Generator (SSG)](https://qwik.builder.io/qwikcity/guides/static-site-generation/).
```shell
pnpm qwik add # or `pnpm qwik add`
```
## Development
Development mode uses [Vite's development server](https://vitejs.dev/). The `dev` command will server-side render (SSR) the output during development.
```shell
npm start # or `pnpm start`
```
> Note: during dev mode, Vite may request a significant number of `.js` files. This does not represent a Qwik production build.
## Preview
The preview command will create a production build of the client modules, a production build of `src/entry.preview.tsx`, and run a local server. The preview server is only for convenience to preview a production build locally and should not be used as a production server.
```shell
pnpm preview # or `pnpm preview`
```
## Production
The production build will generate client and server modules by running both client and server build commands. The build command will use Typescript to run a type check on the source code.
```shell
pnpm build # or `pnpm build`
```
## Vercel Edge
This starter site is configured to deploy to [Vercel Edge Functions](https://vercel.com/docs/concepts/functions/edge-functions), which means it will be rendered at an edge location near to your users.
## Installation
The adaptor will add a new `vite.config.ts` within the `adapters/` directory, and a new entry file will be created, such as:
```
└── adapters/
└── vercel-edge/
└── vite.config.ts
└── src/
└── entry.vercel-edge.tsx
```
Additionally, within the `package.json`, the `build.server` script will be updated with the Vercel Edge build.
## Production build
To build the application for production, use the `build` command, this command will automatically run `pnpm build.server` and `pnpm build.client`:
```shell
pnpm build
```
[Read the full guide here](https://github.com/BuilderIO/qwik/blob/main/starters/adapters/vercel-edge/README.md)
## Dev deploy
To deploy the application for development:
```shell
pnpm deploy
```
Notice that you might need a [Vercel account](https://docs.Vercel.com/get-started/) in order to complete this step!
## Production deploy
The project is ready to be deployed to Vercel. However, you will need to create a git repository and push the code to it.
You can [deploy your site to Vercel](https://vercel.com/docs/concepts/deployments/overview) either via a Git provider integration or through the Vercel CLI.

View File

@@ -0,0 +1,16 @@
import { vercelEdgeAdapter } from "@builder.io/qwik-city/adapters/vercel-edge/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.vercel-edge.tsx", "@qwik-city-plan"],
},
outDir: ".vercel/output/functions/_qwik-city.func",
},
plugins: [vercelEdgeAdapter()],
};
});

58
apps/www/package.json Normal file
View File

@@ -0,0 +1,58 @@
{
"name": "my-qwik-empty-starter",
"description": "App with Routing built-in ready to create your app",
"engines": {
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"engines-annotation": "Mostly required by sharp which needs a Node-API v9 compatible runtime",
"private": true,
"trustedDependencies": [
"sharp"
],
"trustedDependencies-annotation": "Needed for bun to allow running install scripts",
"type": "module",
"scripts": {
"build": "qwik build",
"build.client": "vite build",
"build.preview": "vite build --ssr src/entry.preview.tsx",
"build.server": "vite build -c adapters/vercel-edge/vite.config.ts",
"build.types": "tsc --incremental --noEmit",
"deploy": "vercel deploy",
"dev": "vite --mode ssr",
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
"fmt": "prettier --write .",
"fmt.check": "prettier --check .",
"lint": "eslint \"src/**/*.ts*\"",
"preview": "qwik build preview && vite preview --open",
"start": "vite --open --mode ssr",
"qwik": "qwik"
},
"devDependencies": {
"@builder.io/qwik": "^1.5.1",
"@builder.io/qwik-city": "^1.5.1",
"@builder.io/qwik-react": "0.5.0",
"@types/eslint": "^8.56.5",
"@types/node": "^20.11.24",
"@types/react": "^18.2.28",
"@types/react-dom": "^18.2.13",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"autoprefixer": "^10.4.14",
"eslint": "^8.57.0",
"eslint-plugin-qwik": "^1.5.1",
"postcss": "^8.4.31",
"prettier": "^3.2.5",
"prettier-plugin-tailwindcss": "^0.5.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.3",
"typescript": "5.3.3",
"undici": "*",
"vercel": "^29.1.1",
"vite": "^5.1.4",
"vite-tsconfig-paths": "^4.2.1"
},
"dependencies": {
"@fontsource/geist-sans": "^5.0.2"
}
}

9347
apps/www/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

BIN
apps/www/public/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
"name": "qwik-project-name",
"short_name": "Welcome to Qwik",
"start_url": ".",
"display": "standalone",
"background_color": "#fff",
"description": "A Qwik project app."
}

View File

View File

@@ -0,0 +1,32 @@
import { component$ } from "@builder.io/qwik";
import { useDocumentHead, useLocation } from "@builder.io/qwik-city";
/**
* The RouterHead component is placed inside of the document `<head>` element.
*/
export const RouterHead = component$(() => {
const head = useDocumentHead();
const loc = useLocation();
return (
<>
<title>{head.title}</title>
<link rel="canonical" href={loc.url.href} />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/png" href="/favicon.png" />
{head.meta.map((m) => (
<meta key={m.key} {...m} />
))}
{head.links.map((l) => (
<link key={l.key} {...l} />
))}
{head.styles.map((s) => (
<style key={s.key} {...s.props} dangerouslySetInnerHTML={s.style} />
))}
</>
);
});

View File

@@ -0,0 +1,17 @@
/*
* WHAT IS THIS FILE?
*
* Development entry point using only client-side modules:
* - Do not use this mode in production!
* - No SSR
* - No portion of the application is pre-rendered on the server.
* - All of the application is running eagerly in the browser.
* - More code is transferred to the browser than in SSR mode.
* - Optimizer/Serialization/Deserialization code is not exercised!
*/
import { render, type RenderOptions } from "@builder.io/qwik";
import Root from "./root";
export default function (opts: RenderOptions) {
return render(document, <Root />, opts);
}

View File

@@ -0,0 +1,20 @@
/*
* WHAT IS THIS FILE?
*
* It's the bundle entry point for `npm run preview`.
* That is, serving your app built in production mode.
*
* Feel free to modify this file, but don't remove it!
*
* Learn more about Vite's preview command:
* - https://vitejs.dev/config/preview-options.html#preview-options
*
*/
import { createQwikCity } from "@builder.io/qwik-city/middleware/node";
import qwikCityPlan from "@qwik-city-plan";
import render from "./entry.ssr";
/**
* The default export is the QwikCity adapter used by Vite preview.
*/
export default createQwikCity({ render, qwikCityPlan });

View File

@@ -0,0 +1,30 @@
/**
* WHAT IS THIS FILE?
*
* SSR entry point, in all cases the application is rendered outside the browser, this
* entry point will be the common one.
*
* - Server (express, cloudflare...)
* - npm run start
* - npm run preview
* - npm run build
*
*/
import {
renderToStream,
type RenderToStreamOptions,
} from "@builder.io/qwik/server";
import { manifest } from "@qwik-client-manifest";
import Root from "./root";
export default function (opts: RenderToStreamOptions) {
return renderToStream(<Root />, {
manifest,
...opts,
// Use container attributes to set attributes on the html tag.
containerAttributes: {
lang: "en-us",
...opts.containerAttributes,
},
});
}

View File

@@ -0,0 +1,22 @@
/*
* WHAT IS THIS FILE?
*
* It's the entry point for Vercel Edge when building for production.
*
* Learn more about the Vercel Edge integration here:
* - https://qwik.builder.io/docs/deployments/vercel-edge/
*
*/
import {
createQwikCity,
type PlatformVercel,
} from "@builder.io/qwik-city/middleware/vercel-edge";
import qwikCityPlan from "@qwik-city-plan";
import { manifest } from "@qwik-client-manifest";
import render from "./entry.ssr";
declare global {
interface QwikCityPlatform extends PlatformVercel {}
}
export default createQwikCity({ render, qwikCityPlan, manifest });

15
apps/www/src/global.css Normal file
View File

@@ -0,0 +1,15 @@
/**
* Tailwind CSS imports
* View the full documentation at https://tailwindcss.com
*/
@tailwind base;
@tailwind components;
@tailwind utilities;
html *,
html *::after,
html *::before {
box-sizing: border-box;
margin: 0;
padding: 0;
}

33
apps/www/src/root.tsx Normal file
View File

@@ -0,0 +1,33 @@
import { component$ } from "@builder.io/qwik";
import {
QwikCityProvider,
RouterOutlet,
ServiceWorkerRegister,
} from "@builder.io/qwik-city";
import { RouterHead } from "./components/router-head/router-head";
import "./global.css";
import "@fontsource/geist-sans/400.css";
export default component$(() => {
/**
* The root of a QwikCity site always start with the <QwikCityProvider> component,
* immediately followed by the document's <head> and <body>.
*
* Don't remove the `<head>` and `<body>` elements.
*/
return (
<QwikCityProvider>
<head>
<meta charSet="utf-8" />
<link rel="manifest" href="/manifest.json" />
<RouterHead />
</head>
<body lang="en" class="min-h-screen font-sans antialiased">
<RouterOutlet />
<ServiceWorkerRegister />
</body>
</QwikCityProvider>
);
});

View File

@@ -0,0 +1,14 @@
import { component$ } from "@builder.io/qwik";
export default component$(() => {
return (
<div class='justify-center items-center w-screen h-screen flex flex-col gap-3' >
<h1 class='text-3xl' >Hi 👋</h1>
<p class='text-xl' >
Can't wait to see what you build with qwik!
<br />
Happy coding.
</p>
</div>
);
});

View File

@@ -0,0 +1,29 @@
import { component$, Slot } from "@builder.io/qwik";
import type { RequestHandler } from "@builder.io/qwik-city";
import type { DocumentHead } from "@builder.io/qwik-city";
export const onGet: RequestHandler = async ({ cacheControl }) => {
// Control caching for this request for best performance and to reduce hosting costs:
// https://qwik.builder.io/docs/caching/
cacheControl({
// Always serve a cached response by default, up to a week stale
staleWhileRevalidate: 60 * 60 * 24 * 7,
// Max once every 5 seconds, revalidate on the server to get a fresh version of this page
maxAge: 5,
});
};
export default component$(() => {
return <Slot />;
});
export const head: DocumentHead = {
title: "netris.me/dev | Build the future of gaming",
meta: [
{
name: "description",
content: "Play with your friends right from your browser",
},
],
};

View File

@@ -0,0 +1,18 @@
/*
* WHAT IS THIS FILE?
*
* The service-worker.ts file is used to have state of the art prefetching.
* https://qwik.builder.io/qwikcity/prefetching/overview/
*
* Qwik uses a service worker to speed up your site and reduce latency, ie, not used in the traditional way of offline.
* You can also use this file to add more functionality that runs in the service worker.
*/
import { setupServiceWorker } from "@builder.io/qwik-city/service-worker";
setupServiceWorker();
addEventListener("install", () => self.skipWaiting());
addEventListener("activate", () => self.clients.claim());
declare const self: ServiceWorkerGlobalScope;

View File

@@ -0,0 +1,26 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
theme: {
extend: {
fontFamily: {
sans: [
"Geist Sans",
"ui-sans-serif",
"system-ui",
"-apple-system",
"BlinkMacSystemFont",
"Inter",
"Segoe UI",
"Roboto",
"sans-serif",
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji",
],
},
},
},
plugins: [],
};

26
apps/www/tsconfig.json Normal file
View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"allowJs": true,
"target": "ES2017",
"module": "ES2022",
"lib": ["es2022", "DOM", "WebWorker", "DOM.Iterable"],
"jsx": "react-jsx",
"jsxImportSource": "@builder.io/qwik",
"strict": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"incremental": true,
"isolatedModules": true,
"outDir": "tmp",
"noEmit": true,
"types": ["node", "vite/client"],
"paths": {
"~/*": ["./src/*"]
}
},
"files": ["./.eslintrc.cjs"],
"include": ["src", "./*.d.ts", "./*.config.ts"]
}

13
apps/www/vercel.json Normal file
View File

@@ -0,0 +1,13 @@
{
"headers": [
{
"source": "/build/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, s-maxage=31536000, immutable"
}
]
}
]
}

56
apps/www/vite.config.ts Normal file
View File

@@ -0,0 +1,56 @@
/**
* This is the base config for vite.
* When building, the adapter config is used which loads this file and extends it.
*/
import { defineConfig, type UserConfig } from "vite";
import { qwikVite } from "@builder.io/qwik/optimizer";
import { qwikCity } from "@builder.io/qwik-city/vite";
import tsconfigPaths from "vite-tsconfig-paths";
import pkg from "./package.json";
import { qwikReact } from "@builder.io/qwik-react/vite";
const { dependencies = {}, devDependencies = {} } = pkg as any as {
dependencies: Record<string, string>;
devDependencies: Record<string, string>;
[key: string]: unknown;
};
/**
* Note that Vite normally starts from `index.html` but the qwikCity plugin makes start at `src/entry.ssr.tsx` instead.
*/
export default defineConfig(({ command, mode }): UserConfig => {
return {
plugins: [qwikCity(), qwikVite(), tsconfigPaths(), qwikReact()],
// This tells Vite which dependencies to pre-build in dev mode.
optimizeDeps: {
// Put problematic deps that break bundling here, mostly those with binaries.
// For example ['better-sqlite3'] if you use that in server functions.
exclude: [],
},
// This tells Vite how to bundle the server code.
ssr:
command === "build" && mode === "production"
? {
// All dev dependencies should be bundled in the server build
noExternal: Object.keys(devDependencies),
// Anything marked as a dependency will not be bundled
// These should only be production binary deps (including deps of deps), CLI deps, and their module graph
// If a dep-of-dep needs to be external, add it here
// For example, if something uses `bcrypt` but you don't have it as a dep, you can write
// external: [...Object.keys(dependencies), 'bcrypt']
external: Object.keys(dependencies),
}
: undefined,
server: {
headers: {
// Don't cache the server response in dev mode
"Cache-Control": "public, max-age=0",
},
},
preview: {
headers: {
// Do cache the server response in preview (non-adapter production build)
"Cache-Control": "public, max-age=600",
},
},
};
});