commit 6c6a88931cb52955e03e7318aa8776f13f3f3e62 Author: juyoungk09 Date: Fri Jul 25 06:56:27 2025 +0900 Initial commit ⚡️ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4183fdf --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Build +/dist +/lib +/lib-types +/server + +# Development +node_modules +.env +*.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 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..b62a968 --- /dev/null +++ b/.prettierignore @@ -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 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e684cc8 --- /dev/null +++ b/.vscode/launch.json @@ -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": ["/**"], + "cwd": "${workspaceFolder}", + "program": "${workspaceFolder}/node_modules/vite/bin/vite.js", + "args": ["--mode", "ssr", "--force"] + } + ] +} diff --git a/.vscode/qwik-city.code-snippets b/.vscode/qwik-city.code-snippets new file mode 100644 index 0000000..878fcf6 --- /dev/null +++ b/.vscode/qwik-city.code-snippets @@ -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", + "});", + ], + }, +} diff --git a/.vscode/qwik.code-snippets b/.vscode/qwik.code-snippets new file mode 100644 index 0000000..62edc82 --- /dev/null +++ b/.vscode/qwik.code-snippets @@ -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", + "});", + ], + }, + "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", + " ", + " );", + "});", + ], + }, + "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", + "});", + "", + ], + }, +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..bc53f27 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# Qwik City App ⚡️ + +- [Qwik Docs](https://qwik.dev/) +- [Discord](https://qwik.dev/chat) +- [Qwik GitHub](https://github.com/QwikDev/qwik) +- [@QwikDev](https://twitter.com/QwikDev) +- [Vite](https://vitejs.dev/) + +--- + +## Project Structure + +This project is using Qwik with [QwikCity](https://qwik.dev/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.dev/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 `npm run 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.dev/qwikcity/guides/static-site-generation/). + +```shell +npm run qwik add # or `yarn 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 `yarn 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 +npm run preview # or `yarn 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 +npm run build # or `yarn build` +``` diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..bcfd091 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,73 @@ +import js from "@eslint/js"; +import globals from "globals"; +import tseslint from "typescript-eslint"; +import { globalIgnores } from "eslint/config"; +import { qwikEslint9Plugin } from "eslint-plugin-qwik"; + +const ignores = [ + "**/*.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", + "eslint.config.js", +]; + +export default tseslint.config( + globalIgnores(ignores), + js.configs.recommended, + tseslint.configs.recommended, + qwikEslint9Plugin.configs.recommended, + { + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + ...globals.es2021, + ...globals.serviceworker, + }, + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + rules: { + "@typescript-eslint/no-explicit-any": "off", + }, + }, +); diff --git a/package.json b/package.json new file mode 100644 index 0000000..8bb4d9e --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "my-qwik-empty-starter", + "description": "Blank project with routing included", + "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, + "type": "module", + "scripts": { + "build": "qwik build", + "build.client": "vite build", + "build.preview": "vite build --ssr src/entry.preview.tsx", + "build.types": "tsc --incremental --noEmit", + "deploy": "echo 'Run \"npm run qwik add\" to install a server adapter'", + "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.15.0", + "@builder.io/qwik-city": "^1.15.0", + "@eslint/js": "latest", + "@types/node": "20.14.11", + "eslint": "9.25.1", + "eslint-plugin-qwik": "^1.15.0", + "globals": "16.0.0", + "prettier": "3.3.3", + "typescript": "5.4.5", + "typescript-eslint": "8.26.1", + "typescript-plugin-css-modules": "latest", + "undici": "*", + "vite": "5.3.5", + "vite-tsconfig-paths": "^4.2.1" + } +} diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..0ded7c1 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..c18e75f --- /dev/null +++ b/public/manifest.json @@ -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." +} diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e69de29 diff --git a/qwik.env.d.ts b/qwik.env.d.ts new file mode 100644 index 0000000..25af92b --- /dev/null +++ b/qwik.env.d.ts @@ -0,0 +1,4 @@ +// This file can be used to add references for global types like `vite/client`. + +// Add global `vite/client` types. For more info, see: https://vitejs.dev/guide/features#client-types +/// diff --git a/src/components/router-head/router-head.tsx b/src/components/router-head/router-head.tsx new file mode 100644 index 0000000..da5b68f --- /dev/null +++ b/src/components/router-head/router-head.tsx @@ -0,0 +1,48 @@ +import { component$ } from "@builder.io/qwik"; +import { useDocumentHead, useLocation } from "@builder.io/qwik-city"; + +/** + * The RouterHead component is placed inside of the document `` element. + */ +export const RouterHead = component$(() => { + const head = useDocumentHead(); + const loc = useLocation(); + + return ( + <> + {head.title} + + + + + + {head.meta.map((m) => ( + + ))} + + {head.links.map((l) => ( + + ))} + + {head.styles.map((s) => ( +