create-young-proj 1.3.0 → 1.5.0
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/CHANGELOG.md +39 -0
- package/README.md +6 -1
- package/dist/index.mjs +12 -12
- package/package.json +1 -1
- package/src/index.ts +6 -1
- package/template-nuxt-admin/env.d.ts +19 -1
- package/template-nuxt-admin/server/plugins/env.ts +0 -1
- package/template-nuxt-website/env.d.ts +18 -1
- package/template-uni-app/_env +1 -1
- package/template-uni-app/custom-plugins/multiconf.ts +13 -2
- package/template-vitepress/.vitepress/components/HomePage.vue +54 -0
- package/template-vitepress/.vitepress/components/TodoItem.vue +16 -0
- package/template-vitepress/.vitepress/components.d.ts +13 -0
- package/template-vitepress/.vitepress/config.mts +159 -0
- package/template-vitepress/.vitepress/theme/index.ts +26 -0
- package/template-vitepress/.vitepress/theme/style.css +139 -0
- package/template-vitepress/Dockerfile +45 -0
- package/template-vitepress/README.md +102 -0
- package/template-vitepress/_gitignore +6 -0
- package/template-vitepress/_npmrc +2 -0
- package/template-vitepress/_nvmrc +1 -0
- package/template-vitepress/boot.mjs +17 -0
- package/template-vitepress/index.md +53 -0
- package/template-vitepress/nitro.config.ts +19 -0
- package/template-vitepress/package.json +26 -0
- package/template-vitepress/plugins/init.ts +204 -0
- package/template-vitepress/tsconfig.json +3 -0
- package/template-vitepress/vite.config.ts +66 -0
@@ -0,0 +1,204 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-11-10 18:02:07
|
4
|
+
* @LastEditTime: 2023-11-27 15:01:31
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import { resolve } from 'node:path'
|
8
|
+
import { loadConfig } from 'c12'
|
9
|
+
import md5 from 'md5'
|
10
|
+
|
11
|
+
/**
|
12
|
+
* 签名
|
13
|
+
* @param params 参与签名的参数
|
14
|
+
* @param token 秘钥
|
15
|
+
*/
|
16
|
+
export function signFn(params: Record<string, any>, token: string) {
|
17
|
+
const asciiSortedIndexArr = Object.keys(params).sort()
|
18
|
+
let str = ''
|
19
|
+
const obj: Record<string, any> = {}
|
20
|
+
if (asciiSortedIndexArr.length > 0) {
|
21
|
+
for (const key of asciiSortedIndexArr) {
|
22
|
+
const v = params[key]
|
23
|
+
if (v !== null && v !== '') {
|
24
|
+
str += `${key}=${encodeURIComponent(v)}&`
|
25
|
+
obj[key] = v
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
str += `token=${token}`
|
30
|
+
return {
|
31
|
+
sign: md5(str).toUpperCase(),
|
32
|
+
rawValue: obj,
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
/**
|
37
|
+
* 服务上报
|
38
|
+
*/
|
39
|
+
export async function useServerReport(port: number) {
|
40
|
+
enum ReportURL {
|
41
|
+
上线 = '/register/login',
|
42
|
+
心跳 = '/register/heart',
|
43
|
+
}
|
44
|
+
|
45
|
+
const commonReq = async <T>(url: string, data: Record<string, any>, token: string) => {
|
46
|
+
const api_server_url
|
47
|
+
= process.env.NUXT_PUBLIC_API_SERVER || `http://${process.env.APIGATEHOST}`
|
48
|
+
const { sign, rawValue } = signFn(data, token)
|
49
|
+
|
50
|
+
console.log('🚀 ~ file: env.ts:41 ~ commonReq ~ api_server_url:', api_server_url, rawValue)
|
51
|
+
|
52
|
+
const headers = {
|
53
|
+
'Authorization': `Bearer ${token}`,
|
54
|
+
'content-type': 'application/json; charset=utf-8;',
|
55
|
+
'time': `${Math.floor(Date.now() / 1000)}`,
|
56
|
+
sign,
|
57
|
+
}
|
58
|
+
|
59
|
+
return $fetch<T>(`${api_server_url}${url}`, {
|
60
|
+
method: 'post',
|
61
|
+
headers,
|
62
|
+
body: JSON.stringify(rawValue),
|
63
|
+
})
|
64
|
+
}
|
65
|
+
|
66
|
+
/**
|
67
|
+
* auth token
|
68
|
+
*/
|
69
|
+
let token: string
|
70
|
+
|
71
|
+
/**
|
72
|
+
* 登录/获取 token
|
73
|
+
*/
|
74
|
+
const login = async () => {
|
75
|
+
const data = {
|
76
|
+
serverId: process.env.APP_SERVER_ID,
|
77
|
+
serverName: process.env.APP_SERVER_NAME,
|
78
|
+
}
|
79
|
+
|
80
|
+
const { data: _data } = await commonReq<{
|
81
|
+
code: number
|
82
|
+
message: string
|
83
|
+
data: { token: string }
|
84
|
+
}>('/account/v1/internal/service/get_token', data, process.env.APP_SERVER_SECERET as string)
|
85
|
+
|
86
|
+
console.log('🚀 ~ file: env.ts:73 ~ login ~ _data:', _data)
|
87
|
+
|
88
|
+
const { token } = _data
|
89
|
+
console.log('login success, token: ', token, '\ntime: ', new Date().toLocaleString())
|
90
|
+
return token
|
91
|
+
}
|
92
|
+
|
93
|
+
/**
|
94
|
+
* 获取 auth token
|
95
|
+
*/
|
96
|
+
const getToken = async () => {
|
97
|
+
if (!token) {
|
98
|
+
token = await login()
|
99
|
+
setInterval(() => {
|
100
|
+
// 每 23 小时刷一次 token
|
101
|
+
token = ''
|
102
|
+
}, 1000 * 3600 * 23)
|
103
|
+
}
|
104
|
+
return token
|
105
|
+
}
|
106
|
+
|
107
|
+
/**
|
108
|
+
* 服务上线
|
109
|
+
*/
|
110
|
+
const report = async (url: ReportURL) => {
|
111
|
+
const token = await getToken()
|
112
|
+
try {
|
113
|
+
const res = await commonReq<{
|
114
|
+
host: string
|
115
|
+
port: string | number
|
116
|
+
weight: number
|
117
|
+
expire: number
|
118
|
+
}>(url, { port }, token)
|
119
|
+
|
120
|
+
console.log('请求成功:', url, new Date().toLocaleString())
|
121
|
+
return res
|
122
|
+
}
|
123
|
+
catch (error) {
|
124
|
+
console.error('请求失败:', url, error)
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
console.log('------------------------服务登录------------------------')
|
129
|
+
await login()
|
130
|
+
console.log('--------------------------------------------------------')
|
131
|
+
|
132
|
+
console.log('------------------------服务上线------------------------')
|
133
|
+
const info1 = await report(ReportURL.上线)
|
134
|
+
console.log('🚀 ~ file: init.ts:156 ~ defineNitroPlugin ~ info', info1)
|
135
|
+
console.log('--------------------------------------------------------')
|
136
|
+
|
137
|
+
console.log('------------------------服务心跳上报----------------------')
|
138
|
+
const info2 = await report(ReportURL.心跳)
|
139
|
+
console.log('🚀 ~ file: init.ts:163 ~ setInterval ~ info', info2)
|
140
|
+
console.log('----------------------------------------------------------')
|
141
|
+
setInterval(async () => {
|
142
|
+
console.log('------------------------服务心跳上报----------------------')
|
143
|
+
const info = await report(ReportURL.心跳)
|
144
|
+
console.log('🚀 ~ file: init.ts:163 ~ setInterval ~ info', info)
|
145
|
+
console.log('----------------------------------------------------------')
|
146
|
+
}, 1e4)
|
147
|
+
}
|
148
|
+
|
149
|
+
export default defineNitroPlugin(async (nitroApp) => {
|
150
|
+
const env = (process.env.DEPLOY_ENV as 'dev' | 'test' | 'online') || 'dev'
|
151
|
+
const { config } = await loadConfig<Record<string, any>>({
|
152
|
+
name: env,
|
153
|
+
cwd: resolve(process.cwd(), 'config'),
|
154
|
+
defaultConfig: {
|
155
|
+
// 此处可以放置通用的环境变量
|
156
|
+
// 由于频繁修改 package.json 会浪费 docker 性能,故将版本信息放于此处
|
157
|
+
// 优先读取环境变量中的版本信息(自己打的 Tag)
|
158
|
+
NUXT_PUBLIC_CURRENT_VERSION: process.env.PROJECT_VERSION || 'v0.0.1',
|
159
|
+
|
160
|
+
// 服务秘钥,不对前端开放
|
161
|
+
APP_SERVER_SECERET: '我是秘钥',
|
162
|
+
APP_SERVER_NAME: '我是服务名称',
|
163
|
+
APP_SERVER_ID: '我是服务id',
|
164
|
+
},
|
165
|
+
})
|
166
|
+
|
167
|
+
for (const key in config) {
|
168
|
+
if (process.env[key]) {
|
169
|
+
console.log(
|
170
|
+
'系统环境变量优先: ',
|
171
|
+
key,
|
172
|
+
' = ',
|
173
|
+
process.env[key],
|
174
|
+
' -> ',
|
175
|
+
config[key],
|
176
|
+
' -> ',
|
177
|
+
'覆盖',
|
178
|
+
)
|
179
|
+
config[key] = process.env[key]
|
180
|
+
}
|
181
|
+
else {
|
182
|
+
process.env[key] = config[key]
|
183
|
+
}
|
184
|
+
if (!(key.indexOf('NUXT_PUBLIC_') === 0))
|
185
|
+
delete config[key]
|
186
|
+
}
|
187
|
+
|
188
|
+
console.log('------------------------读取配置文件------------------------')
|
189
|
+
console.log(config)
|
190
|
+
console.log('-------------------------------------------------------------')
|
191
|
+
|
192
|
+
nitroApp.hooks.hook('request', (event) => {
|
193
|
+
const headers = event.node.req.headers
|
194
|
+
const path = event.node.req.url
|
195
|
+
console.log('path', path, 'ua', headers['user-agent'], 'x-forwarded-for', headers['x-forwarded-for'], 'x-real-ip', headers['x-real-ip'])
|
196
|
+
})
|
197
|
+
|
198
|
+
// 本地开发,不上报
|
199
|
+
if (process.env.NODE_ENV === 'development')
|
200
|
+
return
|
201
|
+
|
202
|
+
const port = process.env.LISTEN_PORT || 3333
|
203
|
+
useServerReport(+port)
|
204
|
+
})
|
@@ -0,0 +1,66 @@
|
|
1
|
+
/*
|
2
|
+
* @Author: zhangyang
|
3
|
+
* @Date: 2023-11-08 16:35:24
|
4
|
+
* @LastEditTime: 2023-11-08 16:37:49
|
5
|
+
* @Description:
|
6
|
+
*/
|
7
|
+
import fs from 'node:fs'
|
8
|
+
import type { Plugin } from 'vite'
|
9
|
+
import { defineConfig } from 'vite'
|
10
|
+
import Components from 'unplugin-vue-components/vite'
|
11
|
+
import Unocss from 'unocss/vite'
|
12
|
+
import { presetAttributify, presetIcons, presetUno } from 'unocss'
|
13
|
+
import { resolve } from 'pathe'
|
14
|
+
|
15
|
+
export default defineConfig({
|
16
|
+
optimizeDeps: {
|
17
|
+
// vitepress is aliased with replacement `join(DIST_CLIENT_PATH, '/index')`
|
18
|
+
// This needs to be excluded from optimization
|
19
|
+
exclude: ['@vueuse/core', 'vitepress'],
|
20
|
+
},
|
21
|
+
server: {
|
22
|
+
host: true,
|
23
|
+
hmr: {
|
24
|
+
overlay: false,
|
25
|
+
},
|
26
|
+
},
|
27
|
+
plugins: [
|
28
|
+
Components({
|
29
|
+
include: [/\.vue/, /\.md/],
|
30
|
+
dirs: '.vitepress/components',
|
31
|
+
dts: '.vitepress/components.d.ts',
|
32
|
+
}) as Plugin,
|
33
|
+
Unocss({
|
34
|
+
shortcuts: [
|
35
|
+
['btn', 'px-4 py-1 rounded inline-flex justify-center gap-2 text-white leading-30px children:mya !no-underline cursor-pointer disabled:cursor-default disabled:bg-gray-600 disabled:opacity-50'],
|
36
|
+
],
|
37
|
+
presets: [
|
38
|
+
presetUno({
|
39
|
+
dark: 'media',
|
40
|
+
}),
|
41
|
+
presetAttributify(),
|
42
|
+
presetIcons({
|
43
|
+
scale: 1.2,
|
44
|
+
}),
|
45
|
+
],
|
46
|
+
}),
|
47
|
+
IncludesPlugin(),
|
48
|
+
],
|
49
|
+
})
|
50
|
+
|
51
|
+
function IncludesPlugin(): Plugin {
|
52
|
+
return {
|
53
|
+
name: 'include-plugin',
|
54
|
+
enforce: 'pre',
|
55
|
+
transform(code, id) {
|
56
|
+
let changed = false
|
57
|
+
code = code.replace(/\[@@include\]\((.*?)\)/, (_, url) => {
|
58
|
+
changed = true
|
59
|
+
const full = resolve(id, url)
|
60
|
+
return fs.readFileSync(full, 'utf-8')
|
61
|
+
})
|
62
|
+
if (changed)
|
63
|
+
return code
|
64
|
+
},
|
65
|
+
}
|
66
|
+
}
|