Commit 5e99463cd0d6f7a642a8e06624a7de7ad4b79fac
1 parent
5e4be0ad
perf: Refactor vite configuration
Showing
56 changed files
with
645 additions
and
456 deletions
Too many changes to show.
To preserve performance only 56 of 65 files are displayed.
.env.analyze
0 → 100644
1 | +# Whether to open mock | ||
2 | +VITE_USE_MOCK = true | ||
3 | + | ||
4 | +# public path | ||
5 | +VITE_PUBLIC_PATH = / | ||
6 | + | ||
7 | +# Whether to enable gzip or brotli compression | ||
8 | +# Optional: gzip | brotli | none | ||
9 | +# If you need multiple forms, you can use `,` to separate | ||
10 | +VITE_BUILD_COMPRESS = 'none' | ||
11 | + | ||
12 | + | ||
13 | +# Basic interface address SPA | ||
14 | +VITE_GLOB_API_URL=/basic-api | ||
15 | + | ||
16 | +# File upload address, optional | ||
17 | +# It can be forwarded by nginx or write the actual address directly | ||
18 | +VITE_GLOB_UPLOAD_URL=/upload | ||
19 | + | ||
20 | +# Interface prefix | ||
21 | +VITE_GLOB_API_URL_PREFIX= | ||
22 | + | ||
23 | +VITE_ENABLE_ANALYZE = true |
.env.development
@@ -7,7 +7,6 @@ VITE_PUBLIC_PATH = / | @@ -7,7 +7,6 @@ VITE_PUBLIC_PATH = / | ||
7 | # Cross-domain proxy, you can configure multiple | 7 | # Cross-domain proxy, you can configure multiple |
8 | # Please note that no line breaks | 8 | # Please note that no line breaks |
9 | VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]] | 9 | VITE_PROXY = [["/basic-api","http://localhost:3000"],["/upload","http://localhost:3300/upload"]] |
10 | -# VITE_PROXY=[["/api","https://vvbin.cn/test"]] | ||
11 | 10 | ||
12 | # Basic interface address SPA | 11 | # Basic interface address SPA |
13 | VITE_GLOB_API_URL=/basic-api | 12 | VITE_GLOB_API_URL=/basic-api |
.env.production
@@ -9,8 +9,6 @@ VITE_PUBLIC_PATH = / | @@ -9,8 +9,6 @@ VITE_PUBLIC_PATH = / | ||
9 | # If you need multiple forms, you can use `,` to separate | 9 | # If you need multiple forms, you can use `,` to separate |
10 | VITE_BUILD_COMPRESS = 'none' | 10 | VITE_BUILD_COMPRESS = 'none' |
11 | 11 | ||
12 | -# Whether to delete origin files when using compress, default false | ||
13 | -VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false | ||
14 | 12 | ||
15 | # Basic interface address SPA | 13 | # Basic interface address SPA |
16 | VITE_GLOB_API_URL=/basic-api | 14 | VITE_GLOB_API_URL=/basic-api |
.env.test
@@ -10,9 +10,6 @@ VITE_PUBLIC_PATH = / | @@ -10,9 +10,6 @@ VITE_PUBLIC_PATH = / | ||
10 | # If you need multiple forms, you can use `,` to separate | 10 | # If you need multiple forms, you can use `,` to separate |
11 | VITE_BUILD_COMPRESS = 'none' | 11 | VITE_BUILD_COMPRESS = 'none' |
12 | 12 | ||
13 | -# Whether to delete origin files when using compress, default false | ||
14 | -VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false | ||
15 | - | ||
16 | # Basic interface address SPA | 13 | # Basic interface address SPA |
17 | VITE_GLOB_API_URL=/basic-api | 14 | VITE_GLOB_API_URL=/basic-api |
18 | 15 |
apps/portal-view/.gitkeep
0 → 100644
tests/server/README.md renamed to apps/test-server/README.md
tests/server/controller/FileController.ts renamed to apps/test-server/controller/FileController.ts
tests/server/controller/UserController.ts renamed to apps/test-server/controller/UserController.ts
tests/server/ecosystem.config.js renamed to apps/test-server/ecosystem.config.js
tests/server/index.ts renamed to apps/test-server/index.ts
tests/server/nodemon.json renamed to apps/test-server/nodemon.json
tests/server/package.json renamed to apps/test-server/package.json
@@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
3 | "version": "1.0.0", | 3 | "version": "1.0.0", |
4 | "license": "MIT", | 4 | "license": "MIT", |
5 | "scripts": { | 5 | "scripts": { |
6 | - "build": "rimraf ./dist && tsup ./index.ts --dts --format cjs,esm ", | 6 | + "compile": "rimraf ./dist && tsup ./index.ts --dts --format cjs,esm ", |
7 | "prod": "npx pm2 start ecosystem.config.js --env production", | 7 | "prod": "npx pm2 start ecosystem.config.js --env production", |
8 | "restart": "pm2 restart ecosystem.config.js --env production", | 8 | "restart": "pm2 restart ecosystem.config.js --env production", |
9 | "start": "nodemon", | 9 | "start": "nodemon", |
tests/server/routes.ts renamed to apps/test-server/routes.ts
tests/server/service/FileService.ts renamed to apps/test-server/service/FileService.ts
tests/server/service/UserService.ts renamed to apps/test-server/service/UserService.ts
apps/test-server/tsconfig.json
0 → 100644
tests/server/utils.ts renamed to apps/test-server/utils.ts
build/config/themeConfig.ts deleted
100644 → 0
1 | -import { generate } from '@ant-design/colors'; | ||
2 | - | ||
3 | -export const primaryColor = '#0960bd'; | ||
4 | - | ||
5 | -export const darkMode = 'light'; | ||
6 | - | ||
7 | -type Fn = (...arg: any) => any; | ||
8 | - | ||
9 | -type GenerateTheme = 'default' | 'dark'; | ||
10 | - | ||
11 | -export interface GenerateColorsParams { | ||
12 | - mixLighten: Fn; | ||
13 | - mixDarken: Fn; | ||
14 | - tinycolor: any; | ||
15 | - color?: string; | ||
16 | -} | ||
17 | - | ||
18 | -export function generateAntColors(color: string, theme: GenerateTheme = 'default') { | ||
19 | - return generate(color, { | ||
20 | - theme, | ||
21 | - }); | ||
22 | -} | ||
23 | - | ||
24 | -export function getThemeColors(color?: string) { | ||
25 | - const tc = color || primaryColor; | ||
26 | - const lightColors = generateAntColors(tc); | ||
27 | - const primary = lightColors[5]; | ||
28 | - const modeColors = generateAntColors(primary, 'dark'); | ||
29 | - | ||
30 | - return [...lightColors, ...modeColors]; | ||
31 | -} | ||
32 | - | ||
33 | -export function generateColors({ | ||
34 | - color = primaryColor, | ||
35 | - mixLighten, | ||
36 | - mixDarken, | ||
37 | - tinycolor, | ||
38 | -}: GenerateColorsParams) { | ||
39 | - const arr = new Array(19).fill(0); | ||
40 | - const lightens = arr.map((_t, i) => { | ||
41 | - return mixLighten(color, i / 5); | ||
42 | - }); | ||
43 | - | ||
44 | - const darkens = arr.map((_t, i) => { | ||
45 | - return mixDarken(color, i / 5); | ||
46 | - }); | ||
47 | - | ||
48 | - const alphaColors = arr.map((_t, i) => { | ||
49 | - return tinycolor(color) | ||
50 | - .setAlpha(i / 20) | ||
51 | - .toRgbString(); | ||
52 | - }); | ||
53 | - | ||
54 | - const shortAlphaColors = alphaColors.map((item) => item.replace(/\s/g, '').replace(/0\./g, '.')); | ||
55 | - | ||
56 | - const tinycolorLightens = arr | ||
57 | - .map((_t, i) => { | ||
58 | - return tinycolor(color) | ||
59 | - .lighten(i * 5) | ||
60 | - .toHexString(); | ||
61 | - }) | ||
62 | - .filter((item) => item !== '#ffffff'); | ||
63 | - | ||
64 | - const tinycolorDarkens = arr | ||
65 | - .map((_t, i) => { | ||
66 | - return tinycolor(color) | ||
67 | - .darken(i * 5) | ||
68 | - .toHexString(); | ||
69 | - }) | ||
70 | - .filter((item) => item !== '#000000'); | ||
71 | - return [ | ||
72 | - ...lightens, | ||
73 | - ...darkens, | ||
74 | - ...alphaColors, | ||
75 | - ...shortAlphaColors, | ||
76 | - ...tinycolorDarkens, | ||
77 | - ...tinycolorLightens, | ||
78 | - ].filter((item) => !item.includes('-')); | ||
79 | -} |
build/constant.ts deleted
100644 → 0
build/generate/icon/index.ts deleted
100644 → 0
1 | -import path from 'path'; | ||
2 | -import fs from 'fs-extra'; | ||
3 | -import inquirer from 'inquirer'; | ||
4 | -import colors from 'picocolors'; | ||
5 | -import pkg from '../../../package.json'; | ||
6 | - | ||
7 | -async function generateIcon() { | ||
8 | - const dir = path.resolve(process.cwd(), 'node_modules/@iconify/json'); | ||
9 | - | ||
10 | - const raw = await fs.readJSON(path.join(dir, 'collections.json')); | ||
11 | - | ||
12 | - const collections = Object.entries(raw).map(([id, v]) => ({ | ||
13 | - ...(v as any), | ||
14 | - id, | ||
15 | - })); | ||
16 | - | ||
17 | - const choices = collections.map((item) => ({ key: item.id, value: item.id, name: item.name })); | ||
18 | - | ||
19 | - inquirer | ||
20 | - .prompt([ | ||
21 | - { | ||
22 | - type: 'list', | ||
23 | - name: 'useType', | ||
24 | - choices: [ | ||
25 | - { key: 'local', value: 'local', name: 'Local' }, | ||
26 | - { key: 'onLine', value: 'onLine', name: 'OnLine' }, | ||
27 | - ], | ||
28 | - message: 'How to use icons?', | ||
29 | - }, | ||
30 | - { | ||
31 | - type: 'list', | ||
32 | - name: 'iconSet', | ||
33 | - choices: choices, | ||
34 | - message: 'Select the icon set that needs to be generated?', | ||
35 | - }, | ||
36 | - { | ||
37 | - type: 'input', | ||
38 | - name: 'output', | ||
39 | - message: 'Select the icon set that needs to be generated?', | ||
40 | - default: 'src/components/Icon/data', | ||
41 | - }, | ||
42 | - ]) | ||
43 | - .then(async (answers) => { | ||
44 | - const { iconSet, output, useType } = answers; | ||
45 | - const outputDir = path.resolve(process.cwd(), output); | ||
46 | - fs.ensureDir(outputDir); | ||
47 | - const genCollections = collections.filter((item) => [iconSet].includes(item.id)); | ||
48 | - const prefixSet: string[] = []; | ||
49 | - for (const info of genCollections) { | ||
50 | - const data = await fs.readJSON(path.join(dir, 'json', `${info.id}.json`)); | ||
51 | - if (data) { | ||
52 | - const { prefix } = data; | ||
53 | - const isLocal = useType === 'local'; | ||
54 | - const icons = Object.keys(data.icons).map( | ||
55 | - (item) => `${isLocal ? prefix + ':' : ''}${item}`, | ||
56 | - ); | ||
57 | - | ||
58 | - await fs.writeFileSync( | ||
59 | - path.join(output, `icons.data.ts`), | ||
60 | - `export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`, | ||
61 | - ); | ||
62 | - prefixSet.push(prefix); | ||
63 | - } | ||
64 | - } | ||
65 | - fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite')); | ||
66 | - console.log( | ||
67 | - `✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`, | ||
68 | - ); | ||
69 | - }); | ||
70 | -} | ||
71 | - | ||
72 | -generateIcon(); |
build/getConfigFileName.ts deleted
100644 → 0
build/script/buildConf.ts deleted
100644 → 0
1 | -/** | ||
2 | - * Generate additional configuration files when used for packaging. The file can be configured with some global variables, so that it can be changed directly externally without repackaging | ||
3 | - */ | ||
4 | -import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant'; | ||
5 | -import fs, { writeFileSync } from 'fs-extra'; | ||
6 | -import colors from 'picocolors'; | ||
7 | - | ||
8 | -import { getEnvConfig, getRootPath } from '../utils'; | ||
9 | -import { getConfigFileName } from '../getConfigFileName'; | ||
10 | - | ||
11 | -import pkg from '../../package.json'; | ||
12 | - | ||
13 | -interface CreateConfigParams { | ||
14 | - configName: string; | ||
15 | - config: any; | ||
16 | - configFileName?: string; | ||
17 | -} | ||
18 | - | ||
19 | -function createConfig(params: CreateConfigParams) { | ||
20 | - const { configName, config, configFileName } = params; | ||
21 | - try { | ||
22 | - const windowConf = `window.${configName}`; | ||
23 | - // Ensure that the variable will not be modified | ||
24 | - let configStr = `${windowConf}=${JSON.stringify(config)};`; | ||
25 | - configStr += ` | ||
26 | - Object.freeze(${windowConf}); | ||
27 | - Object.defineProperty(window, "${configName}", { | ||
28 | - configurable: false, | ||
29 | - writable: false, | ||
30 | - }); | ||
31 | - `.replace(/\s/g, ''); | ||
32 | - | ||
33 | - fs.mkdirp(getRootPath(OUTPUT_DIR)); | ||
34 | - writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr); | ||
35 | - | ||
36 | - console.log(colors.cyan(`✨ [${pkg.name}]`) + ` - configuration file is build successfully:`); | ||
37 | - console.log(colors.gray(OUTPUT_DIR + '/' + colors.green(configFileName)) + '\n'); | ||
38 | - } catch (error) { | ||
39 | - console.log(colors.red('configuration file configuration file failed to package:\n' + error)); | ||
40 | - } | ||
41 | -} | ||
42 | - | ||
43 | -export function runBuildConfig() { | ||
44 | - const config = getEnvConfig(); | ||
45 | - const configFileName = getConfigFileName(config); | ||
46 | - createConfig({ config, configName: configFileName, configFileName: GLOB_CONFIG_FILE_NAME }); | ||
47 | -} |
build/script/postBuild.ts deleted
100644 → 0
1 | -// #!/usr/bin/env node | ||
2 | - | ||
3 | -import { runBuildConfig } from './buildConf'; | ||
4 | -import colors from 'picocolors'; | ||
5 | - | ||
6 | -import pkg from '../../package.json'; | ||
7 | - | ||
8 | -export const runBuild = async () => { | ||
9 | - try { | ||
10 | - const argvList = process.argv.splice(2); | ||
11 | - | ||
12 | - // Generate configuration file | ||
13 | - if (!argvList.includes('disabled-config')) { | ||
14 | - runBuildConfig(); | ||
15 | - } | ||
16 | - | ||
17 | - console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!'); | ||
18 | - } catch (error) { | ||
19 | - console.log(colors.red('vite build error:\n' + error)); | ||
20 | - process.exit(1); | ||
21 | - } | ||
22 | -}; | ||
23 | -runBuild(); |
build/vite/plugin/html.ts deleted
100644 → 0
1 | -/** | ||
2 | - * Plugin to minimize and use ejs template syntax in index.html. | ||
3 | - * https://github.com/anncwb/vite-plugin-html | ||
4 | - */ | ||
5 | -import type { PluginOption } from 'vite'; | ||
6 | -import { createHtmlPlugin } from 'vite-plugin-html'; | ||
7 | -import pkg from '../../../package.json'; | ||
8 | -import { GLOB_CONFIG_FILE_NAME } from '../../constant'; | ||
9 | - | ||
10 | -export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) { | ||
11 | - const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env; | ||
12 | - | ||
13 | - const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`; | ||
14 | - | ||
15 | - const getAppConfigSrc = () => { | ||
16 | - return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}`; | ||
17 | - }; | ||
18 | - | ||
19 | - const htmlPlugin: PluginOption[] = createHtmlPlugin({ | ||
20 | - minify: isBuild, | ||
21 | - inject: { | ||
22 | - // Inject data into ejs template | ||
23 | - data: { | ||
24 | - title: VITE_GLOB_APP_TITLE, | ||
25 | - }, | ||
26 | - // Embed the generated app.config.js file | ||
27 | - tags: isBuild | ||
28 | - ? [ | ||
29 | - { | ||
30 | - tag: 'script', | ||
31 | - attrs: { | ||
32 | - src: getAppConfigSrc(), | ||
33 | - }, | ||
34 | - }, | ||
35 | - ] | ||
36 | - : [], | ||
37 | - }, | ||
38 | - }); | ||
39 | - return htmlPlugin; | ||
40 | -} |
build/vite/proxy.ts deleted
100644 → 0
1 | -/** | ||
2 | - * Used to parse the .env.development proxy configuration | ||
3 | - */ | ||
4 | -import type { ProxyOptions } from 'vite'; | ||
5 | - | ||
6 | -type ProxyItem = [string, string]; | ||
7 | - | ||
8 | -type ProxyList = ProxyItem[]; | ||
9 | - | ||
10 | -type ProxyTargetList = Record<string, ProxyOptions>; | ||
11 | - | ||
12 | -const httpsRE = /^https:\/\//; | ||
13 | - | ||
14 | -/** | ||
15 | - * Generate proxy | ||
16 | - * @param list | ||
17 | - */ | ||
18 | -export function createProxy(list: ProxyList = []) { | ||
19 | - const ret: ProxyTargetList = {}; | ||
20 | - for (const [prefix, target] of list) { | ||
21 | - const isHttps = httpsRE.test(target); | ||
22 | - | ||
23 | - // https://github.com/http-party/node-http-proxy#options | ||
24 | - ret[prefix] = { | ||
25 | - target: target, | ||
26 | - changeOrigin: true, | ||
27 | - ws: true, | ||
28 | - rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''), | ||
29 | - // https is require secure=false | ||
30 | - ...(isHttps ? { secure: false } : {}), | ||
31 | - }; | ||
32 | - } | ||
33 | - return ret; | ||
34 | -} |
index.html
@@ -8,20 +8,10 @@ | @@ -8,20 +8,10 @@ | ||
8 | name="viewport" | 8 | name="viewport" |
9 | content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" | 9 | content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" |
10 | /> | 10 | /> |
11 | - <title><%= title %></title> | 11 | + <title><%= VITE_GLOB_APP_TITLE %></title> |
12 | <link rel="icon" href="/favicon.ico" /> | 12 | <link rel="icon" href="/favicon.ico" /> |
13 | </head> | 13 | </head> |
14 | <body> | 14 | <body> |
15 | - <script> | ||
16 | - (() => { | ||
17 | - var htmlRoot = document.getElementById('htmlRoot'); | ||
18 | - var theme = window.localStorage.getItem('__APP__DARK__MODE__'); | ||
19 | - if (htmlRoot && theme) { | ||
20 | - htmlRoot.setAttribute('data-theme', theme); | ||
21 | - theme = htmlRoot = null; | ||
22 | - } | ||
23 | - })(); | ||
24 | - </script> | ||
25 | <div id="app"> | 15 | <div id="app"> |
26 | <style> | 16 | <style> |
27 | html[data-theme='dark'] .app-loading { | 17 | html[data-theme='dark'] .app-loading { |
@@ -150,11 +140,11 @@ | @@ -150,11 +140,11 @@ | ||
150 | </style> | 140 | </style> |
151 | <div class="app-loading"> | 141 | <div class="app-loading"> |
152 | <div class="app-loading-wrap"> | 142 | <div class="app-loading-wrap"> |
153 | - <img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo" /> | 143 | + <img src="/logo.png" class="app-loading-logo" alt="Logo" /> |
154 | <div class="app-loading-dots"> | 144 | <div class="app-loading-dots"> |
155 | <span class="dot dot-spin"><i></i><i></i><i></i><i></i></span> | 145 | <span class="dot dot-spin"><i></i><i></i><i></i><i></i></span> |
156 | </div> | 146 | </div> |
157 | - <div class="app-loading-title"><%= title %></div> | 147 | + <div class="app-loading-title"><%= VITE_GLOB_APP_TITLE %></div> |
158 | </div> | 148 | </div> |
159 | </div> | 149 | </div> |
160 | </div> | 150 | </div> |
internal/eslint-config/package.json
@@ -2,6 +2,15 @@ | @@ -2,6 +2,15 @@ | ||
2 | "name": "@vben/eslint-config", | 2 | "name": "@vben/eslint-config", |
3 | "version": "1.0.0", | 3 | "version": "1.0.0", |
4 | "private": true, | 4 | "private": true, |
5 | + "homepage": "https://github.com/vbenjs/vue-vben-admin", | ||
6 | + "bugs": { | ||
7 | + "url": "https://github.com/vbenjs/vue-vben-admin/issues" | ||
8 | + }, | ||
9 | + "repository": { | ||
10 | + "type": "git", | ||
11 | + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", | ||
12 | + "directory": "internal/eslint-config" | ||
13 | + }, | ||
5 | "license": "MIT", | 14 | "license": "MIT", |
6 | "exports": { | 15 | "exports": { |
7 | ".": { | 16 | ".": { |
internal/stylelint-config/package.json
@@ -2,6 +2,15 @@ | @@ -2,6 +2,15 @@ | ||
2 | "name": "@vben/stylelint-config", | 2 | "name": "@vben/stylelint-config", |
3 | "version": "1.0.0", | 3 | "version": "1.0.0", |
4 | "private": true, | 4 | "private": true, |
5 | + "homepage": "https://github.com/vbenjs/vue-vben-admin", | ||
6 | + "bugs": { | ||
7 | + "url": "https://github.com/vbenjs/vue-vben-admin/issues" | ||
8 | + }, | ||
9 | + "repository": { | ||
10 | + "type": "git", | ||
11 | + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", | ||
12 | + "directory": "internal/stylelint-config" | ||
13 | + }, | ||
5 | "license": "MIT", | 14 | "license": "MIT", |
6 | "exports": { | 15 | "exports": { |
7 | ".": { | 16 | ".": { |
tests/server/tsconfig.json renamed to internal/ts-config/node-server.json
internal/ts-config/node.json
@@ -4,9 +4,9 @@ | @@ -4,9 +4,9 @@ | ||
4 | "extends": "./base.json", | 4 | "extends": "./base.json", |
5 | "compilerOptions": { | 5 | "compilerOptions": { |
6 | "lib": ["ESNext"], | 6 | "lib": ["ESNext"], |
7 | - "types": ["vite/client"], | ||
8 | "noImplicitAny": true, | 7 | "noImplicitAny": true, |
9 | "sourceMap": true, | 8 | "sourceMap": true, |
10 | - "noEmit": true | 9 | + "noEmit": true, |
10 | + "baseUrl": "./" | ||
11 | } | 11 | } |
12 | } | 12 | } |
internal/ts-config/package.json
@@ -2,11 +2,23 @@ | @@ -2,11 +2,23 @@ | ||
2 | "name": "@vben/ts-config", | 2 | "name": "@vben/ts-config", |
3 | "version": "1.0.0", | 3 | "version": "1.0.0", |
4 | "private": true, | 4 | "private": true, |
5 | + "homepage": "https://github.com/vbenjs/vue-vben-admin", | ||
6 | + "bugs": { | ||
7 | + "url": "https://github.com/vbenjs/vue-vben-admin/issues" | ||
8 | + }, | ||
9 | + "repository": { | ||
10 | + "type": "git", | ||
11 | + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", | ||
12 | + "directory": "internal/ts-config" | ||
13 | + }, | ||
5 | "license": "MIT", | 14 | "license": "MIT", |
6 | "files": [ | 15 | "files": [ |
7 | "base.json", | 16 | "base.json", |
8 | "node.json", | 17 | "node.json", |
9 | - "vue.json" | 18 | + "vue.json", |
19 | + "node-server.json" | ||
10 | ], | 20 | ], |
11 | - "devDependencies": {} | 21 | + "dependencies": { |
22 | + "@types/node": "^18.15.11" | ||
23 | + } | ||
12 | } | 24 | } |
internal/vite-config/.commitlintrc.js
0 → 100644
1 | +const fs = require('fs'); | ||
2 | +const path = require('path'); | ||
3 | +const { execSync } = require('child_process'); | ||
4 | + | ||
5 | +const scopes = fs | ||
6 | + .readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true }) | ||
7 | + .filter((dirent) => dirent.isDirectory()) | ||
8 | + .map((dirent) => dirent.name.replace(/s$/, '')); | ||
9 | + | ||
10 | +// precomputed scope | ||
11 | +const scopeComplete = execSync('git status --porcelain || true') | ||
12 | + .toString() | ||
13 | + .trim() | ||
14 | + .split('\n') | ||
15 | + .find((r) => ~r.indexOf('M src')) | ||
16 | + ?.replace(/(\/)/g, '%%') | ||
17 | + ?.match(/src%%((\w|-)*)/)?.[1] | ||
18 | + ?.replace(/s$/, ''); | ||
19 | + | ||
20 | +/** @type {import('cz-git').UserConfig} */ | ||
21 | +module.exports = { | ||
22 | + ignores: [(commit) => commit.includes('init')], | ||
23 | + extends: ['@commitlint/config-conventional'], | ||
24 | + rules: { | ||
25 | + 'body-leading-blank': [2, 'always'], | ||
26 | + 'footer-leading-blank': [1, 'always'], | ||
27 | + 'header-max-length': [2, 'always', 108], | ||
28 | + 'subject-empty': [2, 'never'], | ||
29 | + 'type-empty': [2, 'never'], | ||
30 | + 'subject-case': [0], | ||
31 | + 'type-enum': [ | ||
32 | + 2, | ||
33 | + 'always', | ||
34 | + [ | ||
35 | + 'feat', | ||
36 | + 'fix', | ||
37 | + 'perf', | ||
38 | + 'style', | ||
39 | + 'docs', | ||
40 | + 'test', | ||
41 | + 'refactor', | ||
42 | + 'build', | ||
43 | + 'ci', | ||
44 | + 'chore', | ||
45 | + 'revert', | ||
46 | + 'wip', | ||
47 | + 'workflow', | ||
48 | + 'types', | ||
49 | + 'release', | ||
50 | + ], | ||
51 | + ], | ||
52 | + }, | ||
53 | + prompt: { | ||
54 | + /** @use `yarn commit :f` */ | ||
55 | + alias: { | ||
56 | + f: 'docs: fix typos', | ||
57 | + r: 'docs: update README', | ||
58 | + s: 'style: update code format', | ||
59 | + b: 'build: bump dependencies', | ||
60 | + c: 'chore: update config', | ||
61 | + }, | ||
62 | + customScopesAlign: !scopeComplete ? 'top' : 'bottom', | ||
63 | + defaultScope: scopeComplete, | ||
64 | + scopes: [...scopes, 'mock'], | ||
65 | + allowEmptyIssuePrefixs: false, | ||
66 | + allowCustomIssuePrefixs: false, | ||
67 | + | ||
68 | + // English | ||
69 | + typesAppend: [ | ||
70 | + { value: 'wip', name: 'wip: work in process' }, | ||
71 | + { value: 'workflow', name: 'workflow: workflow improvements' }, | ||
72 | + { value: 'types', name: 'types: type definition file changes' }, | ||
73 | + ], | ||
74 | + | ||
75 | + // 中英文对照版 | ||
76 | + // messages: { | ||
77 | + // type: '选择你要提交的类型 :', | ||
78 | + // scope: '选择一个提交范围 (可选):', | ||
79 | + // customScope: '请输入自定义的提交范围 :', | ||
80 | + // subject: '填写简短精炼的变更描述 :\n', | ||
81 | + // body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n', | ||
82 | + // breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n', | ||
83 | + // footerPrefixsSelect: '选择关联issue前缀 (可选):', | ||
84 | + // customFooterPrefixs: '输入自定义issue前缀 :', | ||
85 | + // footer: '列举关联issue (可选) 例如: #31, #I3244 :\n', | ||
86 | + // confirmCommit: '是否提交或修改commit ?', | ||
87 | + // }, | ||
88 | + // types: [ | ||
89 | + // { value: 'feat', name: 'feat: 新增功能' }, | ||
90 | + // { value: 'fix', name: 'fix: 修复缺陷' }, | ||
91 | + // { value: 'docs', name: 'docs: 文档变更' }, | ||
92 | + // { value: 'style', name: 'style: 代码格式' }, | ||
93 | + // { value: 'refactor', name: 'refactor: 代码重构' }, | ||
94 | + // { value: 'perf', name: 'perf: 性能优化' }, | ||
95 | + // { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' }, | ||
96 | + // { value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' }, | ||
97 | + // { value: 'ci', name: 'ci: 修改 CI 配置、脚本' }, | ||
98 | + // { value: 'revert', name: 'revert: 回滚 commit' }, | ||
99 | + // { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' }, | ||
100 | + // { value: 'wip', name: 'wip: 正在开发中' }, | ||
101 | + // { value: 'workflow', name: 'workflow: 工作流程改进' }, | ||
102 | + // { value: 'types', name: 'types: 类型定义文件修改' }, | ||
103 | + // ], | ||
104 | + // emptyScopesAlias: 'empty: 不填写', | ||
105 | + // customScopesAlias: 'custom: 自定义', | ||
106 | + }, | ||
107 | +}; |
internal/vite-config/.eslintignore
0 → 100644
internal/vite-config/.eslintrc.js
0 → 100644
internal/vite-config/.prettierignore
0 → 100644
internal/vite-config/.prettierrc.js
0 → 100644
1 | +module.exports = { | ||
2 | + printWidth: 100, | ||
3 | + semi: true, | ||
4 | + vueIndentScriptAndStyle: true, | ||
5 | + singleQuote: true, | ||
6 | + trailingComma: 'all', | ||
7 | + proseWrap: 'never', | ||
8 | + htmlWhitespaceSensitivity: 'strict', | ||
9 | + endOfLine: 'auto', | ||
10 | + plugins: ['prettier-plugin-packagejson'], | ||
11 | + overrides: [ | ||
12 | + { | ||
13 | + files: '.*rc', | ||
14 | + options: { | ||
15 | + parser: 'json', | ||
16 | + }, | ||
17 | + }, | ||
18 | + ], | ||
19 | +}; |
internal/vite-config/.stylelintignore
0 → 100644
internal/vite-config/.stylelintrc.js
0 → 100644
internal/vite-config/build.config.ts
0 → 100644
internal/vite-config/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "@vben/vite-config", | ||
3 | + "version": "1.0.0", | ||
4 | + "private": true, | ||
5 | + "homepage": "https://github.com/vbenjs/vue-vben-admin", | ||
6 | + "bugs": { | ||
7 | + "url": "https://github.com/vbenjs/vue-vben-admin/issues" | ||
8 | + }, | ||
9 | + "repository": { | ||
10 | + "type": "git", | ||
11 | + "url": "git+https://github.com/vbenjs/vue-vben-admin.git", | ||
12 | + "directory": "internal/vite-config" | ||
13 | + }, | ||
14 | + "license": "MIT", | ||
15 | + "exports": { | ||
16 | + ".": { | ||
17 | + "types": "./dist/index.d.ts", | ||
18 | + "import": "./dist/index.mjs", | ||
19 | + "require": "./dist/index.cjs" | ||
20 | + } | ||
21 | + }, | ||
22 | + "main": "./dist/index.cjs", | ||
23 | + "module": "./dist/index.mjs", | ||
24 | + "types": "./dist/index.d.ts", | ||
25 | + "files": [ | ||
26 | + "dist" | ||
27 | + ], | ||
28 | + "scripts": { | ||
29 | + "clean": "pnpm rimraf .turbo node_modules dist", | ||
30 | + "lint": "pnpm eslint .", | ||
31 | + "stub": "pnpm unbuild --stub" | ||
32 | + }, | ||
33 | + "dependencies": { | ||
34 | + "vite": "^4.3.0-beta.1" | ||
35 | + }, | ||
36 | + "devDependencies": { | ||
37 | + "@types/fs-extra": "^11.0.1", | ||
38 | + "ant-design-vue": "^3.2.16", | ||
39 | + "dayjs": "^1.11.7", | ||
40 | + "dotenv": "^16.0.3", | ||
41 | + "fs-extra": "^11.1.1", | ||
42 | + "less": "^4.1.3", | ||
43 | + "picocolors": "^1.0.0", | ||
44 | + "pkg-types": "^1.0.2", | ||
45 | + "rollup-plugin-visualizer": "^5.9.0", | ||
46 | + "sass": "^1.60.0", | ||
47 | + "vite-plugin-compression": "^0.5.1", | ||
48 | + "vite-plugin-html": "^3.2.0", | ||
49 | + "vite-plugin-mock": "^2.9.6", | ||
50 | + "vite-plugin-purge-icons": "^0.9.2", | ||
51 | + "vite-plugin-svg-icons": "^2.0.1", | ||
52 | + "vite-plugin-windicss": "^1.8.10" | ||
53 | + } | ||
54 | +} |
internal/vite-config/src/config/application.ts
0 → 100644
1 | +import { type UserConfig, defineConfig, mergeConfig, loadEnv } from 'vite'; | ||
2 | +import { resolve } from 'node:path'; | ||
3 | +import { readPackageJSON } from 'pkg-types'; | ||
4 | +import { generateModifyVars } from '../utils/modifyVars'; | ||
5 | +import { commonConfig } from './common'; | ||
6 | +import { createPlugins } from '../plugins'; | ||
7 | +import dayjs from 'dayjs'; | ||
8 | + | ||
9 | +interface DefineOptions { | ||
10 | + overrides?: UserConfig; | ||
11 | + options?: {}; | ||
12 | +} | ||
13 | + | ||
14 | +function defineApplicationConfig(defineOptions: DefineOptions = {}) { | ||
15 | + const { overrides = {} } = defineOptions; | ||
16 | + | ||
17 | + return defineConfig(async ({ command, mode }) => { | ||
18 | + const root = process.cwd(); | ||
19 | + const isBuild = command === 'build'; | ||
20 | + const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_ENABLE_ANALYZE } = loadEnv(mode, root); | ||
21 | + | ||
22 | + const defineData = await createDefineData(root); | ||
23 | + const plugins = await createPlugins({ | ||
24 | + isBuild, | ||
25 | + root, | ||
26 | + enableAnalyze: VITE_ENABLE_ANALYZE === 'true', | ||
27 | + enableMock: VITE_USE_MOCK === 'true', | ||
28 | + compress: VITE_BUILD_COMPRESS, | ||
29 | + }); | ||
30 | + | ||
31 | + const pathResolve = (pathname: string) => resolve(root, '.', pathname); | ||
32 | + | ||
33 | + const applicationConfig: UserConfig = { | ||
34 | + optimizeDeps: { | ||
35 | + include: [ | ||
36 | + '@iconify/iconify', | ||
37 | + 'ant-design-vue/es/locale/zh_CN', | ||
38 | + 'ant-design-vue/es/locale/en_US', | ||
39 | + ], | ||
40 | + }, | ||
41 | + resolve: { | ||
42 | + alias: [ | ||
43 | + { | ||
44 | + find: 'vue-i18n', | ||
45 | + replacement: 'vue-i18n/dist/vue-i18n.cjs.js', | ||
46 | + }, | ||
47 | + // /@/xxxx => src/xxxx | ||
48 | + { | ||
49 | + find: /\/@\//, | ||
50 | + replacement: pathResolve('src') + '/', | ||
51 | + }, | ||
52 | + // /#/xxxx => types/xxxx | ||
53 | + { | ||
54 | + find: /\/#\//, | ||
55 | + replacement: pathResolve('types') + '/', | ||
56 | + }, | ||
57 | + // @/xxxx => src/xxxx | ||
58 | + { | ||
59 | + find: /@\//, | ||
60 | + replacement: pathResolve('src') + '/', | ||
61 | + }, | ||
62 | + // #/xxxx => types/xxxx | ||
63 | + { | ||
64 | + find: /#\//, | ||
65 | + replacement: pathResolve('types') + '/', | ||
66 | + }, | ||
67 | + ], | ||
68 | + }, | ||
69 | + define: defineData, | ||
70 | + build: { | ||
71 | + target: 'es2015', | ||
72 | + cssTarget: 'chrome80', | ||
73 | + rollupOptions: { | ||
74 | + output: { | ||
75 | + manualChunks: { | ||
76 | + vue: ['vue', 'pinia', 'vue-router'], | ||
77 | + antdv: ['ant-design-vue', '@ant-design/icons-vue'], | ||
78 | + }, | ||
79 | + }, | ||
80 | + }, | ||
81 | + }, | ||
82 | + css: { | ||
83 | + preprocessorOptions: { | ||
84 | + less: { | ||
85 | + modifyVars: generateModifyVars(), | ||
86 | + javascriptEnabled: true, | ||
87 | + }, | ||
88 | + }, | ||
89 | + }, | ||
90 | + plugins, | ||
91 | + }; | ||
92 | + | ||
93 | + const mergedConfig = mergeConfig(commonConfig, applicationConfig); | ||
94 | + | ||
95 | + return mergeConfig(mergedConfig, overrides); | ||
96 | + }); | ||
97 | +} | ||
98 | + | ||
99 | +async function createDefineData(root: string) { | ||
100 | + try { | ||
101 | + const pkgJson = await readPackageJSON(root); | ||
102 | + const { dependencies, devDependencies, name, version } = pkgJson; | ||
103 | + | ||
104 | + const __APP_INFO__ = { | ||
105 | + pkg: { dependencies, devDependencies, name, version }, | ||
106 | + lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), | ||
107 | + }; | ||
108 | + return { | ||
109 | + __APP_INFO__: JSON.stringify(__APP_INFO__), | ||
110 | + }; | ||
111 | + } catch (error) { | ||
112 | + return {}; | ||
113 | + } | ||
114 | +} | ||
115 | + | ||
116 | +export { defineApplicationConfig }; |
internal/vite-config/src/config/common.ts
0 → 100644
1 | +import { type UserConfig } from 'vite'; | ||
2 | + | ||
3 | +const commonConfig: UserConfig = { | ||
4 | + server: { | ||
5 | + host: true, | ||
6 | + }, | ||
7 | + esbuild: { | ||
8 | + drop: ['console', 'debugger'], | ||
9 | + }, | ||
10 | + build: { | ||
11 | + reportCompressedSize: false, | ||
12 | + chunkSizeWarningLimit: 1500, | ||
13 | + rollupOptions: { | ||
14 | + // TODO: Prevent memory overflow | ||
15 | + maxParallelFileOps: 3, | ||
16 | + }, | ||
17 | + }, | ||
18 | +}; | ||
19 | + | ||
20 | +export { commonConfig }; |
internal/vite-config/src/config/package.ts
0 → 100644
internal/vite-config/src/index.ts
0 → 100644
1 | +export * from './config/application'; |
internal/vite-config/src/plugins/appConfig.ts
0 → 100644
1 | +import { type PluginOption } from 'vite'; | ||
2 | +import { getEnvConfig } from '../utils/env'; | ||
3 | +import { createContentHash } from '../utils/hash'; | ||
4 | +import { readPackageJSON } from 'pkg-types'; | ||
5 | +import colors from 'picocolors'; | ||
6 | + | ||
7 | +const GLOBAL_CONFIG_FILE_NAME = '_app.config.js'; | ||
8 | +const PLUGIN_NAME = 'app-config'; | ||
9 | + | ||
10 | +async function createAppConfigPlugin({ | ||
11 | + root, | ||
12 | + isBuild, | ||
13 | +}: { | ||
14 | + root: string; | ||
15 | + isBuild: boolean; | ||
16 | +}): Promise<PluginOption> { | ||
17 | + let publicPath: string; | ||
18 | + let source: string; | ||
19 | + if (!isBuild) { | ||
20 | + return { | ||
21 | + name: PLUGIN_NAME, | ||
22 | + }; | ||
23 | + } | ||
24 | + const { version = '' } = await readPackageJSON(root); | ||
25 | + | ||
26 | + return { | ||
27 | + name: PLUGIN_NAME, | ||
28 | + async configResolved(_config) { | ||
29 | + const appTitle = _config?.env?.VITE_GLOB_APP_SHORT_NAME ?? ''; | ||
30 | + publicPath = _config.base; | ||
31 | + source = await getConfigSource(appTitle); | ||
32 | + }, | ||
33 | + async transformIndexHtml(html) { | ||
34 | + publicPath = publicPath.endsWith('/') ? publicPath : `${publicPath}/`; | ||
35 | + | ||
36 | + const appConfigSrc = `${ | ||
37 | + publicPath || '/' | ||
38 | + }${GLOBAL_CONFIG_FILE_NAME}?v=${version}-${createContentHash(source)}}`; | ||
39 | + | ||
40 | + return { | ||
41 | + html, | ||
42 | + tags: [ | ||
43 | + { | ||
44 | + tag: 'script', | ||
45 | + attrs: { | ||
46 | + src: appConfigSrc, | ||
47 | + }, | ||
48 | + }, | ||
49 | + ], | ||
50 | + }; | ||
51 | + }, | ||
52 | + async generateBundle() { | ||
53 | + try { | ||
54 | + this.emitFile({ | ||
55 | + type: 'asset', | ||
56 | + fileName: GLOBAL_CONFIG_FILE_NAME, | ||
57 | + source, | ||
58 | + }); | ||
59 | + | ||
60 | + console.log(colors.cyan(`✨configuration file is build successfully!`)); | ||
61 | + } catch (error) { | ||
62 | + console.log( | ||
63 | + colors.red('configuration file configuration file failed to package:\n' + error), | ||
64 | + ); | ||
65 | + } | ||
66 | + }, | ||
67 | + }; | ||
68 | +} | ||
69 | + | ||
70 | +/** | ||
71 | + * Get the configuration file variable name | ||
72 | + * @param env | ||
73 | + */ | ||
74 | +const getVariableName = (title: string) => { | ||
75 | + return `__PRODUCTION__${title || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, ''); | ||
76 | +}; | ||
77 | + | ||
78 | +async function getConfigSource(appTitle: string) { | ||
79 | + const config = await getEnvConfig(); | ||
80 | + const variableName = getVariableName(appTitle); | ||
81 | + const windowVariable = `window.${variableName}`; | ||
82 | + // Ensure that the variable will not be modified | ||
83 | + let source = `${windowVariable}=${JSON.stringify(config)};`; | ||
84 | + source += ` | ||
85 | + Object.freeze(${windowVariable}); | ||
86 | + Object.defineProperty(window, "${variableName}", { | ||
87 | + configurable: false, | ||
88 | + writable: false, | ||
89 | + }); | ||
90 | + `.replace(/\s/g, ''); | ||
91 | + return source; | ||
92 | +} | ||
93 | + | ||
94 | +export { createAppConfigPlugin }; |
build/vite/plugin/compress.ts renamed to internal/vite-config/src/plugins/compress.ts
@@ -5,10 +5,13 @@ | @@ -5,10 +5,13 @@ | ||
5 | import type { PluginOption } from 'vite'; | 5 | import type { PluginOption } from 'vite'; |
6 | import compressPlugin from 'vite-plugin-compression'; | 6 | import compressPlugin from 'vite-plugin-compression'; |
7 | 7 | ||
8 | -export function configCompressPlugin( | ||
9 | - compress: 'gzip' | 'brotli' | 'none', | 8 | +export function configCompressPlugin({ |
9 | + compress, | ||
10 | deleteOriginFile = false, | 10 | deleteOriginFile = false, |
11 | -): PluginOption | PluginOption[] { | 11 | +}: { |
12 | + compress: string; | ||
13 | + deleteOriginFile?: boolean; | ||
14 | +}): PluginOption[] { | ||
12 | const compressList = compress.split(','); | 15 | const compressList = compress.split(','); |
13 | 16 | ||
14 | const plugins: PluginOption[] = []; | 17 | const plugins: PluginOption[] = []; |
internal/vite-config/src/plugins/html.ts
0 → 100644
1 | +/** | ||
2 | + * Plugin to minimize and use ejs template syntax in index.html. | ||
3 | + * https://github.com/anncwb/vite-plugin-html | ||
4 | + */ | ||
5 | +import type { PluginOption } from 'vite'; | ||
6 | +import { createHtmlPlugin } from 'vite-plugin-html'; | ||
7 | + | ||
8 | +export function configHtmlPlugin({ isBuild }: { isBuild: boolean }) { | ||
9 | + const htmlPlugin: PluginOption[] = createHtmlPlugin({ | ||
10 | + minify: isBuild, | ||
11 | + }); | ||
12 | + return htmlPlugin; | ||
13 | +} |
build/vite/plugin/index.ts renamed to internal/vite-config/src/plugins/index.ts
1 | -import { PluginOption } from 'vite'; | ||
2 | -import vue from '@vitejs/plugin-vue'; | ||
3 | -import vueJsx from '@vitejs/plugin-vue-jsx'; | ||
4 | -import purgeIcons from 'vite-plugin-purge-icons'; | ||
5 | -import windiCSS from 'vite-plugin-windicss'; | 1 | +import { type PluginOption } from 'vite'; |
6 | import { configHtmlPlugin } from './html'; | 2 | import { configHtmlPlugin } from './html'; |
7 | import { configMockPlugin } from './mock'; | 3 | import { configMockPlugin } from './mock'; |
8 | import { configCompressPlugin } from './compress'; | 4 | import { configCompressPlugin } from './compress'; |
9 | import { configVisualizerConfig } from './visualizer'; | 5 | import { configVisualizerConfig } from './visualizer'; |
10 | import { configSvgIconsPlugin } from './svgSprite'; | 6 | import { configSvgIconsPlugin } from './svgSprite'; |
7 | +import { createAppConfigPlugin } from './appConfig'; | ||
8 | +import vue from '@vitejs/plugin-vue'; | ||
9 | +import vueJsx from '@vitejs/plugin-vue-jsx'; | ||
10 | +import purgeIcons from 'vite-plugin-purge-icons'; | ||
11 | +import windiCSS from 'vite-plugin-windicss'; | ||
11 | 12 | ||
12 | -export async function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) { | ||
13 | - const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv; | 13 | +interface Options { |
14 | + isBuild: boolean; | ||
15 | + root: string; | ||
16 | + compress: string; | ||
17 | + enableMock?: boolean; | ||
18 | + enableAnalyze?: boolean; | ||
19 | +} | ||
14 | 20 | ||
15 | - const vitePlugins: (PluginOption | PluginOption[])[] = [ | ||
16 | - // have to | ||
17 | - vue(), | ||
18 | - // have to | ||
19 | - vueJsx(), | ||
20 | - ]; | 21 | +async function createPlugins({ isBuild, root, enableMock, compress, enableAnalyze }: Options) { |
22 | + const vitePlugins: (PluginOption | PluginOption[])[] = [vue(), vueJsx()]; | ||
23 | + | ||
24 | + const appConfigPlugin = await createAppConfigPlugin({ root, isBuild }); | ||
25 | + vitePlugins.push(appConfigPlugin); | ||
21 | 26 | ||
22 | // vite-plugin-windicss | 27 | // vite-plugin-windicss |
23 | vitePlugins.push(windiCSS()); | 28 | vitePlugins.push(windiCSS()); |
24 | 29 | ||
25 | // vite-plugin-html | 30 | // vite-plugin-html |
26 | - vitePlugins.push(configHtmlPlugin(viteEnv, isBuild)); | 31 | + vitePlugins.push(configHtmlPlugin({ isBuild })); |
27 | 32 | ||
28 | // vite-plugin-svg-icons | 33 | // vite-plugin-svg-icons |
29 | - vitePlugins.push(configSvgIconsPlugin(isBuild)); | ||
30 | - | ||
31 | - // vite-plugin-mock | ||
32 | - VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild)); | 34 | + vitePlugins.push(configSvgIconsPlugin({ isBuild })); |
33 | 35 | ||
34 | // vite-plugin-purge-icons | 36 | // vite-plugin-purge-icons |
35 | vitePlugins.push(purgeIcons()); | 37 | vitePlugins.push(purgeIcons()); |
36 | 38 | ||
37 | - // rollup-plugin-visualizer | ||
38 | - vitePlugins.push(configVisualizerConfig()); | ||
39 | - | ||
40 | // The following plugins only work in the production environment | 39 | // The following plugins only work in the production environment |
41 | if (isBuild) { | 40 | if (isBuild) { |
42 | // rollup-plugin-gzip | 41 | // rollup-plugin-gzip |
43 | vitePlugins.push( | 42 | vitePlugins.push( |
44 | - configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE), | 43 | + configCompressPlugin({ |
44 | + compress, | ||
45 | + }), | ||
45 | ); | 46 | ); |
46 | } | 47 | } |
47 | 48 | ||
49 | + // rollup-plugin-visualizer | ||
50 | + if (enableAnalyze) { | ||
51 | + vitePlugins.push(configVisualizerConfig()); | ||
52 | + } | ||
53 | + | ||
54 | + // vite-plugin-mock | ||
55 | + if (enableMock) { | ||
56 | + vitePlugins.push(configMockPlugin({ isBuild })); | ||
57 | + } | ||
58 | + | ||
48 | return vitePlugins; | 59 | return vitePlugins; |
49 | } | 60 | } |
61 | + | ||
62 | +export { createPlugins }; |
build/vite/plugin/mock.ts renamed to internal/vite-config/src/plugins/mock.ts
@@ -4,7 +4,7 @@ | @@ -4,7 +4,7 @@ | ||
4 | */ | 4 | */ |
5 | import { viteMockServe } from 'vite-plugin-mock'; | 5 | import { viteMockServe } from 'vite-plugin-mock'; |
6 | 6 | ||
7 | -export function configMockPlugin(isBuild: boolean) { | 7 | +export function configMockPlugin({ isBuild }: { isBuild: boolean }) { |
8 | return viteMockServe({ | 8 | return viteMockServe({ |
9 | ignore: /^_/, | 9 | ignore: /^_/, |
10 | mockPath: 'mock', | 10 | mockPath: 'mock', |
build/vite/plugin/svgSprite.ts renamed to internal/vite-config/src/plugins/svgSprite.ts
@@ -4,15 +4,13 @@ | @@ -4,15 +4,13 @@ | ||
4 | */ | 4 | */ |
5 | 5 | ||
6 | import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; | 6 | import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; |
7 | -import path from 'path'; | 7 | +import { resolve } from 'node:path'; |
8 | import type { PluginOption } from 'vite'; | 8 | import type { PluginOption } from 'vite'; |
9 | 9 | ||
10 | -export function configSvgIconsPlugin(isBuild: boolean) { | 10 | +export function configSvgIconsPlugin({ isBuild }: { isBuild: boolean }) { |
11 | const svgIconsPlugin = createSvgIconsPlugin({ | 11 | const svgIconsPlugin = createSvgIconsPlugin({ |
12 | - iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], | 12 | + iconDirs: [resolve(process.cwd(), 'src/assets/icons')], |
13 | svgoOptions: isBuild, | 13 | svgoOptions: isBuild, |
14 | - // default | ||
15 | - symbolId: 'icon-[dir]-[name]', | ||
16 | }); | 14 | }); |
17 | return svgIconsPlugin as PluginOption; | 15 | return svgIconsPlugin as PluginOption; |
18 | } | 16 | } |
build/vite/plugin/visualizer.ts renamed to internal/vite-config/src/plugins/visualizer.ts
1 | /** | 1 | /** |
2 | * Package file volume analysis | 2 | * Package file volume analysis |
3 | */ | 3 | */ |
4 | +import { type PluginOption } from 'vite'; | ||
4 | import visualizer from 'rollup-plugin-visualizer'; | 5 | import visualizer from 'rollup-plugin-visualizer'; |
5 | 6 | ||
6 | export function configVisualizerConfig() { | 7 | export function configVisualizerConfig() { |
7 | - if (process.env.REPORT === 'true') { | ||
8 | - return visualizer({ | ||
9 | - filename: './node_modules/.cache/visualizer/stats.html', | ||
10 | - open: true, | ||
11 | - gzipSize: true, | ||
12 | - brotliSize: true, | ||
13 | - }) as Plugin; | ||
14 | - } | ||
15 | - return []; | 8 | + return visualizer({ |
9 | + filename: './node_modules/.cache/visualizer/stats.html', | ||
10 | + open: true, | ||
11 | + gzipSize: true, | ||
12 | + brotliSize: true, | ||
13 | + }) as PluginOption; | ||
16 | } | 14 | } |
build/utils.ts renamed to internal/vite-config/src/utils/env.ts
1 | -import fs from 'fs'; | ||
2 | -import path from 'path'; | ||
3 | import dotenv from 'dotenv'; | 1 | import dotenv from 'dotenv'; |
4 | - | ||
5 | -// Read all environment variable configuration files to process.env | ||
6 | -export function wrapperEnv(envConf: Recordable): ViteEnv { | ||
7 | - const ret: any = {}; | ||
8 | - | ||
9 | - for (const envName of Object.keys(envConf)) { | ||
10 | - let realName = envConf[envName].replace(/\\n/g, '\n'); | ||
11 | - realName = realName === 'true' ? true : realName === 'false' ? false : realName; | ||
12 | - if (envName === 'VITE_PROXY' && realName) { | ||
13 | - try { | ||
14 | - realName = JSON.parse(realName.replace(/'/g, '"')); | ||
15 | - } catch (error) { | ||
16 | - realName = ''; | ||
17 | - } | ||
18 | - } | ||
19 | - ret[envName] = realName; | ||
20 | - // if (typeof realName === 'string') { | ||
21 | - // process.env[envName] = realName; | ||
22 | - // } else if (typeof realName === 'object') { | ||
23 | - // process.env[envName] = JSON.stringify(realName); | ||
24 | - // } | ||
25 | - } | ||
26 | - return ret; | ||
27 | -} | 2 | +import { readFile } from 'fs-extra'; |
3 | +import { join } from 'node:path'; | ||
28 | 4 | ||
29 | /** | 5 | /** |
30 | * 获取当前环境下生效的配置文件名 | 6 | * 获取当前环境下生效的配置文件名 |
31 | */ | 7 | */ |
32 | function getConfFiles() { | 8 | function getConfFiles() { |
33 | - const script = process.env.npm_lifecycle_script; | 9 | + const script = process.env.npm_lifecycle_script as string; |
34 | const reg = new RegExp('--mode ([a-z_\\d]+)'); | 10 | const reg = new RegExp('--mode ([a-z_\\d]+)'); |
35 | - const result = reg.exec(script as string) as any; | 11 | + const result = reg.exec(script); |
36 | if (result) { | 12 | if (result) { |
37 | - const mode = result[1] as string; | 13 | + const mode = result[1]; |
38 | return ['.env', `.env.${mode}`]; | 14 | return ['.env', `.env.${mode}`]; |
39 | } | 15 | } |
40 | return ['.env', '.env.production']; | 16 | return ['.env', '.env.production']; |
@@ -45,16 +21,18 @@ function getConfFiles() { | @@ -45,16 +21,18 @@ function getConfFiles() { | ||
45 | * @param match prefix | 21 | * @param match prefix |
46 | * @param confFiles ext | 22 | * @param confFiles ext |
47 | */ | 23 | */ |
48 | -export function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { | 24 | +export async function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { |
49 | let envConfig = {}; | 25 | let envConfig = {}; |
50 | - confFiles.forEach((item) => { | 26 | + |
27 | + for (const confFile of confFiles) { | ||
51 | try { | 28 | try { |
52 | - const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item))); | 29 | + const envPath = await readFile(join(process.cwd(), confFile), { encoding: 'utf8' }); |
30 | + const env = dotenv.parse(envPath); | ||
53 | envConfig = { ...envConfig, ...env }; | 31 | envConfig = { ...envConfig, ...env }; |
54 | } catch (e) { | 32 | } catch (e) { |
55 | - console.error(`Error in parsing ${item}`, e); | 33 | + console.error(`Error in parsing ${confFile}`, e); |
56 | } | 34 | } |
57 | - }); | 35 | + } |
58 | const reg = new RegExp(`^(${match})`); | 36 | const reg = new RegExp(`^(${match})`); |
59 | Object.keys(envConfig).forEach((key) => { | 37 | Object.keys(envConfig).forEach((key) => { |
60 | if (!reg.test(key)) { | 38 | if (!reg.test(key)) { |
@@ -63,11 +41,3 @@ export function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { | @@ -63,11 +41,3 @@ export function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { | ||
63 | }); | 41 | }); |
64 | return envConfig; | 42 | return envConfig; |
65 | } | 43 | } |
66 | - | ||
67 | -/** | ||
68 | - * Get user root directory | ||
69 | - * @param dir file path | ||
70 | - */ | ||
71 | -export function getRootPath(...dir: string[]) { | ||
72 | - return path.resolve(process.cwd(), ...dir); | ||
73 | -} |
internal/vite-config/src/utils/hash.ts
0 → 100644
build/generate/generateModifyVars.ts renamed to internal/vite-config/src/utils/modifyVars.ts
1 | -import { generateAntColors, primaryColor } from '../config/themeConfig'; | 1 | +import { generate } from '@ant-design/colors'; |
2 | +import { resolve } from 'node:path'; | ||
3 | +// @ts-ignore | ||
2 | import { getThemeVariables } from 'ant-design-vue/dist/theme'; | 4 | import { getThemeVariables } from 'ant-design-vue/dist/theme'; |
3 | -import { resolve } from 'path'; | 5 | + |
6 | +const primaryColor = '#0960bd'; | ||
7 | + | ||
8 | +function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') { | ||
9 | + return generate(color, { | ||
10 | + theme, | ||
11 | + }); | ||
12 | +} | ||
4 | 13 | ||
5 | /** | 14 | /** |
6 | * less global variable | 15 | * less global variable |
7 | */ | 16 | */ |
8 | -export function generateModifyVars(dark = false) { | 17 | +export function generateModifyVars() { |
9 | const palettes = generateAntColors(primaryColor); | 18 | const palettes = generateAntColors(primaryColor); |
10 | const primary = palettes[5]; | 19 | const primary = palettes[5]; |
11 | 20 | ||
@@ -15,10 +24,9 @@ export function generateModifyVars(dark = false) { | @@ -15,10 +24,9 @@ export function generateModifyVars(dark = false) { | ||
15 | primaryColorObj[`primary-${index + 1}`] = palettes[index]; | 24 | primaryColorObj[`primary-${index + 1}`] = palettes[index]; |
16 | } | 25 | } |
17 | 26 | ||
18 | - const modifyVars = getThemeVariables({ dark }); | 27 | + const modifyVars = getThemeVariables(); |
19 | return { | 28 | return { |
20 | ...modifyVars, | 29 | ...modifyVars, |
21 | - // Used for global import to avoid the need to import each style file separately | ||
22 | // reference: Avoid repeated references | 30 | // reference: Avoid repeated references |
23 | hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`, | 31 | hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`, |
24 | 'primary-color': primary, | 32 | 'primary-color': primary, |
@@ -28,7 +36,6 @@ export function generateModifyVars(dark = false) { | @@ -28,7 +36,6 @@ export function generateModifyVars(dark = false) { | ||
28 | 'success-color': '#55D187', // Success color | 36 | 'success-color': '#55D187', // Success color |
29 | 'error-color': '#ED6F6F', // False color | 37 | 'error-color': '#ED6F6F', // False color |
30 | 'warning-color': '#EFBD47', // Warning color | 38 | 'warning-color': '#EFBD47', // Warning color |
31 | - //'border-color-base': '#EEEEEE', | ||
32 | 'font-size-base': '14px', // Main font size | 39 | 'font-size-base': '14px', // Main font size |
33 | 'border-radius-base': '2px', // Component/float fillet | 40 | 'border-radius-base': '2px', // Component/float fillet |
34 | 'link-color': primary, // Link color | 41 | 'link-color': primary, // Link color |
internal/vite-config/tsconfig.json
0 → 100644
package.json
1 | { | 1 | { |
2 | "name": "vben-admin", | 2 | "name": "vben-admin", |
3 | "version": "2.9.0", | 3 | "version": "2.9.0", |
4 | - "homepage": "https://github.com/anncwb/vue-vben-admin", | 4 | + "homepage": "https://github.com/vbenjs/vue-vben-admin", |
5 | "bugs": { | 5 | "bugs": { |
6 | - "url": "https://github.com/anncwb/vue-vben-admin/issues" | 6 | + "url": "https://github.com/vbenjs/vue-vben-admin/issues" |
7 | }, | 7 | }, |
8 | "repository": { | 8 | "repository": { |
9 | "type": "git", | 9 | "type": "git", |
10 | - "url": "git+https://github.com/anncwb/vue-vben-admin.git" | 10 | + "url": "git+https://github.com/vbenjs/vue-vben-admin.git" |
11 | }, | 11 | }, |
12 | "license": "MIT", | 12 | "license": "MIT", |
13 | "author": { | 13 | "author": { |
@@ -17,29 +17,23 @@ | @@ -17,29 +17,23 @@ | ||
17 | }, | 17 | }, |
18 | "scripts": { | 18 | "scripts": { |
19 | "bootstrap": "pnpm install", | 19 | "bootstrap": "pnpm install", |
20 | - "build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 NODE_ENV=production vite build && esno ./build/script/postBuild.ts", | 20 | + "build": "NODE_ENV=production pnpm vite build", |
21 | + "build:analyze": "pnpm vite build --mode analyze", | ||
21 | "build:no-cache": "pnpm clean:cache && npm run build", | 22 | "build:no-cache": "pnpm clean:cache && npm run build", |
22 | - "build:test": "cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build --mode test && esno ./build/script/postBuild.ts", | ||
23 | - "clean:cache": "rimraf node_modules/.cache/ && rimraf node_modules/.vite", | ||
24 | - "clean:lib": "rimraf node_modules", | 23 | + "build:test": "pnpm vite build --mode test", |
25 | "commit": "czg", | 24 | "commit": "czg", |
26 | - "dev": "vite", | ||
27 | - "gen:icon": "esno ./build/generate/icon/index.ts", | 25 | + "dev": "pnpm vite", |
28 | "preinstall": "npx only-allow pnpm", | 26 | "preinstall": "npx only-allow pnpm", |
29 | "postinstall": "turbo run stub", | 27 | "postinstall": "turbo run stub", |
30 | "lint": "turbo run lint", | 28 | "lint": "turbo run lint", |
31 | "lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", | 29 | "lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix", |
32 | - "lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"", | 30 | + "lint:prettier": "prettier --write .", |
33 | "lint:stylelint": "stylelint \"**/*.{vue,css,less.scss}\" --fix --cache --cache-location node_modules/.cache/stylelint/", | 31 | "lint:stylelint": "stylelint \"**/*.{vue,css,less.scss}\" --fix --cache --cache-location node_modules/.cache/stylelint/", |
34 | "prepare": "husky install", | 32 | "prepare": "husky install", |
35 | "preview": "npm run build && vite preview", | 33 | "preview": "npm run build && vite preview", |
36 | - "preview:dist": "vite preview", | ||
37 | "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap", | 34 | "reinstall": "rimraf pnpm-lock.yaml && rimraf package.lock.json && rimraf node_modules && npm run bootstrap", |
38 | - "report": "cross-env REPORT=true npm run build", | ||
39 | "serve": "npm run dev", | 35 | "serve": "npm run dev", |
40 | - "test:br": "npx http-server dist --cors --brotli -c-1", | ||
41 | "test:gzip": "npx http-server dist --cors --gzip -c-1", | 36 | "test:gzip": "npx http-server dist --cors --gzip -c-1", |
42 | - "test:unit": "jest", | ||
43 | "type:check": "vue-tsc --noEmit --skipLibCheck" | 37 | "type:check": "vue-tsc --noEmit --skipLibCheck" |
44 | }, | 38 | }, |
45 | "lint-staged": { | 39 | "lint-staged": { |
@@ -82,7 +76,7 @@ | @@ -82,7 +76,7 @@ | ||
82 | "@vueuse/core": "^9.13.0", | 76 | "@vueuse/core": "^9.13.0", |
83 | "@vueuse/shared": "^9.13.0", | 77 | "@vueuse/shared": "^9.13.0", |
84 | "@zxcvbn-ts/core": "^2.2.1", | 78 | "@zxcvbn-ts/core": "^2.2.1", |
85 | - "ant-design-vue": "^3.2.16", | 79 | + "ant-design-vue": "^3.2.17", |
86 | "axios": "^1.3.4", | 80 | "axios": "^1.3.4", |
87 | "codemirror": "^5.65.12", | 81 | "codemirror": "^5.65.12", |
88 | "cropperjs": "^1.5.13", | 82 | "cropperjs": "^1.5.13", |
@@ -121,12 +115,9 @@ | @@ -121,12 +115,9 @@ | ||
121 | "@purge-icons/generated": "^0.9.0", | 115 | "@purge-icons/generated": "^0.9.0", |
122 | "@types/codemirror": "^5.60.7", | 116 | "@types/codemirror": "^5.60.7", |
123 | "@types/crypto-js": "^4.1.1", | 117 | "@types/crypto-js": "^4.1.1", |
124 | - "@types/fs-extra": "^11.0.1", | ||
125 | - "@types/inquirer": "^8.2.6", | ||
126 | "@types/intro.js": "^5.1.1", | 118 | "@types/intro.js": "^5.1.1", |
127 | "@types/lodash-es": "^4.17.7", | 119 | "@types/lodash-es": "^4.17.7", |
128 | "@types/mockjs": "^1.0.7", | 120 | "@types/mockjs": "^1.0.7", |
129 | - "@types/node": "^18.15.11", | ||
130 | "@types/nprogress": "^0.2.0", | 121 | "@types/nprogress": "^0.2.0", |
131 | "@types/qrcode": "^1.5.0", | 122 | "@types/qrcode": "^1.5.0", |
132 | "@types/qs": "^6.9.7", | 123 | "@types/qs": "^6.9.7", |
@@ -135,6 +126,7 @@ | @@ -135,6 +126,7 @@ | ||
135 | "@vben/eslint-config": "workspace:*", | 126 | "@vben/eslint-config": "workspace:*", |
136 | "@vben/stylelint-config": "workspace:*", | 127 | "@vben/stylelint-config": "workspace:*", |
137 | "@vben/ts-config": "workspace:*", | 128 | "@vben/ts-config": "workspace:*", |
129 | + "@vben/vite-config": "workspace:*", | ||
138 | "@vitejs/plugin-vue": "^4.1.0", | 130 | "@vitejs/plugin-vue": "^4.1.0", |
139 | "@vitejs/plugin-vue-jsx": "^3.0.1", | 131 | "@vitejs/plugin-vue-jsx": "^3.0.1", |
140 | "@vue/compiler-sfc": "^3.2.47", | 132 | "@vue/compiler-sfc": "^3.2.47", |
@@ -142,32 +134,16 @@ | @@ -142,32 +134,16 @@ | ||
142 | "cross-env": "^7.0.3", | 134 | "cross-env": "^7.0.3", |
143 | "cz-git": "^1.6.1", | 135 | "cz-git": "^1.6.1", |
144 | "czg": "^1.6.1", | 136 | "czg": "^1.6.1", |
145 | - "dotenv": "^16.0.3", | ||
146 | - "esno": "^0.16.3", | ||
147 | - "fs-extra": "^11.1.1", | ||
148 | "husky": "^8.0.3", | 137 | "husky": "^8.0.3", |
149 | - "inquirer": "^9.1.5", | ||
150 | - "less": "^4.1.3", | ||
151 | "lint-staged": "13.2.0", | 138 | "lint-staged": "13.2.0", |
152 | - "picocolors": "^1.0.0", | ||
153 | - "postcss": "^8.4.21", | ||
154 | - "postcss-html": "^1.5.0", | ||
155 | - "postcss-less": "^6.0.0", | ||
156 | "prettier": "^2.8.7", | 139 | "prettier": "^2.8.7", |
157 | "prettier-plugin-packagejson": "^2.4.3", | 140 | "prettier-plugin-packagejson": "^2.4.3", |
158 | "rimraf": "^4.4.1", | 141 | "rimraf": "^4.4.1", |
159 | - "rollup-plugin-visualizer": "^5.9.0", | ||
160 | - "sass": "^1.60.0", | ||
161 | "turbo": "^1.8.8", | 142 | "turbo": "^1.8.8", |
162 | "typescript": "^5.0.3", | 143 | "typescript": "^5.0.3", |
163 | "unbuild": "^1.2.0", | 144 | "unbuild": "^1.2.0", |
164 | "vite": "^4.3.0-beta.1", | 145 | "vite": "^4.3.0-beta.1", |
165 | - "vite-plugin-compression": "^0.5.1", | ||
166 | - "vite-plugin-html": "^3.2.0", | ||
167 | "vite-plugin-mock": "^2.9.6", | 146 | "vite-plugin-mock": "^2.9.6", |
168 | - "vite-plugin-purge-icons": "^0.9.2", | ||
169 | - "vite-plugin-svg-icons": "^2.0.1", | ||
170 | - "vite-plugin-windicss": "^1.8.10", | ||
171 | "vue-tsc": "^1.2.0" | 147 | "vue-tsc": "^1.2.0" |
172 | }, | 148 | }, |
173 | "packageManager": "pnpm@8.1.0", | 149 | "packageManager": "pnpm@8.1.0", |