create-me-antdv-next 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md ADDED
@@ -0,0 +1,78 @@
1
+ # create-me-antdv-next
2
+
3
+ Project scaffold (CLI) based on Vue 3 + TypeScript + Vite + antdv-next + me-ui-antdv-next.
4
+
5
+ Use `npm create` to generate a ready-to-develop, ready-to-build Vue application.
6
+
7
+ ## Getting Started
8
+
9
+ ```bash
10
+ # Generate a project (replace my-app with any project name)
11
+ npm create me-antdv-next@latest my-app
12
+
13
+ # Enter project, install dependencies, start development
14
+ cd my-app
15
+ npm install
16
+ npm run dev
17
+ ```
18
+
19
+ > If you omit the project name (`npm create me-antdv-next@latest`), you'll be prompted interactively.
20
+
21
+ The generated project ships complete source code and configuration, and can be built with `npm run build`.
22
+
23
+ Common commands inside the generated **application**:
24
+
25
+ ```bash
26
+ npm run dev # Start dev server (default port 3000)
27
+ npm run build # Type-check + build production bundle
28
+ npm run preview # Preview production build
29
+ npm run lint # Lint and auto-fix
30
+ ```
31
+
32
+ Requests prefixed with `/api` in the dev server are proxied to `VITE_API_BASE_URL` configured in `env/`.
33
+
34
+ ## Generated App Tech Stack
35
+
36
+ - **Framework**: Vue 3.5 + TypeScript
37
+ - **Build**: Vite 8
38
+ - **UI Library**: antdv-next 1.5 + @me-framework/me-ui-antdv-next
39
+ - **Icons**: @antdv-next/icons + @lucide/vue
40
+ - **Router**: vue-router 5
41
+ - **State Management**: Pinia 4 (with persistedstate)
42
+ - **Auto Import**: unplugin-auto-import + unplugin-vue-components
43
+ - **Styling**: SCSS
44
+ - **Code Quality**: ESLint + Prettier
45
+
46
+ ## Scaffold Source Structure
47
+
48
+ ```
49
+ ├── index.mjs # CLI entry
50
+ ├── template/ # App template (copied when generating a project)
51
+ │ ├── env/ # Environment variables
52
+ │ ├── src/ # App source
53
+ │ │ ├── router/ # Router configuration
54
+ │ │ ├── store/ # State management (Pinia)
55
+ │ │ ├── styles/ # Global styles
56
+ │ │ ├── views/ # Page views
57
+ │ │ └── main.ts # Entry file
58
+ │ ├── index.html
59
+ │ ├── vite.config.ts
60
+ │ └── ...
61
+ ├── scripts/
62
+ │ ├── publish.js # Bump version + publish + tag/push
63
+ │ └── quick-publish.js # Bump version + publish
64
+ └── package.json # Scaffold (CLI) package manifest
65
+ ```
66
+
67
+ ## Development & Publishing
68
+
69
+ This repo is the scaffold source itself. After cloning:
70
+
71
+ ```bash
72
+ # Debug the CLI locally (generate into a directory)
73
+ node index.mjs my-app
74
+
75
+ # Publish a new version
76
+ node scripts/quick-publish.js patch # Bump version and publish
77
+ node scripts/publish.js patch # Bump version + publish + tag & push
78
+ ```
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # create-me-antdv-next
2
+
3
+ 基于 Vue 3 + TypeScript + Vite + antdv-next + me-ui-antdv-next 的项目脚手架(CLI)。
4
+
5
+ 使用 `npm create` 一键生成一个可直接开发、构建的 Vue 应用项目。
6
+
7
+ ## 快速开始
8
+
9
+ ```bash
10
+ # 生成项目(my-app 可换成任意项目名)
11
+ npm create me-antdv-next@latest my-app
12
+
13
+ # 进入项目、安装依赖、启动开发
14
+ cd my-app
15
+ npm install
16
+ npm run dev
17
+ ```
18
+
19
+ > 也可以不传项目名:`npm create me-antdv-next@latest` 会交互式提醒输入名称。
20
+
21
+ 生成的项目包含完整源码和配置,可直接 `npm run build` 输出生产包。
22
+
23
+ 生成的**应用**内的常用命令:
24
+
25
+ ```bash
26
+ npm run dev # 启动开发服务(默认端口 3000)
27
+ npm run build # 类型检查 + 构建生产包
28
+ npm run preview # 预览生产构建
29
+ npm run lint # ESLint 检查并修复
30
+ ```
31
+
32
+ 开发服务 `/api` 前缀请求会代理到 `env/` 中配置的 `VITE_API_BASE_URL`。
33
+
34
+ ## 生成的应用技术栈
35
+
36
+ - **框架**: Vue 3.5 + TypeScript
37
+ - **构建**: Vite 8
38
+ - **UI 库**: antdv-next 1.5 + @me-framework/me-ui-antdv-next
39
+ - **图标**: @antdv-next/icons + @lucide/vue
40
+ - **路由**: vue-router 5
41
+ - **状态管理**: Pinia 4(含 persistedstate 持久化)
42
+ - **自动导入**: unplugin-auto-import + unplugin-vue-components
43
+ - **样式**: SCSS
44
+ - **代码规范**: ESLint + Prettier
45
+
46
+ ## 脚手架源码目录结构
47
+
48
+ ```
49
+ ├── index.mjs # CLI 入口
50
+ ├── template/ # 应用模板(生成项目时复制过去)
51
+ │ ├── env/ # 环境变量配置
52
+ │ ├── src/ # 应用源码
53
+ │ │ ├── router/ # 路由配置
54
+ │ │ ├── store/ # 状态管理 (Pinia)
55
+ │ │ ├── styles/ # 全局样式
56
+ │ │ ├── views/ # 页面视图
57
+ │ │ └── main.ts # 入口文件
58
+ │ ├── index.html
59
+ │ ├── vite.config.ts
60
+ │ └── ...
61
+ ├── scripts/
62
+ │ ├── publish.js # 发布脚本(更新版本号 + 发布 + 打 tag)
63
+ │ └── quick-publish.js # 快速发布(仅更新版本号 + 发布)
64
+ └── package.json # 脚手架(CLI)包配置
65
+ ```
66
+
67
+ ## 开发与发布
68
+
69
+ 本仓库是脚手架本体的代码。克隆后:
70
+
71
+ ```bash
72
+ # 本地调试 CLI(生成到指定目录)
73
+ node index.mjs my-app
74
+
75
+ # 发布新版本
76
+ node scripts/quick-publish.js patch # 更新版本号并发布
77
+ node scripts/publish.js patch # 更新版本号 + 发布 + 打 tag 并推送
78
+ ```
package/index.mjs ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * create-me-antdv-next
4
+ *
5
+ * Usage:
6
+ * npm create me-antdv-next@latest my-app
7
+ * npm create me-antdv-next@latest
8
+ */
9
+ import {
10
+ readdirSync,
11
+ statSync,
12
+ mkdirSync,
13
+ readFileSync,
14
+ writeFileSync,
15
+ copyFileSync,
16
+ cpSync,
17
+ existsSync
18
+ } from 'node:fs'
19
+ import { readdir } from 'node:fs/promises'
20
+ import { resolve, dirname, basename, join } from 'node:path'
21
+ import { fileURLToPath } from 'node:url'
22
+ import { createInterface } from 'node:readline'
23
+
24
+ const __dirname = dirname(fileURLToPath(import.meta.url))
25
+ const templateDir = resolve(__dirname, 'template')
26
+
27
+ // 合法的 npm 包名(小写,不含空格/特殊字符,不能以 . 或 _ 开头)
28
+ const NAME_RE = /^[a-z][a-z0-9-_]*$/
29
+
30
+ async function promptProjectName(targetDir) {
31
+ const rl = createInterface({ input: process.stdin, output: process.stdout })
32
+ const answer = await new Promise((resolvePromise) => {
33
+ rl.question(`Project name: (${targetDir}) `, (v) => resolvePromise(v.trim()))
34
+ })
35
+ rl.close()
36
+ return answer || targetDir
37
+ }
38
+
39
+ async function hasFiles(dir) {
40
+ try {
41
+ return (await readdir(dir)).length > 0
42
+ } catch {
43
+ return false
44
+ }
45
+ }
46
+
47
+ async function copyTemplate(targetDir) {
48
+ for (const name of readdirSync(templateDir)) {
49
+ const srcPath = join(templateDir, name)
50
+ const destPath = join(targetDir, name === '_gitignore' ? '.gitignore' : name)
51
+ if (existsSync(srcPath) && statSync(srcPath).isDirectory()) {
52
+ cpSync(srcPath, destPath, { recursive: true })
53
+ } else {
54
+ copyFileSync(srcPath, destPath)
55
+ }
56
+ }
57
+ }
58
+
59
+ async function main() {
60
+ const args = process.argv.slice(2)
61
+ const unnamedTarget = args.find((a) => a && !a.startsWith('-'))
62
+ const targetArg = unnamedTarget || (await promptProjectName('me-antdv-next-app'))
63
+
64
+ let targetDir = resolve(targetArg)
65
+ let projectName = basename(targetDir)
66
+
67
+ if (!NAME_RE.test(projectName)) {
68
+ console.error(`✖ Invalid project name: ${projectName}`)
69
+ console.error(` - must be lowercase (a-z, 0-9, -, _)`)
70
+ console.error(` - must not start with a dot or underscore`)
71
+ process.exit(1)
72
+ }
73
+
74
+ if (existsSync(targetDir) && (await hasFiles(targetDir))) {
75
+ console.error(`✖ Target directory "${targetArg}" is not empty.`)
76
+ console.error(` Remove it or choose another name.`)
77
+ process.exit(1)
78
+ }
79
+
80
+ mkdirSync(targetDir, { recursive: true })
81
+ await copyTemplate(targetDir)
82
+
83
+ // 写入真实项目名
84
+ const pkgPath = join(targetDir, 'package.json')
85
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'))
86
+ pkg.name = projectName
87
+ writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n')
88
+
89
+ console.log('')
90
+ console.log(`✓ Scaffolding project in ${targetDir}...`)
91
+ console.log('')
92
+ console.log(' Done. Now run:')
93
+ console.log('')
94
+ console.log(` cd ${targetArg}`)
95
+ console.log(' npm install')
96
+ console.log(' npm run dev')
97
+ console.log('')
98
+ }
99
+
100
+ main().catch((err) => {
101
+ console.error(err)
102
+ process.exit(1)
103
+ })
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "create-me-antdv-next",
3
+ "version": "0.1.1",
4
+ "description": "Vue 3 + TypeScript + Vite + Antdv Next + Me UI 项目脚手架",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-me-antdv-next": "index.mjs"
8
+ },
9
+ "files": [
10
+ "index.mjs",
11
+ "template"
12
+ ],
13
+ "keywords": [
14
+ "vite",
15
+ "vue",
16
+ "vue3",
17
+ "antdv-next",
18
+ "scaffold"
19
+ ],
20
+ "license": "MIT",
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "scripts": {
25
+ "publish": "node scripts/publish.js",
26
+ "quick-publish": "node scripts/quick-publish.js",
27
+ "lint": "eslint index.mjs --fix"
28
+ },
29
+ "devDependencies": {
30
+ "eslint": "^8.57.0"
31
+ }
32
+ }
@@ -0,0 +1,27 @@
1
+ /* eslint-env node */
2
+ module.exports = {
3
+ root: true,
4
+ env: {
5
+ browser: true,
6
+ es2022: true,
7
+ node: true,
8
+ 'vue/setup-compiler-macros': true
9
+ },
10
+ extends: [
11
+ 'eslint:recommended',
12
+ 'plugin:vue/vue3-recommended',
13
+ '@vue/eslint-config-typescript',
14
+ '@vue/eslint-config-prettier'
15
+ ],
16
+ parserOptions: {
17
+ ecmaVersion: 'latest',
18
+ sourceType: 'module'
19
+ },
20
+ rules: {
21
+ 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
22
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
23
+ 'vue/multi-word-component-names': 'off',
24
+ '@typescript-eslint/no-explicit-any': 'off',
25
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }]
26
+ }
27
+ }
@@ -0,0 +1,17 @@
1
+ .git
2
+ .gitignore
3
+ .idea
4
+ .vscode
5
+ .DS_Store
6
+ npm-debug.log*
7
+ yarn-debug.log*
8
+ yarn-error.log*
9
+ pnpm-debug.log*
10
+ dist
11
+ build
12
+ .next
13
+ .out
14
+ .serverless
15
+ .webpack
16
+ .webpack-cache
17
+ node_modules
@@ -0,0 +1,2 @@
1
+ VITE_APP_TITLE=Me Antdv Next
2
+ VITE_API_BASE_URL=http://localhost:8999
@@ -0,0 +1,2 @@
1
+ VITE_APP_TITLE=Me Antdv Next
2
+ VITE_API_BASE_URL=https://api.example.com
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Me Antdv Next</title>
7
+ </head>
8
+ <body>
9
+ <div id="app"></div>
10
+ <script type="module" src="/src/main.ts"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "me-antdv-next-app",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vue-tsc --noEmit && vite build",
9
+ "preview": "vite preview",
10
+ "lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix"
11
+ },
12
+ "dependencies": {
13
+ "@antdv-next/icons": "^1.1.2",
14
+ "@lucide/vue": "^1.41.0",
15
+ "@me-framework/me-ui-antdv-next": "^0.0.26",
16
+ "antdv-next": "^1.5.3",
17
+ "pinia": "^4.0.3",
18
+ "pinia-plugin-persistedstate": "^4.7.1",
19
+ "vue": "^3.5.42",
20
+ "vue-router": "^5.3.0"
21
+ },
22
+ "devDependencies": {
23
+ "@antdv-next/auto-import-resolver": "^1.1.1",
24
+ "@types/node": "^26.2.0",
25
+ "@typescript-eslint/eslint-plugin": "^7.10.0",
26
+ "@typescript-eslint/parser": "^7.10.0",
27
+ "@vitejs/plugin-vue": "^6.0.8",
28
+ "@vue/eslint-config-prettier": "^9.0.0",
29
+ "@vue/eslint-config-typescript": "^13.0.0",
30
+ "autoprefixer": "^10.5.4",
31
+ "eslint": "^8.57.0",
32
+ "eslint-plugin-vue": "^9.26.0",
33
+ "postcss": "^8.4.0",
34
+ "prettier": "^3.9.6",
35
+ "sass": "^1.103.1",
36
+ "typescript": "^5.9.3",
37
+ "unplugin-auto-import": "^21.1.0",
38
+ "unplugin-vue-components": "^32.1.0",
39
+ "vite": "^8.2.2",
40
+ "vite-plugin-vue-devtools": "^8.2.1",
41
+ "vue-tsc": "^3.3.11"
42
+ }
43
+ }
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ plugins: {
3
+ autoprefixer: {}
4
+ }
5
+ }
@@ -0,0 +1,22 @@
1
+ <script setup lang="ts">
2
+ import { ConfigProvider, App as AntdApp } from 'antdv-next'
3
+ import zhCN from 'antdv-next/locale/zh_CN'
4
+ </script>
5
+
6
+ <template>
7
+ <a-config-provider :locale="zhCN">
8
+ <a-app>
9
+ <router-view />
10
+ </a-app>
11
+ </a-config-provider>
12
+ </template>
13
+
14
+ <style>
15
+ html,
16
+ body,
17
+ #app {
18
+ height: 100%;
19
+ margin: 0;
20
+ padding: 0;
21
+ }
22
+ </style>
@@ -0,0 +1,92 @@
1
+ /* eslint-disable */
2
+ /* prettier-ignore */
3
+ /* oxlint-disable */
4
+ /* oxfmt-ignore */
5
+ // @ts-nocheck
6
+ // noinspection JSUnusedGlobalSymbols
7
+ // Generated by unplugin-auto-import
8
+ // biome-ignore lint: disable
9
+ export {}
10
+ declare global {
11
+ const EffectScope: typeof import('vue').EffectScope
12
+ const acceptHMRUpdate: typeof import('pinia').acceptHMRUpdate
13
+ const computed: typeof import('vue').computed
14
+ const createApp: typeof import('vue').createApp
15
+ const createPinia: typeof import('pinia').createPinia
16
+ const customRef: typeof import('vue').customRef
17
+ const defineAsyncComponent: typeof import('vue').defineAsyncComponent
18
+ const defineComponent: typeof import('vue').defineComponent
19
+ const defineStore: typeof import('pinia').defineStore
20
+ const effectScope: typeof import('vue').effectScope
21
+ const getActivePinia: typeof import('pinia').getActivePinia
22
+ const getCurrentInstance: typeof import('vue').getCurrentInstance
23
+ const getCurrentScope: typeof import('vue').getCurrentScope
24
+ const getCurrentWatcher: typeof import('vue').getCurrentWatcher
25
+ const h: typeof import('vue').h
26
+ const inject: typeof import('vue').inject
27
+ const isProxy: typeof import('vue').isProxy
28
+ const isReactive: typeof import('vue').isReactive
29
+ const isReadonly: typeof import('vue').isReadonly
30
+ const isRef: typeof import('vue').isRef
31
+ const isShallow: typeof import('vue').isShallow
32
+ const mapActions: typeof import('pinia').mapActions
33
+ const mapGetters: typeof import('pinia').mapGetters
34
+ const mapState: typeof import('pinia').mapState
35
+ const mapStores: typeof import('pinia').mapStores
36
+ const mapWritableState: typeof import('pinia').mapWritableState
37
+ const markRaw: typeof import('vue').markRaw
38
+ const nextTick: typeof import('vue').nextTick
39
+ const onActivated: typeof import('vue').onActivated
40
+ const onBeforeMount: typeof import('vue').onBeforeMount
41
+ const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
42
+ const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
43
+ const onBeforeUnmount: typeof import('vue').onBeforeUnmount
44
+ const onBeforeUpdate: typeof import('vue').onBeforeUpdate
45
+ const onDeactivated: typeof import('vue').onDeactivated
46
+ const onErrorCaptured: typeof import('vue').onErrorCaptured
47
+ const onMounted: typeof import('vue').onMounted
48
+ const onRenderTracked: typeof import('vue').onRenderTracked
49
+ const onRenderTriggered: typeof import('vue').onRenderTriggered
50
+ const onScopeDispose: typeof import('vue').onScopeDispose
51
+ const onServerPrefetch: typeof import('vue').onServerPrefetch
52
+ const onUnmounted: typeof import('vue').onUnmounted
53
+ const onUpdated: typeof import('vue').onUpdated
54
+ const onWatcherCleanup: typeof import('vue').onWatcherCleanup
55
+ const provide: typeof import('vue').provide
56
+ const reactive: typeof import('vue').reactive
57
+ const readonly: typeof import('vue').readonly
58
+ const ref: typeof import('vue').ref
59
+ const resolveComponent: typeof import('vue').resolveComponent
60
+ const setActivePinia: typeof import('pinia').setActivePinia
61
+ const setMapStoreSuffix: typeof import('pinia').setMapStoreSuffix
62
+ const shallowReactive: typeof import('vue').shallowReactive
63
+ const shallowReadonly: typeof import('vue').shallowReadonly
64
+ const shallowRef: typeof import('vue').shallowRef
65
+ const storeToRefs: typeof import('pinia').storeToRefs
66
+ const toRaw: typeof import('vue').toRaw
67
+ const toRef: typeof import('vue').toRef
68
+ const toRefs: typeof import('vue').toRefs
69
+ const toValue: typeof import('vue').toValue
70
+ const triggerRef: typeof import('vue').triggerRef
71
+ const unref: typeof import('vue').unref
72
+ const useAttrs: typeof import('vue').useAttrs
73
+ const useCssModule: typeof import('vue').useCssModule
74
+ const useCssVars: typeof import('vue').useCssVars
75
+ const useId: typeof import('vue').useId
76
+ const useLink: typeof import('vue-router').useLink
77
+ const useModel: typeof import('vue').useModel
78
+ const useRoute: typeof import('vue-router').useRoute
79
+ const useRouter: typeof import('vue-router').useRouter
80
+ const useSlots: typeof import('vue').useSlots
81
+ const useTemplateRef: typeof import('vue').useTemplateRef
82
+ const watch: typeof import('vue').watch
83
+ const watchEffect: typeof import('vue').watchEffect
84
+ const watchPostEffect: typeof import('vue').watchPostEffect
85
+ const watchSyncEffect: typeof import('vue').watchSyncEffect
86
+ }
87
+ // for type re-export
88
+ declare global {
89
+ // @ts-ignore
90
+ export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
91
+ import('vue')
92
+ }
@@ -0,0 +1,22 @@
1
+ /* eslint-disable */
2
+ // @ts-nocheck
3
+ // biome-ignore lint: disable
4
+ // oxlint-disable
5
+ // ------
6
+ // Generated by unplugin-vue-components
7
+ // Read more: https://github.com/vuejs/core/pull/3399
8
+
9
+ export {}
10
+
11
+ /* prettier-ignore */
12
+ declare module 'vue' {
13
+ export interface GlobalComponents {
14
+ AApp: typeof import('antdv-next')['App']
15
+ AButton: typeof import('antdv-next')['Button']
16
+ AConfigProvider: typeof import('antdv-next')['ConfigProvider']
17
+ ASpace: typeof import('antdv-next')['Space']
18
+ LucideHeart: typeof import('@lucide/vue')['Heart']
19
+ RouterLink: typeof import('vue-router')['RouterLink']
20
+ RouterView: typeof import('vue-router')['RouterView']
21
+ }
22
+ }
@@ -0,0 +1,15 @@
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_APP_TITLE: string
5
+ }
6
+
7
+ interface ImportMeta {
8
+ readonly env: ImportMetaEnv
9
+ }
10
+
11
+ declare module '*.vue' {
12
+ import type { DefineComponent } from 'vue'
13
+ const component: DefineComponent<{}, {}, any>
14
+ export default component
15
+ }
@@ -0,0 +1,19 @@
1
+ import { createApp } from 'vue'
2
+ import App from './App.vue'
3
+ import router from './router'
4
+ import { setupStore } from './store'
5
+
6
+ import Antd from 'antdv-next'
7
+ import MeUIAntdvNext from '@me-framework/me-ui-antdv-next'
8
+ import 'antdv-next/dist/antd.css'
9
+ import '@me-framework/me-ui-antdv-next/style.css'
10
+ import './styles/global.scss'
11
+
12
+ const app = createApp(App)
13
+
14
+ setupStore(app)
15
+ app.use(router)
16
+ app.use(Antd)
17
+ app.use(MeUIAntdvNext)
18
+
19
+ app.mount('#app')
@@ -0,0 +1,10 @@
1
+ import type { Router } from 'vue-router'
2
+
3
+ export function setupRouterGuard(router: Router) {
4
+ router.beforeEach((to, _from, next) => {
5
+ if (to.meta.title) {
6
+ document.title = `${to.meta.title} - ${import.meta.env.VITE_APP_TITLE || 'Me Antdv Next'}`
7
+ }
8
+ next()
9
+ })
10
+ }
@@ -0,0 +1,14 @@
1
+ import { createRouter, createWebHashHistory } from 'vue-router'
2
+ import { constantRoutes } from './routes'
3
+ import { setupRouterGuard } from './guard'
4
+
5
+ const router = createRouter({
6
+ history: createWebHashHistory(),
7
+ routes: constantRoutes,
8
+ scrollBehavior: () => ({ top: 0 })
9
+ })
10
+
11
+ // 安装路由守卫
12
+ setupRouterGuard(router)
13
+
14
+ export default router
@@ -0,0 +1,9 @@
1
+ import type { RouteRecordRaw } from 'vue-router'
2
+
3
+ export const constantRoutes: RouteRecordRaw[] = [
4
+ {
5
+ path: '/',
6
+ name: 'Home',
7
+ component: () => import('@/views/home/index.vue')
8
+ }
9
+ ]
@@ -0,0 +1,12 @@
1
+ import type { App } from 'vue'
2
+ import { createPinia } from 'pinia'
3
+ import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
4
+
5
+ const store = createPinia()
6
+ store.use(piniaPluginPersistedstate)
7
+
8
+ export function setupStore(app: App) {
9
+ app.use(store)
10
+ }
11
+
12
+ export { store }
@@ -0,0 +1,42 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ html,
8
+ body,
9
+ #app {
10
+ height: 100%;
11
+ width: 100%;
12
+ }
13
+
14
+ body {
15
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
16
+ Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
17
+ -webkit-font-smoothing: antialiased;
18
+ -moz-osx-font-smoothing: grayscale;
19
+ }
20
+
21
+ a {
22
+ text-decoration: none;
23
+ color: inherit;
24
+ }
25
+
26
+ ::-webkit-scrollbar {
27
+ width: 6px;
28
+ height: 6px;
29
+ }
30
+
31
+ ::-webkit-scrollbar-track {
32
+ background: transparent;
33
+ }
34
+
35
+ ::-webkit-scrollbar-thumb {
36
+ background: rgba(0, 0, 0, 0.2);
37
+ border-radius: 3px;
38
+
39
+ &:hover {
40
+ background: rgba(0, 0, 0, 0.4);
41
+ }
42
+ }
@@ -0,0 +1,5 @@
1
+ $primary-color: #1677ff;
2
+ $text-color: rgba(0, 0, 0, 0.88);
3
+ $text-color-secondary: rgba(0, 0, 0, 0.65);
4
+ $border-color: #d9d9d9;
5
+ $background-color: #f5f5f5;
@@ -0,0 +1,48 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+
4
+ const count = ref(0)
5
+ </script>
6
+
7
+ <template>
8
+ <div class="home">
9
+ <a-space direction="vertical" size="large" align="center">
10
+ <h1>Me Antdv Next</h1>
11
+ <p>Vue 3 + TypeScript + Vite + Antdv Next + Me UI</p>
12
+ <a-button type="primary" @click="count++">
13
+ <template #icon><LucideHeart :size="16" /></template>
14
+ count is {{ count }}
15
+ </a-button>
16
+ <p>
17
+ Edit
18
+ <code>src/views/home/index.vue</code>
19
+ to test hot module replacement.
20
+ </p>
21
+ </a-space>
22
+ </div>
23
+ </template>
24
+
25
+ <style scoped lang="scss">
26
+ .home {
27
+ display: flex;
28
+ flex-direction: column;
29
+ align-items: center;
30
+ justify-content: center;
31
+ height: 100%;
32
+
33
+ h1 {
34
+ font-size: 2.5rem;
35
+ margin-bottom: 0;
36
+ }
37
+
38
+ p {
39
+ color: rgba(0, 0, 0, 0.65);
40
+ }
41
+
42
+ code {
43
+ background-color: rgba(0, 0, 0, 0.06);
44
+ padding: 2px 6px;
45
+ border-radius: 4px;
46
+ }
47
+ }
48
+ </style>
@@ -0,0 +1,31 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "resolveJsonModule": true,
11
+ "isolatedModules": true,
12
+ "noEmit": true,
13
+ "jsx": "preserve",
14
+ "strict": true,
15
+ "noUnusedLocals": false,
16
+ "noUnusedParameters": false,
17
+ "noFallthroughCasesInSwitch": true,
18
+ "baseUrl": ".",
19
+ "paths": {
20
+ "@/*": ["src/*"]
21
+ },
22
+ "types": ["vite/client", "node"]
23
+ },
24
+ "include": [
25
+ "src/**/*.ts",
26
+ "src/**/*.d.ts",
27
+ "src/**/*.tsx",
28
+ "src/**/*.vue"
29
+ ],
30
+ "references": [{ "path": "./tsconfig.node.json" }]
31
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "skipLibCheck": true,
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "allowSyntheticDefaultImports": true,
8
+ "strict": true
9
+ },
10
+ "include": ["vite.config.ts"]
11
+ }
@@ -0,0 +1,84 @@
1
+ import { defineConfig, loadEnv } from 'vite'
2
+ import vue from '@vitejs/plugin-vue'
3
+ import AutoImport from 'unplugin-auto-import/vite'
4
+ import Components from 'unplugin-vue-components/vite'
5
+ import { AntdvNextResolver } from '@antdv-next/auto-import-resolver'
6
+ import { fileURLToPath } from 'node:url'
7
+ import { resolve, dirname } from 'node:path'
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url))
10
+
11
+ /**
12
+ * Object.prototype 上继承的属性名集合。
13
+ * AntdvNextResolver 内部用 `componentsMap[name]` 直接取值,
14
+ * 当自动导入扫描到 constructor / toString 等标识符时,会命中原型链返回原生函数对象,
15
+ * 序列化后生成损坏的 import。这里在 resolver 层显式排除这些原型属性名。
16
+ */
17
+ const OBJECT_PROTO_KEYWORDS = [
18
+ 'constructor',
19
+ 'toString',
20
+ 'valueOf',
21
+ 'hasOwnProperty',
22
+ 'isPrototypeOf',
23
+ 'propertyIsEnumerable',
24
+ 'toLocaleString',
25
+ '__proto__'
26
+ ]
27
+
28
+ export default defineConfig(({ mode }) => {
29
+ const envDir = resolve(__dirname, 'env')
30
+ const env = loadEnv(mode, envDir)
31
+ return {
32
+ envDir,
33
+ resolve: {
34
+ alias: {
35
+ '@': resolve(__dirname, 'src')
36
+ }
37
+ },
38
+ css: {
39
+ preprocessorOptions: {
40
+ scss: {
41
+ additionalData: `@use "@/styles/variables.scss" as *;`
42
+ }
43
+ }
44
+ },
45
+ plugins: [
46
+ vue(),
47
+ AutoImport({
48
+ imports: ['vue', 'vue-router', 'pinia'],
49
+ dts: 'src/auto-imports.d.ts',
50
+ resolvers: [AntdvNextResolver({ exclude: OBJECT_PROTO_KEYWORDS })]
51
+ }),
52
+ Components({
53
+ dts: 'src/components.d.ts',
54
+ resolvers: [
55
+ AntdvNextResolver({ exclude: OBJECT_PROTO_KEYWORDS }),
56
+ (componentName) => {
57
+ if (componentName.startsWith('Lucide')) {
58
+ return { name: componentName.slice(6), from: '@lucide/vue' }
59
+ }
60
+ }
61
+ ]
62
+ })
63
+ ],
64
+ server: {
65
+ host: '0.0.0.0',
66
+ port: 3000,
67
+ open: false,
68
+ proxy: {
69
+ '/api': {
70
+ target: env.VITE_API_BASE_URL,
71
+ changeOrigin: true,
72
+ rewrite: (path) => path.replace(/^\/api/, '')
73
+ }
74
+ }
75
+ },
76
+ build: {
77
+ outDir: 'dist',
78
+ sourcemap: false
79
+ },
80
+ optimizeDeps: {
81
+ include: ['@me-framework/me-ui-antdv-next']
82
+ }
83
+ }
84
+ })