From 05429fc3bc375093dd48cb22df706cf74e69378f Mon Sep 17 00:00:00 2001 From: jeff Date: Sat, 12 Oct 2024 14:46:41 +0800 Subject: [PATCH] feat: init --- .browserslistrc | 4 + .editorconfig | 14 +++ .env | 1 + .env.client | 1 + .eslintignore | 11 +++ .eslintrc.js | 120 +++++++++++++++++++++++ .gitignore | 34 +++++++ .prettierrc.json | 8 ++ .stylelintignore | 4 + README.md | 49 ++++++++++ app/server.ts | 30 ++++++ app/user/api.md | 0 app/user/api.ts | 25 +++++ app/user/db.ts | 55 +++++++++++ app/user/user.ts | 17 ++++ env.d.ts | 1 + eslint.config.js | 171 +++++++++++++++++++++++++++++++++ index.html | 13 +++ package.json | 57 +++++++++++ public/favicon.ico | Bin 0 -> 4286 bytes schema.sql | 16 +++ src/App.vue | 9 ++ src/assets/base.css | 86 +++++++++++++++++ src/assets/logo.svg | 1 + src/assets/main.css | 35 +++++++ src/main.ts | 14 +++ src/router/index.ts | 15 +++ src/views/helloworld/index.vue | 18 ++++ tsconfig.app.json | 15 +++ tsconfig.json | 23 +++++ tsconfig.node.json | 19 ++++ vite.config.d.ts | 2 + vite.config.ts | 51 ++++++++++ wrangler.toml | 3 + 34 files changed, 922 insertions(+) create mode 100644 .browserslistrc create mode 100644 .editorconfig create mode 100644 .env create mode 100644 .env.client create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitignore create mode 100644 .prettierrc.json create mode 100644 .stylelintignore create mode 100644 README.md create mode 100644 app/server.ts create mode 100644 app/user/api.md create mode 100644 app/user/api.ts create mode 100644 app/user/db.ts create mode 100644 app/user/user.ts create mode 100644 env.d.ts create mode 100644 eslint.config.js create mode 100644 index.html create mode 100644 package.json create mode 100644 public/favicon.ico create mode 100644 schema.sql create mode 100644 src/App.vue create mode 100644 src/assets/base.css create mode 100644 src/assets/logo.svg create mode 100644 src/assets/main.css create mode 100644 src/main.ts create mode 100644 src/router/index.ts create mode 100644 src/views/helloworld/index.vue create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.d.ts create mode 100644 vite.config.ts create mode 100644 wrangler.toml diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..40bd99c --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,4 @@ +> 1% +last 2 versions +not dead +not ie 11 \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..ea6e20f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/.env b/.env new file mode 100644 index 0000000..8bc9092 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +VITE_DOMAIN = http://192.168.3.17:3000/ diff --git a/.env.client b/.env.client new file mode 100644 index 0000000..8bc9092 --- /dev/null +++ b/.env.client @@ -0,0 +1 @@ +VITE_DOMAIN = http://192.168.3.17:3000/ diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..b84beaf --- /dev/null +++ b/.eslintignore @@ -0,0 +1,11 @@ +public +dist +*.d.ts +/src/assets +package.json +eslint.config.js +.prettierrc.js +commitlint.config.js +postcss.config.js +tailwind.config.js +stylelint.config.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..009f5bc --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,120 @@ +module.exports = { + root: true, + env: { + node: true + }, + globals: { + // Ref sugar (take 2) + $: "readonly", + $$: "readonly", + $ref: "readonly", + $shallowRef: "readonly", + $computed: "readonly", + + // index.d.ts + // global.d.ts + Fn: "readonly", + PromiseFn: "readonly", + RefType: "readonly", + LabelValueOptions: "readonly", + EmitType: "readonly", + TargetContext: "readonly", + ComponentElRef: "readonly", + ComponentRef: "readonly", + ElRef: "readonly", + global: "readonly", + ForDataType: "readonly", + ComponentRoutes: "readonly", + + // script setup + defineProps: "readonly", + defineEmits: "readonly", + defineExpose: "readonly", + withDefaults: "readonly" + }, + extends: [ + "plugin:vue/vue3-essential", + "eslint:recommended", + "@vue/typescript/recommended", + "@vue/prettier", + "@vue/eslint-config-typescript" + ], + parser: "vue-eslint-parser", + parserOptions: { + parser: "@typescript-eslint/parser", + ecmaVersion: 2020, + sourceType: "module", + jsxPragma: "React", + ecmaFeatures: { + jsx: true + } + }, + overrides: [ + { + files: ["*.ts", "*.vue"], + rules: { + "no-undef": "off" + } + }, + { + files: ["*.vue"], + parser: "vue-eslint-parser", + parserOptions: { + parser: "@typescript-eslint/parser", + extraFileExtensions: [".vue"], + ecmaVersion: "latest", + ecmaFeatures: { + jsx: true + } + }, + rules: { + "no-undef": "off" + } + } + ], + rules: { + "vue/no-v-html": "off", + "vue/require-default-prop": "off", + "vue/require-explicit-emits": "off", + "vue/multi-word-component-names": "off", + "@typescript-eslint/no-explicit-any": "off", // any + "no-debugger": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", // setup() + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "vue/html-self-closing": [ + "error", + { + html: { + void: "always", + normal: "always", + component: "always" + }, + svg: "always", + math: "always" + } + ], + "@typescript-eslint/no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_" + } + ], + "no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_" + } + ], + "prettier/prettier": [ + "error", + { + endOfLine: "auto" + } + ] + } +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..47badfb --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo + +# wrangler files +.wrangler +.dev.vars diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..ee7d693 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://json.schemastore.org/prettierrc", + "semi": true, + "tabWidth": 2, + "singleQuote": false, + "printWidth": 100, + "trailingComma": "none" +} diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 0000000..0c34e61 --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,4 @@ +/dist/* +/public/* +public/* +src/style/reset.scss \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..215c167 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# cloudflare-pages-demo + +## Project Setup + +```sh +npm install +``` + +### Compile and Hot-Reload for Development + +```sh +npm run dev +``` + +### Run/Debug on Webstorm + +Set Run/Debug Configuration -> npm -> Command: run, Scripts: dev + +### Type-Check, Compile and Minify for Production + +```sh +npm run build +``` + +### Lint with [ESLint](https://eslint.org/) + +```sh +npm run lint +``` + +### Preview on Local Host + +```sh +npm run preview +``` + +### Deploy + +```sh +npm run deploy +``` + +## D1 + +### 查看数据库表 + +```sql +SELECT name FROM sqlite_master WHERE type='table'; +``` diff --git a/app/server.ts b/app/server.ts new file mode 100644 index 0000000..6d3d87e --- /dev/null +++ b/app/server.ts @@ -0,0 +1,30 @@ +// app/server.ts +import { Hono } from "hono"; +import { cors } from "hono/cors"; +import userRouters from "./user/api"; + +interface Env { + ASSETS: { + fetch: (request: Request) => Promise; + }; +} + +const app = new Hono(); +app.use("/*", cors()); + +/* +API +*/ +app.route("/api/user", userRouters); + +app.get("/api/hello-world", async (c) => { + return c.text("Hello World!"); +}); + +// 处理所有其他请求,返回 Vue 的打包好的静态资源 +app.get("/*", async (c) => { + const env = c.env as Env; + return env.ASSETS.fetch(c.req.raw); +}); + +export default app; diff --git a/app/user/api.md b/app/user/api.md new file mode 100644 index 0000000..e69de29 diff --git a/app/user/api.ts b/app/user/api.ts new file mode 100644 index 0000000..6b7172c --- /dev/null +++ b/app/user/api.ts @@ -0,0 +1,25 @@ +// api.ts +import { Hono } from "hono"; +import { saveUser, getUserById } from "./db"; +import type User from "./user"; +import type { D1Database } from "@cloudflare/workers-types"; + +const api = new Hono<{ Bindings: { DB: D1Database } }>(); + +api.post("/save", async (c) => { + const user: User = await c.req.json(); + await saveUser(c.env.DB, user); + return c.json({ success: true }); +}); + +api.get("/detail", async (c) => { + const id = parseInt(c.req.query("id") as string, 10); + const user = await getUserById(c.env.DB, id); + if (user) { + return c.json(user); + } else { + return c.json({ error: "User not found" }, 404); + } +}); + +export default api; diff --git a/app/user/db.ts b/app/user/db.ts new file mode 100644 index 0000000..29768ef --- /dev/null +++ b/app/user/db.ts @@ -0,0 +1,55 @@ +// db.ts +import type { D1Database } from "@cloudflare/workers-types"; +import type User from "./user"; + +export async function initializeUsersTable(DB: D1Database): Promise { + const query = ` + CREATE TABLE IF NOT EXISTS users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + resolution VARCHAR(50), + local_language VARCHAR(10), + m1 VARCHAR(255), + oaid VARCHAR(255), + channel VARCHAR(50), + app_version VARCHAR(20), + app_name VARCHAR(100), + pkg_name VARCHAR(100), + device_id VARCHAR(100), + platform VARCHAR(20), + os_version VARCHAR(20), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + `; + await DB.prepare(query).run(); +} + +export async function saveUser(DB: D1Database, user: User): Promise { + await initializeUsersTable(DB); // Ensure the table exists + const query = ` + INSERT INTO users ( + resolution, local_language, m1, oaid, channel, app_version, app_name, pkg_name, device_id, platform, os_version + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `; + const values = [ + user.resolution, + user.local_language, + user.m1, + user.oaid, + user.channel, + user.app_version, + user.app_name, + user.pkg_name, + user.device_id, + user.platform, + user.os_version + ]; + await DB.prepare(query) + .bind(...values) + .run(); +} + +export async function getUserById(DB: D1Database, id: number): Promise { + const query = `SELECT * FROM users WHERE id = ?`; + const result = await DB.prepare(query).bind(id).first(); + return result || null; +} diff --git a/app/user/user.ts b/app/user/user.ts new file mode 100644 index 0000000..bf041f7 --- /dev/null +++ b/app/user/user.ts @@ -0,0 +1,17 @@ +// user.ts + +export default interface User { + id: number; + resolution: string; + local_language: string; + m1: string; + oaid: string; + channel: string; + app_version: string; + app_name: string; + pkg_name: string; + device_id: string; + platform: string; + os_version: string; + created_at: Date; +} diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..8803bcf --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,171 @@ +import js from "@eslint/js"; +import pluginVue from "eslint-plugin-vue"; +import * as parserVue from "vue-eslint-parser"; +import configPrettier from "eslint-config-prettier"; +import pluginPrettier from "eslint-plugin-prettier"; +import { defineFlatConfig } from "eslint-define-config"; +import * as parserTypeScript from "@typescript-eslint/parser"; +import pluginTypeScript from "@typescript-eslint/eslint-plugin"; + +export default defineFlatConfig([ + { + ...js.configs.recommended, + ignores: ["src/assets/**", "src/**/iconfont/**"], + languageOptions: { + globals: { + // index.d.ts + RefType: "readonly", + EmitType: "readonly", + TargetContext: "readonly", + ComponentRef: "readonly", + ElRef: "readonly", + ForDataType: "readonly", + AnyFunction: "readonly", + PropType: "readonly", + Writable: "readonly", + Nullable: "readonly", + NonNullable: "readonly", + Recordable: "readonly", + ReadonlyRecordable: "readonly", + Indexable: "readonly", + DeepPartial: "readonly", + Without: "readonly", + Exclusive: "readonly", + TimeoutHandle: "readonly", + IntervalHandle: "readonly", + Effect: "readonly", + ChangeEvent: "readonly", + WheelEvent: "readonly", + ImportMetaEnv: "readonly", + Fn: "readonly", + PromiseFn: "readonly", + ComponentElRef: "readonly", + parseInt: "readonly", + parseFloat: "readonly" + } + }, + plugins: { + prettier: pluginPrettier + }, + rules: { + ...configPrettier.rules, + ...pluginPrettier.configs.recommended.rules, + "no-debugger": "off", + "no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_" + } + ], + "prettier/prettier": [ + "error", + { + endOfLine: "auto" + } + ] + } + }, + { + files: ["**/*.?([cm])ts", "**/*.?([cm])tsx"], + languageOptions: { + parser: parserTypeScript, + parserOptions: { + sourceType: "module" + } + }, + plugins: { + "@typescript-eslint": pluginTypeScript + }, + rules: { + ...pluginTypeScript.configs.strict.rules, + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-redeclare": "error", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/prefer-as-const": "warn", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-import-type-side-effects": "error", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/consistent-type-imports": [ + "error", + { disallowTypeAnnotations: false, fixStyle: "inline-type-imports" } + ], + "@typescript-eslint/prefer-literal-enum-member": ["error", { allowBitwiseExpressions: true }], + "@typescript-eslint/no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_" + } + ] + } + }, + { + files: ["**/*.d.ts"], + rules: { + "eslint-comments/no-unlimited-disable": "off", + "import/no-duplicates": "off", + "unused-imports/no-unused-vars": "off" + } + }, + { + files: ["**/*.?([cm])js"], + rules: { + "@typescript-eslint/no-require-imports": "off", + "@typescript-eslint/no-var-requires": "off" + } + }, + { + files: ["**/*.vue"], + languageOptions: { + globals: { + $: "readonly", + $$: "readonly", + $computed: "readonly", + $customRef: "readonly", + $ref: "readonly", + $shallowRef: "readonly", + $toRef: "readonly" + }, + parser: parserVue, + parserOptions: { + ecmaFeatures: { + jsx: true + }, + extraFileExtensions: [".vue"], + parser: "@typescript-eslint/parser", + sourceType: "module" + } + }, + plugins: { + vue: pluginVue + }, + processor: pluginVue.processors[".vue"], + rules: { + ...pluginVue.configs.base.rules, + ...pluginVue.configs["vue3-essential"].rules, + ...pluginVue.configs["vue3-recommended"].rules, + "no-undef": "off", + "no-unused-vars": "off", + "vue/no-v-html": "off", + "vue/require-default-prop": "off", + "vue/require-explicit-emits": "off", + "vue/multi-word-component-names": "off", + "vue/no-setup-props-reactivity-loss": "off", + "vue/html-self-closing": [ + "error", + { + html: { + void: "always", + normal: "always", + component: "always" + }, + svg: "always", + math: "always" + } + ] + } + } +]); diff --git a/index.html b/index.html new file mode 100644 index 0000000..a888544 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite App + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..1be96ab --- /dev/null +++ b/package.json @@ -0,0 +1,57 @@ +{ + "name": "cloudflare-pages-demo", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev:client": "vite --mode client", + "dev:optimize": "vite optimize", + "dev:server": "vite", + "dev": "npm run dev:optimize && concurrently \"npm run dev:client\" \"npm run dev:server\"", + "debug": "wrangler dev --log-level=debug", + "build": "vite build --mode client && vite build", + "preview": "npm run build && wrangler pages dev dist --log-level=debug", + "deploy": "npm run build && wrangler pages deploy dist --project-name \"cloudflare-pages-demo\"", + "build-only": "run-p type-check \"build-only {@}\" --", + "type-check": "vue-tsc --build --force", + "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", + "format": "prettier --write src/" + }, + "dependencies": { + "hono": "^4.6.2", + "pinia": "^2.1.7", + "qrcode": "^1.5.4", + "vue": "^3.4.29", + "vue-router": "^4.3.3" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20240909.0", + "@eslint/js": "^9.10.0", + "@hono/vite-cloudflare-pages": "^0.4.2", + "@hono/vite-dev-server": "^0.16.0", + "@rushstack/eslint-patch": "^1.8.0", + "@tsconfig/node20": "^20.1.4", + "@types/node": "^20.14.5", + "@types/qrcode": "^1.5.5", + "@typescript-eslint/eslint-plugin": "^8.6.0", + "@typescript-eslint/parser": "^8.0.0", + "@vitejs/plugin-vue": "^5.0.5", + "@vitejs/plugin-vue-jsx": "^4.0.0", + "@vue/eslint-config-typescript": "^13.0.0", + "@vue/tsconfig": "^0.5.1", + "concurrently": "^9.0.1", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-define-config": "^2.1.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-vue": "^9.23.0", + "npm-run-all2": "^6.2.0", + "prettier": "^3.2.5", + "ts-node": "^10.9.2", + "typescript": "~5.4.0", + "vite": "^5.3.1", + "vue-eslint-parser": "^9.4.3", + "vue-tsc": "^2.0.21", + "wrangler": "^3.78.2" + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2 GIT binary patch literal 4286 zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56 zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei z@g6Xq-pDoPl=MANPiR7%172VA%r)kevtV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp= zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8 zx!=3<4seY*%=OlbCbcae?5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3 z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD zsW0Ab)ZK@0cIW%W7z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6 z={Xwx{TKxD#iCLfl2vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S literal 0 HcmV?d00001 diff --git a/schema.sql b/schema.sql new file mode 100644 index 0000000..baa2539 --- /dev/null +++ b/schema.sql @@ -0,0 +1,16 @@ +-- schema.sql +CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + resolution VARCHAR(50), + local_language VARCHAR(10), + m1 VARCHAR(255), + oaid VARCHAR(255), + channel VARCHAR(50), + app_version VARCHAR(20), + app_name VARCHAR(100), + pkg_name VARCHAR(100), + device_id VARCHAR(100), + platform VARCHAR(20), + os_version VARCHAR(20), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..b911eeb --- /dev/null +++ b/src/App.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/src/assets/base.css b/src/assets/base.css new file mode 100644 index 0000000..8816868 --- /dev/null +++ b/src/assets/base.css @@ -0,0 +1,86 @@ +/* color palette from */ +:root { + --vt-c-white: #ffffff; + --vt-c-white-soft: #f8f8f8; + --vt-c-white-mute: #f2f2f2; + + --vt-c-black: #181818; + --vt-c-black-soft: #222222; + --vt-c-black-mute: #282828; + + --vt-c-indigo: #2c3e50; + + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); + + --vt-c-text-light-1: var(--vt-c-indigo); + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); + --vt-c-text-dark-1: var(--vt-c-white); + --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); +} + +/* semantic color variables for this project */ +:root { + --color-background: var(--vt-c-white); + --color-background-soft: var(--vt-c-white-soft); + --color-background-mute: var(--vt-c-white-mute); + + --color-border: var(--vt-c-divider-light-2); + --color-border-hover: var(--vt-c-divider-light-1); + + --color-heading: var(--vt-c-text-light-1); + --color-text: var(--vt-c-text-light-1); + + --section-gap: 160px; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-background: var(--vt-c-black); + --color-background-soft: var(--vt-c-black-soft); + --color-background-mute: var(--vt-c-black-mute); + + --color-border: var(--vt-c-divider-dark-2); + --color-border-hover: var(--vt-c-divider-dark-1); + + --color-heading: var(--vt-c-text-dark-1); + --color-text: var(--vt-c-text-dark-2); + } +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + font-weight: normal; +} + +body { + min-height: 100vh; + color: var(--color-text); + background: var(--color-background); + transition: + color 0.5s, + background-color 0.5s; + line-height: 1.6; + font-family: + Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Oxygen, + Ubuntu, + Cantarell, + 'Fira Sans', + 'Droid Sans', + 'Helvetica Neue', + sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} diff --git a/src/assets/logo.svg b/src/assets/logo.svg new file mode 100644 index 0000000..7565660 --- /dev/null +++ b/src/assets/logo.svg @@ -0,0 +1 @@ + diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..36fb845 --- /dev/null +++ b/src/assets/main.css @@ -0,0 +1,35 @@ +@import './base.css'; + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + font-weight: normal; +} + +a, +.green { + text-decoration: none; + color: hsla(160, 100%, 37%, 1); + transition: 0.4s; + padding: 3px; +} + +@media (hover: hover) { + a:hover { + background-color: hsla(160, 100%, 37%, 0.2); + } +} + +@media (min-width: 1024px) { + body { + display: flex; + place-items: center; + } + + #app { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 0 2rem; + } +} diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..5c94f08 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,14 @@ +import "./assets/main.css"; + +import { createApp } from "vue"; +import { createPinia } from "pinia"; + +import App from "@/App.vue"; +import router from "./router"; + +const app = createApp(App); + +app.use(createPinia()); +app.use(router); + +app.mount("#app"); diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..a8358cd --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,15 @@ +import { createRouter, createWebHashHistory } from "vue-router"; + +const router = createRouter({ + history: createWebHashHistory(import.meta.env.BASE_URL), + strict: true, + routes: [ + { + path: "/", + name: "Home", + component: () => import("@/views/helloworld/index.vue") + } + ] +}); + +export default router; diff --git a/src/views/helloworld/index.vue b/src/views/helloworld/index.vue new file mode 100644 index 0000000..58a3e8f --- /dev/null +++ b/src/views/helloworld/index.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..87eeb4f --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,15 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "exclude": ["src/**/__tests__/*"], + "compilerOptions": { + "composite": true, + "noEmit": false, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ffadb15 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,23 @@ +{ + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.app.json" + } + ], + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "strict": true, + "skipLibCheck": true, + "types": [ + "@cloudflare/workers-types/2023-07-01" + ] + } +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..5b8b8db --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,19 @@ +{ + "extends": "@tsconfig/node20/tsconfig.json", + "include": [ + "vite.config.*", + "vitest.config.*", + "cypress.config.*", + "nightwatch.conf.*", + "playwright.config.*", + "app/**/*", + ], + "compilerOptions": { + "composite": true, + "noEmit": false, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "module": "ESNext", + "moduleResolution": "Bundler", + "types": ["node"], + } +} diff --git a/vite.config.d.ts b/vite.config.d.ts new file mode 100644 index 0000000..089eeef --- /dev/null +++ b/vite.config.d.ts @@ -0,0 +1,2 @@ +declare const _default: import("vite").UserConfigFnObject; +export default _default; diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..a8de01b --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,51 @@ +import { fileURLToPath, URL } from "node:url"; + +import { defineConfig } from "vite"; +import vue from "@vitejs/plugin-vue"; +import vueJsx from "@vitejs/plugin-vue-jsx"; +import pages from "@hono/vite-cloudflare-pages"; +import devServer from "@hono/vite-dev-server"; +import adapter from "@hono/vite-dev-server/cloudflare"; + +export default defineConfig(({ mode }) => { + if (mode === "client") { + return { + plugins: [vue(), vueJsx()], + resolve: { + alias: { + "@": fileURLToPath(new URL("./src", import.meta.url)) + } + }, + server: { + port: 3000, + proxy: { + "/api": { + target: "http://localhost:5173", + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, "/api") + } + } + } + }; + } else { + return { + plugins: [ + pages(), + devServer({ + entry: "app/server.ts", + adapter + }) + ], + build: { + rollupOptions: { + input: "app/server.ts", + output: { + format: "es", + dir: "dist", + entryFileNames: "_worker.js" + } + } + } + }; + } +}); diff --git a/wrangler.toml b/wrangler.toml new file mode 100644 index 0000000..48f4bd0 --- /dev/null +++ b/wrangler.toml @@ -0,0 +1,3 @@ +name = "cloudflare-pages-demo" +compatibility_date = "2024-09-09" +main = "app/server.ts"