diff --git a/README.md b/README.md index bb1d0e6..f030ea4 100644 --- a/README.md +++ b/README.md @@ -25,23 +25,7 @@ References: ## Features -- [💚 Nuxt 3](https://v3.nuxtjs.org) - SSR, ESR, File-based routing, components auto importing, modules, etc. - -- 💻 [TypeGraphql](https://typegraphql.com/docs/introduction.html) + [Apollo Server](https://www.apollographql.com/docs/apollo-server/) - -- 🌞 [@urql/vue](https://formidable.com/open-source/urql/docs/basics/vue/) - composable query, SSR or client mode - For example: - ```ts - import { usePersonQuery } from '~/graphql/generated/hello.query' - - const { data, fetching, error } = usePersonQuery({ - variables: ref({ - personInput: { - name: 'Phil Xu', - }, - }), - }) - ``` +- [💚 Nuxt 3](https://nuxt.com/) - SSR, ESR, File-based routing, components auto importing, modules, etc. - 🌏 [i18n](https://github.com/intlify/nuxt3) customized intlify i18n - set preferred language according to browser, and save user's preferred language to cookie. diff --git a/components/Footer.vue b/components/Footer.vue index 2bb911e..9aa1be8 100644 --- a/components/Footer.vue +++ b/components/Footer.vue @@ -7,7 +7,7 @@ const { setLocale, locale } = useLocale() diff --git a/components/Home.vue b/components/Home.vue deleted file mode 100644 index 84866ab..0000000 --- a/components/Home.vue +++ /dev/null @@ -1,32 +0,0 @@ - - - diff --git a/components/InputEntry.vue b/components/InputEntry.vue index eb99534..89b9b6e 100644 --- a/components/InputEntry.vue +++ b/components/InputEntry.vue @@ -8,7 +8,7 @@ const go = (): void => { if (name.value) { void router.push({ name: routes.hiId, - params: { id: encodeURIComponent(name.value as string) }, + params: { id: name.value as string }, }) } } @@ -19,7 +19,7 @@ const go = (): void => { +const { t } = useI18n() + +const { data } = await useFetch('/api/pageview' as const) +const time = useTimeAgo( + computed(() => data.value?.startAt ?? new Date()), + { + fullDateFormatter: (date: Date) => date.toLocaleDateString(), + messages: { + justNow: t('justNow'), + past: (n: number | string) => + String(n).match(/\d/) ? t('timeAgo', [n]) : String(n), + future: (n: number | string) => + String(n).match(/\d/) ? t('inTime', [n]) : String(n), + second: (n: number | string) => `${n} ${t(`second${n > 1 ? 's' : ''}`)}`, + minute: (n: number | string) => `${n} ${t(`minute${n > 1 ? 's' : ''}`)}`, + hour: (n: number | string) => `${n} ${t(`hour${n > 1 ? 's' : ''}`)}`, + day: (n: number | string, past: boolean) => + n === 1 + ? past + ? t('yesterday') + : t('tomorrow') + : `${n} ${t(`day${n > 1 ? 's' : ''}`)}`, + week: (n: number | string, past: boolean) => + n === 1 + ? past + ? t('last week') + : t('next week') + : `${n} ${t(`week${n > 1 ? 's' : ''}`)}`, + month: (n: number | string, past: boolean) => + n === 1 + ? past + ? t('last month') + : t('next month') + : `${n} ${t(`month${n > 1 ? 's' : ''}`)}`, + year: (n: number | string, past: boolean) => + n === 1 + ? past + ? t('last year') + : t('next year') + : `${n} ${t(`year${n > 1 ? 's' : ''}`)}`, + }, + }, +) + + + diff --git a/generated/auto-imports.d.ts b/generated/auto-imports.d.ts index 2ed2854..fa882b9 100644 --- a/generated/auto-imports.d.ts +++ b/generated/auto-imports.d.ts @@ -13,6 +13,7 @@ declare global { const setActivePinia: typeof import('pinia')['setActivePinia'] const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] const storeToRefs: typeof import('pinia')['storeToRefs'] + const useI18n: typeof import('vue-i18n')['useI18n'] } // for vue template auto import import { UnwrapRef } from 'vue' @@ -30,5 +31,6 @@ declare module 'vue' { readonly setActivePinia: UnwrapRef readonly setMapStoreSuffix: UnwrapRef readonly storeToRefs: UnwrapRef + readonly useI18n: UnwrapRef } } diff --git a/generated/typed-router/__routes.ts b/generated/typed-router/__routes.ts index 2fc343a..dbf2f0d 100644 --- a/generated/typed-router/__routes.ts +++ b/generated/typed-router/__routes.ts @@ -5,10 +5,9 @@ * */ export const routerPagesNames = { - '404': '404' as const, + all: 'all' as const, hiId: 'hi-id' as const, index: 'index' as const, - restfulPageView: 'restful-page-view' as const, } -export type TypedRouteList = '404' | 'hi-id' | 'index' | 'restful-page-view' +export type TypedRouteList = 'all' | 'hi-id' | 'index' diff --git a/generated/typed-router/__useTypedRouter.ts b/generated/typed-router/__useTypedRouter.ts index b0b9648..5d6abd4 100644 --- a/generated/typed-router/__useTypedRouter.ts +++ b/generated/typed-router/__useTypedRouter.ts @@ -23,12 +23,7 @@ export const useTypedRouter = (): { } => { const { $router } = useNuxtApp() - const routesList = { - '404': '404', - hiId: 'hi-id', - index: 'index', - restfulPageView: 'restful-page-view', - } + const routesList = { all: 'all', hiId: 'hi-id', index: 'index' } return { router: $router, diff --git a/generated/typed-router/typed-router.d.ts b/generated/typed-router/typed-router.d.ts index 2342764..fb461ed 100644 --- a/generated/typed-router/typed-router.d.ts +++ b/generated/typed-router/typed-router.d.ts @@ -13,22 +13,16 @@ import type { } from 'vue-router' import type { TypedRouteList } from './__routes' -export type RouteListDecl = { - '404': '404' - hiId: 'hi-id' - index: 'index' - restfulPageView: 'restful-page-view' -} +export type RouteListDecl = { all: 'all'; hiId: 'hi-id'; index: 'index' } export type TypedRouteParams = { - '404': { - catchAll: string | number + all: { + all: string | number } 'hi-id': { id: string | number } index: never - 'restful-page-view': never } type TypedRouteParamsStructure = { diff --git a/graphql/codegen.yml b/graphql/codegen.yml deleted file mode 100644 index 7745147..0000000 --- a/graphql/codegen.yml +++ /dev/null @@ -1,31 +0,0 @@ -schema: graphql/generated/schema.gql -documents: '**/*.gql' -# hooks: -# afterOneFileWrite: -# - eslint --fix -config: - defaultScalarType: never - useTypeImports: true -# Reference: https://github.com/bicouy0/nuxt3-urql/blob/0f9040955a42cdd6916f48665cdb475037b6b4e7/codegen.yml -generates: - graphql/generated/types.d.ts: - plugins: - - typescript - graphql/generated/ops: - preset: near-operation-file - presetConfig: - baseTypesPath: ../types.d.ts - extension: .ts - # folder: generated - plugins: - - typescript-operations - - typed-document-node - - typescript-vue-urql: - # Disable for we're using `typed-document-node` generated the typed DocumentNode - documentMode: external - # For Graphcache - # - typescript-urql-graphcache - # For Graphcache - # graphql/generated/introspection.ts: - # plugins: - # - urql-introspection diff --git a/graphql/generated/index.ts b/graphql/generated/index.ts deleted file mode 100644 index 7502af2..0000000 --- a/graphql/generated/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './ops/queries/person' diff --git a/graphql/generated/ops/index.js b/graphql/generated/ops/index.js deleted file mode 100644 index 971262a..0000000 --- a/graphql/generated/ops/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports.queries = require('./queries'); diff --git a/graphql/generated/ops/queries/index.js b/graphql/generated/ops/queries/index.js deleted file mode 100644 index e58d340..0000000 --- a/graphql/generated/ops/queries/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const fs = require('fs'); -const path = require('path'); - -module.exports.person = fs.readFileSync(path.join(__dirname, 'person.gql'), 'utf8'); diff --git a/graphql/generated/ops/queries/person.gql b/graphql/generated/ops/queries/person.gql deleted file mode 100644 index 630dd60..0000000 --- a/graphql/generated/ops/queries/person.gql +++ /dev/null @@ -1,6 +0,0 @@ -query person($personInput: PersonInput!){ - person(personInput: $personInput){ - name - tags - } -} \ No newline at end of file diff --git a/graphql/generated/ops/queries/person.ts b/graphql/generated/ops/queries/person.ts deleted file mode 100644 index 7dace73..0000000 --- a/graphql/generated/ops/queries/person.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type * as Types from '../../types.d'; - -import type { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -import * as Urql from '@urql/vue'; -export type Omit = Pick>; -export type PersonQueryVariables = Types.Exact<{ - personInput: Types.PersonInput; -}>; - - -export type PersonQuery = { __typename?: 'Query', person: { __typename?: 'Person', name: string, tags?: Array | null } }; - - -export const PersonDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"person"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"personInput"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"PersonInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"person"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"personInput"},"value":{"kind":"Variable","name":{"kind":"Name","value":"personInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}}]}}]}}]} as unknown as DocumentNode; - - -export function usePersonQuery(options: Omit, 'query'> = {}) { - return Urql.useQuery({ query: PersonDocument, ...options }); -}; \ No newline at end of file diff --git a/graphql/generated/schema.gql b/graphql/generated/schema.gql deleted file mode 100644 index 12a7ef6..0000000 --- a/graphql/generated/schema.gql +++ /dev/null @@ -1,17 +0,0 @@ -# ----------------------------------------------- -# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! -# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! -# ----------------------------------------------- - -type Query { - person(personInput: PersonInput!): Person! -} - -type Person { - name: String! - tags: [String] -} - -input PersonInput { - name: String! -} diff --git a/graphql/generated/types.d.ts b/graphql/generated/types.d.ts deleted file mode 100644 index f374254..0000000 --- a/graphql/generated/types.d.ts +++ /dev/null @@ -1,33 +0,0 @@ -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: string; - String: string; - Boolean: boolean; - Int: number; - Float: number; -}; - -export type Person = { - __typename?: 'Person'; - name: Scalars['String']; - tags?: Maybe>>; -}; - -export type PersonInput = { - name: Scalars['String']; -}; - -export type Query = { - __typename?: 'Query'; - person: Person; -}; - - -export type QueryPersonArgs = { - personInput: PersonInput; -}; diff --git a/layouts/README.md b/layouts/README.md index 0eff511..d5b1fb0 100644 --- a/layouts/README.md +++ b/layouts/README.md @@ -12,4 +12,4 @@ definePageMeta({ ``` -Learn more on https://v3.nuxtjs.org/guide/directory-structure/layouts \ No newline at end of file +Learn more on https://nuxt.com/docs/guide/directory-structure/layouts diff --git a/locales/en.ts b/locales/en.ts index 95e49f5..3e0d585 100644 --- a/locales/en.ts +++ b/locales/en.ts @@ -3,11 +3,25 @@ export default { clientMode: 'Client Mode', ssrLoading: 'Loading when jump from other landing page', ssrMode: 'Prefetch on SSR Mode', - 'input-name': "What's your name?", + inputName: "What's your name?", go: 'Go', visited: '{count} page views since {time}', back: 'Back', - alias: 'Also as known as', - China: 'China', - 'Phil Xu': 'Phil Xu', + justNow: 'just now', + timeAgo: '{0} ago', + inTime: 'in {0}', + second: 'second', + seconds: 'seconds', + minute: 'minute', + minutes: 'minutes', + hour: 'hour', + hours: 'hours', + day: 'day', + days: 'days', + week: 'week', + weeks: 'weeks', + month: 'month', + months: 'months', + year: 'year', + years: 'years', } diff --git a/locales/zh-CN.ts b/locales/zh-CN.ts index 89f9d7b..e4995a9 100644 --- a/locales/zh-CN.ts +++ b/locales/zh-CN.ts @@ -3,11 +3,25 @@ export default { clientMode: '客户端模式数据', ssrLoading: '从其他落地页跳转加载中效果', ssrMode: 'SSR模式预加载数据', - 'input-name': '你的名字?', + inputName: '你的名字?', go: '确定', visited: '自{time}以来访问了{count}次', back: '返回', - alias: '也叫做', - China: '中国', - 'Phil Xu': '许鹏飞', + justNow: '刚刚', + timeAgo: '{0}之前', + inTime: '{0}之后', + second: '秒', + seconds: '秒', + minute: '分钟', + minutes: '分钟', + hour: '小时', + hours: '小时', + day: '天', + days: '天', + week: '周', + weeks: '周', + month: '月', + months: '月', + year: '年', + years: '年', } diff --git a/netlify.toml b/netlify.toml index bd06a07..88ef990 100755 --- a/netlify.toml +++ b/netlify.toml @@ -1,10 +1,9 @@ [build.environment] - NPM_FLAGS = "--version" NODE_VERSION = "16" [build] publish = "dist" - command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run build" + command = "pnpm run build" [[redirects]] from = "/*" diff --git a/nuxt.config.ts b/nuxt.config.ts index 477b8f6..109af2c 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,6 +1,6 @@ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' -const lifecycle = process.env.npm_lifecycle_event +const _lifecycle = process.env.npm_lifecycle_event const elementPlusResolver = ElementPlusResolver({ ssr: true, @@ -12,6 +12,7 @@ const autoImportOpts = { imports: [ // presets 'pinia', + 'vue-i18n', // custom {}, ], @@ -81,6 +82,7 @@ export default defineNuxtConfig({ }, experimental: { reactivityTransform: true, + inlineSSRStyles: false, // May disable for error: // https://github.com/antfu/vitesse-nuxt3/issues/42#issuecomment-1126377430 // viteNode: false, diff --git a/package.json b/package.json index 0b73b00..bb319a3 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,6 @@ "build": "nuxi build", "build:lambda": "cross-env NITRO_PRESET=lambda nuxi build", "generate": "nuxi generate", - "graphql-gen": "npm run graphql-gen-ops && npm run graphql-codegen", - "graphql-gen-ops": "gqlg --schemaFilePath ./graphql/generated/schema.gql --destDirPath ./graphql/generated/ops --depthLimit 100", - "graphql-codegen": "graphql-codegen -c ./graphql/codegen.yml", "start": "node .output/server/index.mjs", "serverless:deploy": "serverless deploy", "serverless:domain": "serverless create_domain", @@ -34,55 +31,42 @@ }, "prettier": "@daotl/prettier-config", "dependencies": { - "@iconify-json/carbon": "^1.1.9", - "@iconify-json/twemoji": "^1.1.5", - "@urql/vue": "^1.0.2", - "apollo-server-core": "^3.10.3", - "class-validator": "^0.13.2", - "element-plus": "^2.2.19", - "graphql": "^15.3.0", - "graphql-playground-html": "^1.6.30", - "graphql-tag": "^2.12.6", - "pinia": "^2.0.23", + "@iconify-json/carbon": "^1.1.11", + "@iconify-json/twemoji": "^1.1.7", + "class-validator": "^0.14.0", + "element-plus": "^2.2.27", + "pinia": "^2.0.28", "reflect-metadata": "^0.1.13", - "rxjs": "^7.5.7", - "type-graphql": "^1.1.1", - "vue": "^3.2.41", - "vue-i18n": "^9.2.2", - "vue-tsc": "^1.0.9" + "rxjs": "^7.8.0", + "vue": "^3.2.45", + "vue-i18n": "^9.2.2" }, "devDependencies": { - "@daotl/eslint-config-vue": "^0.3.32", - "@graphql-codegen/cli": "^2.13.7", - "@graphql-codegen/near-operation-file-preset": "^2.4.3", - "@graphql-codegen/typed-document-node": "^2.3.5", - "@graphql-codegen/typescript-operations": "^2.5.5", - "@graphql-codegen/typescript-vue-apollo": "^3.3.5", - "@graphql-codegen/typescript-vue-urql": "^2.3.5", - "@nuxtjs/color-mode": "^3.1.8", - "@pinia/nuxt": "^0.4.3", + "@daotl/eslint-config-vue": "^0.3.33", + "@nuxtjs/color-mode": "^3.2.0", + "@pinia/nuxt": "^0.4.6", "@stylelint/postcss-css-in-js": "^0.38.0", - "@types/node": "^18.11.5", - "@unocss/nuxt": "^0.46.0", - "@vueuse/nuxt": "^9.4.0", - "eslint": "^8.26.0", - "gql-generator": "^1.0.18", - "husky": "^8.0.1", - "lint-staged": "^13.0.3", - "nuxt": "3.0.0-rc.12", + "@types/node": "^18.11.17", + "@unocss/nuxt": "^0.47.6", + "@vueuse/nuxt": "^9.7.0", + "eslint": "^8.30.0", + "husky": "^8.0.2", + "lint-staged": "^13.1.0", + "nuxt": "3.0.0", "nuxt-typed-router": "^1.2.3", - "postcss": "^8.4.18", + "postcss": "^8.4.20", "postcss-html": "^1.5.0", "postcss-syntax": "^0.36.2", - "prettier": "^2.7.1", - "sass": "^1.55.0", - "stylelint": "^14.14.0", + "prettier": "^2.8.1", + "sass": "^1.57.0", + "stylelint": "^14.16.0", "stylelint-config-property-sort-order-smacss": "^9.0.0", "stylelint-config-recommended-scss": "^8.0.0", "stylelint-config-recommended-vue": "^1.4.0", - "typescript": "^4.8.4", - "unplugin-auto-import": "^0.11.4", - "unplugin-vue-components": "^0.22.9", - "vite": "^3.1.8" + "typescript": "^4.9.4", + "unplugin-auto-import": "git://github.com/daotl/unplugin-auto-import#6b2bbc40c928340fb473b56d91240d9d617665c4", + "unplugin-vue-components": "git://github.com/daotl/unplugin-vue-components#75d581e694b62072d3ab7dcae496aff91432f74b", + "vite": "^3.2.5", + "vue-tsc": "1.0.13" } } diff --git a/pages/404.vue b/pages/[...all].vue similarity index 100% rename from pages/404.vue rename to pages/[...all].vue diff --git a/pages/hi/[id].vue b/pages/hi/[id].vue index eafff85..8706adf 100644 --- a/pages/hi/[id].vue +++ b/pages/hi/[id].vue @@ -30,7 +30,7 @@ definePageMeta({
  • - {{ $t(otherName) }} + {{ otherName }}
diff --git a/pages/index.vue b/pages/index.vue index 133e7ea..b081d09 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -2,7 +2,7 @@
- +