68 changed files with 2441 additions and 3989 deletions
@ -0,0 +1,23 @@ |
|||||
|
# Whether to open mock |
||||
|
VITE_USE_MOCK = true |
||||
|
|
||||
|
# public path |
||||
|
VITE_PUBLIC_PATH = / |
||||
|
|
||||
|
# Whether to enable gzip or brotli compression |
||||
|
# Optional: gzip | brotli | none |
||||
|
# If you need multiple forms, you can use `,` to separate |
||||
|
VITE_BUILD_COMPRESS = 'none' |
||||
|
|
||||
|
|
||||
|
# Basic interface address SPA |
||||
|
VITE_GLOB_API_URL=/basic-api |
||||
|
|
||||
|
# File upload address, optional |
||||
|
# It can be forwarded by nginx or write the actual address directly |
||||
|
VITE_GLOB_UPLOAD_URL=/upload |
||||
|
|
||||
|
# Interface prefix |
||||
|
VITE_GLOB_API_URL_PREFIX= |
||||
|
|
||||
|
VITE_ENABLE_ANALYZE = true |
||||
@ -0,0 +1,7 @@ |
|||||
|
{ |
||||
|
"$schema": "https://json.schemastore.org/tsconfig", |
||||
|
"extends": "@vben/ts-config/node-server.json", |
||||
|
"compilerOptions": { |
||||
|
"noImplicitAny": false |
||||
|
} |
||||
|
} |
||||
@ -1,79 +0,0 @@ |
|||||
import { generate } from '@ant-design/colors'; |
|
||||
|
|
||||
export const primaryColor = '#0960bd'; |
|
||||
|
|
||||
export const darkMode = 'light'; |
|
||||
|
|
||||
type Fn = (...arg: any) => any; |
|
||||
|
|
||||
type GenerateTheme = 'default' | 'dark'; |
|
||||
|
|
||||
export interface GenerateColorsParams { |
|
||||
mixLighten: Fn; |
|
||||
mixDarken: Fn; |
|
||||
tinycolor: any; |
|
||||
color?: string; |
|
||||
} |
|
||||
|
|
||||
export function generateAntColors(color: string, theme: GenerateTheme = 'default') { |
|
||||
return generate(color, { |
|
||||
theme, |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
export function getThemeColors(color?: string) { |
|
||||
const tc = color || primaryColor; |
|
||||
const lightColors = generateAntColors(tc); |
|
||||
const primary = lightColors[5]; |
|
||||
const modeColors = generateAntColors(primary, 'dark'); |
|
||||
|
|
||||
return [...lightColors, ...modeColors]; |
|
||||
} |
|
||||
|
|
||||
export function generateColors({ |
|
||||
color = primaryColor, |
|
||||
mixLighten, |
|
||||
mixDarken, |
|
||||
tinycolor, |
|
||||
}: GenerateColorsParams) { |
|
||||
const arr = new Array(19).fill(0); |
|
||||
const lightens = arr.map((_t, i) => { |
|
||||
return mixLighten(color, i / 5); |
|
||||
}); |
|
||||
|
|
||||
const darkens = arr.map((_t, i) => { |
|
||||
return mixDarken(color, i / 5); |
|
||||
}); |
|
||||
|
|
||||
const alphaColors = arr.map((_t, i) => { |
|
||||
return tinycolor(color) |
|
||||
.setAlpha(i / 20) |
|
||||
.toRgbString(); |
|
||||
}); |
|
||||
|
|
||||
const shortAlphaColors = alphaColors.map((item) => item.replace(/\s/g, '').replace(/0\./g, '.')); |
|
||||
|
|
||||
const tinycolorLightens = arr |
|
||||
.map((_t, i) => { |
|
||||
return tinycolor(color) |
|
||||
.lighten(i * 5) |
|
||||
.toHexString(); |
|
||||
}) |
|
||||
.filter((item) => item !== '#ffffff'); |
|
||||
|
|
||||
const tinycolorDarkens = arr |
|
||||
.map((_t, i) => { |
|
||||
return tinycolor(color) |
|
||||
.darken(i * 5) |
|
||||
.toHexString(); |
|
||||
}) |
|
||||
.filter((item) => item !== '#000000'); |
|
||||
return [ |
|
||||
...lightens, |
|
||||
...darkens, |
|
||||
...alphaColors, |
|
||||
...shortAlphaColors, |
|
||||
...tinycolorDarkens, |
|
||||
...tinycolorLightens, |
|
||||
].filter((item) => !item.includes('-')); |
|
||||
} |
|
||||
@ -1,6 +0,0 @@ |
|||||
/** |
|
||||
* The name of the configuration file entered in the production environment |
|
||||
*/ |
|
||||
export const GLOB_CONFIG_FILE_NAME = '_app.config.js'; |
|
||||
|
|
||||
export const OUTPUT_DIR = 'dist'; |
|
||||
@ -1,72 +0,0 @@ |
|||||
import path from 'path'; |
|
||||
import fs from 'fs-extra'; |
|
||||
import inquirer from 'inquirer'; |
|
||||
import colors from 'picocolors'; |
|
||||
import pkg from '../../../package.json'; |
|
||||
|
|
||||
async function generateIcon() { |
|
||||
const dir = path.resolve(process.cwd(), 'node_modules/@iconify/json'); |
|
||||
|
|
||||
const raw = await fs.readJSON(path.join(dir, 'collections.json')); |
|
||||
|
|
||||
const collections = Object.entries(raw).map(([id, v]) => ({ |
|
||||
...(v as any), |
|
||||
id, |
|
||||
})); |
|
||||
|
|
||||
const choices = collections.map((item) => ({ key: item.id, value: item.id, name: item.name })); |
|
||||
|
|
||||
inquirer |
|
||||
.prompt([ |
|
||||
{ |
|
||||
type: 'list', |
|
||||
name: 'useType', |
|
||||
choices: [ |
|
||||
{ key: 'local', value: 'local', name: 'Local' }, |
|
||||
{ key: 'onLine', value: 'onLine', name: 'OnLine' }, |
|
||||
], |
|
||||
message: 'How to use icons?', |
|
||||
}, |
|
||||
{ |
|
||||
type: 'list', |
|
||||
name: 'iconSet', |
|
||||
choices: choices, |
|
||||
message: 'Select the icon set that needs to be generated?', |
|
||||
}, |
|
||||
{ |
|
||||
type: 'input', |
|
||||
name: 'output', |
|
||||
message: 'Select the icon set that needs to be generated?', |
|
||||
default: 'src/components/Icon/data', |
|
||||
}, |
|
||||
]) |
|
||||
.then(async (answers) => { |
|
||||
const { iconSet, output, useType } = answers; |
|
||||
const outputDir = path.resolve(process.cwd(), output); |
|
||||
fs.ensureDir(outputDir); |
|
||||
const genCollections = collections.filter((item) => [iconSet].includes(item.id)); |
|
||||
const prefixSet: string[] = []; |
|
||||
for (const info of genCollections) { |
|
||||
const data = await fs.readJSON(path.join(dir, 'json', `${info.id}.json`)); |
|
||||
if (data) { |
|
||||
const { prefix } = data; |
|
||||
const isLocal = useType === 'local'; |
|
||||
const icons = Object.keys(data.icons).map( |
|
||||
(item) => `${isLocal ? prefix + ':' : ''}${item}`, |
|
||||
); |
|
||||
|
|
||||
await fs.writeFileSync( |
|
||||
path.join(output, `icons.data.ts`), |
|
||||
`export default ${isLocal ? JSON.stringify(icons) : JSON.stringify({ prefix, icons })}`, |
|
||||
); |
|
||||
prefixSet.push(prefix); |
|
||||
} |
|
||||
} |
|
||||
fs.emptyDir(path.join(process.cwd(), 'node_modules/.vite')); |
|
||||
console.log( |
|
||||
`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - Icon generated successfully:' + `[${prefixSet}]`, |
|
||||
); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
generateIcon(); |
|
||||
@ -1,9 +0,0 @@ |
|||||
/** |
|
||||
* Get the configuration file variable name |
|
||||
* @param env |
|
||||
*/ |
|
||||
export const getConfigFileName = (env: Record<string, any>) => { |
|
||||
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__` |
|
||||
.toUpperCase() |
|
||||
.replace(/\s/g, ''); |
|
||||
}; |
|
||||
@ -1,47 +0,0 @@ |
|||||
/** |
|
||||
* 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 |
|
||||
*/ |
|
||||
import { GLOB_CONFIG_FILE_NAME, OUTPUT_DIR } from '../constant'; |
|
||||
import fs, { writeFileSync } from 'fs-extra'; |
|
||||
import colors from 'picocolors'; |
|
||||
|
|
||||
import { getEnvConfig, getRootPath } from '../utils'; |
|
||||
import { getConfigFileName } from '../getConfigFileName'; |
|
||||
|
|
||||
import pkg from '../../package.json'; |
|
||||
|
|
||||
interface CreateConfigParams { |
|
||||
configName: string; |
|
||||
config: any; |
|
||||
configFileName?: string; |
|
||||
} |
|
||||
|
|
||||
function createConfig(params: CreateConfigParams) { |
|
||||
const { configName, config, configFileName } = params; |
|
||||
try { |
|
||||
const windowConf = `window.${configName}`; |
|
||||
// Ensure that the variable will not be modified
|
|
||||
let configStr = `${windowConf}=${JSON.stringify(config)};`; |
|
||||
configStr += ` |
|
||||
Object.freeze(${windowConf}); |
|
||||
Object.defineProperty(window, "${configName}", { |
|
||||
configurable: false, |
|
||||
writable: false, |
|
||||
}); |
|
||||
`.replace(/\s/g, '');
|
|
||||
|
|
||||
fs.mkdirp(getRootPath(OUTPUT_DIR)); |
|
||||
writeFileSync(getRootPath(`${OUTPUT_DIR}/${configFileName}`), configStr); |
|
||||
|
|
||||
console.log(colors.cyan(`✨ [${pkg.name}]`) + ` - configuration file is build successfully:`); |
|
||||
console.log(colors.gray(OUTPUT_DIR + '/' + colors.green(configFileName)) + '\n'); |
|
||||
} catch (error) { |
|
||||
console.log(colors.red('configuration file configuration file failed to package:\n' + error)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
export function runBuildConfig() { |
|
||||
const config = getEnvConfig(); |
|
||||
const configFileName = getConfigFileName(config); |
|
||||
createConfig({ config, configName: configFileName, configFileName: GLOB_CONFIG_FILE_NAME }); |
|
||||
} |
|
||||
@ -1,23 +0,0 @@ |
|||||
// #!/usr/bin/env node
|
|
||||
|
|
||||
import { runBuildConfig } from './buildConf'; |
|
||||
import colors from 'picocolors'; |
|
||||
|
|
||||
import pkg from '../../package.json'; |
|
||||
|
|
||||
export const runBuild = async () => { |
|
||||
try { |
|
||||
const argvList = process.argv.splice(2); |
|
||||
|
|
||||
// Generate configuration file
|
|
||||
if (!argvList.includes('disabled-config')) { |
|
||||
runBuildConfig(); |
|
||||
} |
|
||||
|
|
||||
console.log(`✨ ${colors.cyan(`[${pkg.name}]`)}` + ' - build successfully!'); |
|
||||
} catch (error) { |
|
||||
console.log(colors.red('vite build error:\n' + error)); |
|
||||
process.exit(1); |
|
||||
} |
|
||||
}; |
|
||||
runBuild(); |
|
||||
@ -1,73 +0,0 @@ |
|||||
import fs from 'fs'; |
|
||||
import path from 'path'; |
|
||||
import dotenv from 'dotenv'; |
|
||||
|
|
||||
// Read all environment variable configuration files to process.env
|
|
||||
export function wrapperEnv(envConf: Recordable): ViteEnv { |
|
||||
const ret: any = {}; |
|
||||
|
|
||||
for (const envName of Object.keys(envConf)) { |
|
||||
let realName = envConf[envName].replace(/\\n/g, '\n'); |
|
||||
realName = realName === 'true' ? true : realName === 'false' ? false : realName; |
|
||||
if (envName === 'VITE_PROXY' && realName) { |
|
||||
try { |
|
||||
realName = JSON.parse(realName.replace(/'/g, '"')); |
|
||||
} catch (error) { |
|
||||
realName = ''; |
|
||||
} |
|
||||
} |
|
||||
ret[envName] = realName; |
|
||||
// if (typeof realName === 'string') {
|
|
||||
// process.env[envName] = realName;
|
|
||||
// } else if (typeof realName === 'object') {
|
|
||||
// process.env[envName] = JSON.stringify(realName);
|
|
||||
// }
|
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 获取当前环境下生效的配置文件名 |
|
||||
*/ |
|
||||
function getConfFiles() { |
|
||||
const script = process.env.npm_lifecycle_script; |
|
||||
const reg = new RegExp('--mode ([a-z_\\d]+)'); |
|
||||
const result = reg.exec(script as string) as any; |
|
||||
if (result) { |
|
||||
const mode = result[1] as string; |
|
||||
return ['.env', `.env.${mode}`]; |
|
||||
} |
|
||||
return ['.env', '.env.production']; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Get the environment variables starting with the specified prefix |
|
||||
* @param match prefix |
|
||||
* @param confFiles ext |
|
||||
*/ |
|
||||
export function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { |
|
||||
let envConfig = {}; |
|
||||
confFiles.forEach((item) => { |
|
||||
try { |
|
||||
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item))); |
|
||||
envConfig = { ...envConfig, ...env }; |
|
||||
} catch (e) { |
|
||||
console.error(`Error in parsing ${item}`, e); |
|
||||
} |
|
||||
}); |
|
||||
const reg = new RegExp(`^(${match})`); |
|
||||
Object.keys(envConfig).forEach((key) => { |
|
||||
if (!reg.test(key)) { |
|
||||
Reflect.deleteProperty(envConfig, key); |
|
||||
} |
|
||||
}); |
|
||||
return envConfig; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Get user root directory |
|
||||
* @param dir file path |
|
||||
*/ |
|
||||
export function getRootPath(...dir: string[]) { |
|
||||
return path.resolve(process.cwd(), ...dir); |
|
||||
} |
|
||||
@ -1,40 +0,0 @@ |
|||||
/** |
|
||||
* Plugin to minimize and use ejs template syntax in index.html. |
|
||||
* https://github.com/anncwb/vite-plugin-html
|
|
||||
*/ |
|
||||
import type { PluginOption } from 'vite'; |
|
||||
import { createHtmlPlugin } from 'vite-plugin-html'; |
|
||||
import pkg from '../../../package.json'; |
|
||||
import { GLOB_CONFIG_FILE_NAME } from '../../constant'; |
|
||||
|
|
||||
export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) { |
|
||||
const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env; |
|
||||
|
|
||||
const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`; |
|
||||
|
|
||||
const getAppConfigSrc = () => { |
|
||||
return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}`; |
|
||||
}; |
|
||||
|
|
||||
const htmlPlugin: PluginOption[] = createHtmlPlugin({ |
|
||||
minify: isBuild, |
|
||||
inject: { |
|
||||
// Inject data into ejs template
|
|
||||
data: { |
|
||||
title: VITE_GLOB_APP_TITLE, |
|
||||
}, |
|
||||
// Embed the generated app.config.js file
|
|
||||
tags: isBuild |
|
||||
? [ |
|
||||
{ |
|
||||
tag: 'script', |
|
||||
attrs: { |
|
||||
src: getAppConfigSrc(), |
|
||||
}, |
|
||||
}, |
|
||||
] |
|
||||
: [], |
|
||||
}, |
|
||||
}); |
|
||||
return htmlPlugin; |
|
||||
} |
|
||||
@ -1,49 +0,0 @@ |
|||||
import { PluginOption } from 'vite'; |
|
||||
import vue from '@vitejs/plugin-vue'; |
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'; |
|
||||
import purgeIcons from 'vite-plugin-purge-icons'; |
|
||||
import windiCSS from 'vite-plugin-windicss'; |
|
||||
import { configHtmlPlugin } from './html'; |
|
||||
import { configMockPlugin } from './mock'; |
|
||||
import { configCompressPlugin } from './compress'; |
|
||||
import { configVisualizerConfig } from './visualizer'; |
|
||||
import { configSvgIconsPlugin } from './svgSprite'; |
|
||||
|
|
||||
export async function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) { |
|
||||
const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv; |
|
||||
|
|
||||
const vitePlugins: (PluginOption | PluginOption[])[] = [ |
|
||||
// have to
|
|
||||
vue(), |
|
||||
// have to
|
|
||||
vueJsx(), |
|
||||
]; |
|
||||
|
|
||||
// vite-plugin-windicss
|
|
||||
vitePlugins.push(windiCSS()); |
|
||||
|
|
||||
// vite-plugin-html
|
|
||||
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild)); |
|
||||
|
|
||||
// vite-plugin-svg-icons
|
|
||||
vitePlugins.push(configSvgIconsPlugin(isBuild)); |
|
||||
|
|
||||
// vite-plugin-mock
|
|
||||
VITE_USE_MOCK && vitePlugins.push(configMockPlugin(isBuild)); |
|
||||
|
|
||||
// vite-plugin-purge-icons
|
|
||||
vitePlugins.push(purgeIcons()); |
|
||||
|
|
||||
// rollup-plugin-visualizer
|
|
||||
vitePlugins.push(configVisualizerConfig()); |
|
||||
|
|
||||
// The following plugins only work in the production environment
|
|
||||
if (isBuild) { |
|
||||
// rollup-plugin-gzip
|
|
||||
vitePlugins.push( |
|
||||
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE), |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
return vitePlugins; |
|
||||
} |
|
||||
@ -1,16 +0,0 @@ |
|||||
/** |
|
||||
* Package file volume analysis |
|
||||
*/ |
|
||||
import visualizer from 'rollup-plugin-visualizer'; |
|
||||
|
|
||||
export function configVisualizerConfig() { |
|
||||
if (process.env.REPORT === 'true') { |
|
||||
return visualizer({ |
|
||||
filename: './node_modules/.cache/visualizer/stats.html', |
|
||||
open: true, |
|
||||
gzipSize: true, |
|
||||
brotliSize: true, |
|
||||
}) as Plugin; |
|
||||
} |
|
||||
return []; |
|
||||
} |
|
||||
@ -1,34 +0,0 @@ |
|||||
/** |
|
||||
* Used to parse the .env.development proxy configuration |
|
||||
*/ |
|
||||
import type { ProxyOptions } from 'vite'; |
|
||||
|
|
||||
type ProxyItem = [string, string]; |
|
||||
|
|
||||
type ProxyList = ProxyItem[]; |
|
||||
|
|
||||
type ProxyTargetList = Record<string, ProxyOptions>; |
|
||||
|
|
||||
const httpsRE = /^https:\/\//; |
|
||||
|
|
||||
/** |
|
||||
* Generate proxy |
|
||||
* @param list |
|
||||
*/ |
|
||||
export function createProxy(list: ProxyList = []) { |
|
||||
const ret: ProxyTargetList = {}; |
|
||||
for (const [prefix, target] of list) { |
|
||||
const isHttps = httpsRE.test(target); |
|
||||
|
|
||||
// https://github.com/http-party/node-http-proxy#options
|
|
||||
ret[prefix] = { |
|
||||
target: target, |
|
||||
changeOrigin: true, |
|
||||
ws: true, |
|
||||
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''), |
|
||||
// https is require secure=false
|
|
||||
...(isHttps ? { secure: false } : {}), |
|
||||
}; |
|
||||
} |
|
||||
return ret; |
|
||||
} |
|
||||
@ -1,4 +1,7 @@ |
|||||
{ |
{ |
||||
|
"$schema": "https://json.schemastore.org/tsconfig", |
||||
|
"display": "Node Server Config", |
||||
|
"extends": "./base.json", |
||||
"compilerOptions": { |
"compilerOptions": { |
||||
"module": "commonjs", |
"module": "commonjs", |
||||
"declaration": false, |
"declaration": false, |
||||
@ -0,0 +1,107 @@ |
|||||
|
const fs = require('fs'); |
||||
|
const path = require('path'); |
||||
|
const { execSync } = require('child_process'); |
||||
|
|
||||
|
const scopes = fs |
||||
|
.readdirSync(path.resolve(__dirname, 'src'), { withFileTypes: true }) |
||||
|
.filter((dirent) => dirent.isDirectory()) |
||||
|
.map((dirent) => dirent.name.replace(/s$/, '')); |
||||
|
|
||||
|
// precomputed scope
|
||||
|
const scopeComplete = execSync('git status --porcelain || true') |
||||
|
.toString() |
||||
|
.trim() |
||||
|
.split('\n') |
||||
|
.find((r) => ~r.indexOf('M src')) |
||||
|
?.replace(/(\/)/g, '%%') |
||||
|
?.match(/src%%((\w|-)*)/)?.[1] |
||||
|
?.replace(/s$/, ''); |
||||
|
|
||||
|
/** @type {import('cz-git').UserConfig} */ |
||||
|
module.exports = { |
||||
|
ignores: [(commit) => commit.includes('init')], |
||||
|
extends: ['@commitlint/config-conventional'], |
||||
|
rules: { |
||||
|
'body-leading-blank': [2, 'always'], |
||||
|
'footer-leading-blank': [1, 'always'], |
||||
|
'header-max-length': [2, 'always', 108], |
||||
|
'subject-empty': [2, 'never'], |
||||
|
'type-empty': [2, 'never'], |
||||
|
'subject-case': [0], |
||||
|
'type-enum': [ |
||||
|
2, |
||||
|
'always', |
||||
|
[ |
||||
|
'feat', |
||||
|
'fix', |
||||
|
'perf', |
||||
|
'style', |
||||
|
'docs', |
||||
|
'test', |
||||
|
'refactor', |
||||
|
'build', |
||||
|
'ci', |
||||
|
'chore', |
||||
|
'revert', |
||||
|
'wip', |
||||
|
'workflow', |
||||
|
'types', |
||||
|
'release', |
||||
|
], |
||||
|
], |
||||
|
}, |
||||
|
prompt: { |
||||
|
/** @use `yarn commit :f` */ |
||||
|
alias: { |
||||
|
f: 'docs: fix typos', |
||||
|
r: 'docs: update README', |
||||
|
s: 'style: update code format', |
||||
|
b: 'build: bump dependencies', |
||||
|
c: 'chore: update config', |
||||
|
}, |
||||
|
customScopesAlign: !scopeComplete ? 'top' : 'bottom', |
||||
|
defaultScope: scopeComplete, |
||||
|
scopes: [...scopes, 'mock'], |
||||
|
allowEmptyIssuePrefixs: false, |
||||
|
allowCustomIssuePrefixs: false, |
||||
|
|
||||
|
// English
|
||||
|
typesAppend: [ |
||||
|
{ value: 'wip', name: 'wip: work in process' }, |
||||
|
{ value: 'workflow', name: 'workflow: workflow improvements' }, |
||||
|
{ value: 'types', name: 'types: type definition file changes' }, |
||||
|
], |
||||
|
|
||||
|
// 中英文对照版
|
||||
|
// messages: {
|
||||
|
// type: '选择你要提交的类型 :',
|
||||
|
// scope: '选择一个提交范围 (可选):',
|
||||
|
// customScope: '请输入自定义的提交范围 :',
|
||||
|
// subject: '填写简短精炼的变更描述 :\n',
|
||||
|
// body: '填写更加详细的变更描述 (可选)。使用 "|" 换行 :\n',
|
||||
|
// breaking: '列举非兼容性重大的变更 (可选)。使用 "|" 换行 :\n',
|
||||
|
// footerPrefixsSelect: '选择关联issue前缀 (可选):',
|
||||
|
// customFooterPrefixs: '输入自定义issue前缀 :',
|
||||
|
// footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
|
||||
|
// confirmCommit: '是否提交或修改commit ?',
|
||||
|
// },
|
||||
|
// types: [
|
||||
|
// { value: 'feat', name: 'feat: 新增功能' },
|
||||
|
// { value: 'fix', name: 'fix: 修复缺陷' },
|
||||
|
// { value: 'docs', name: 'docs: 文档变更' },
|
||||
|
// { value: 'style', name: 'style: 代码格式' },
|
||||
|
// { value: 'refactor', name: 'refactor: 代码重构' },
|
||||
|
// { value: 'perf', name: 'perf: 性能优化' },
|
||||
|
// { value: 'test', name: 'test: 添加疏漏测试或已有测试改动' },
|
||||
|
// { value: 'build', name: 'build: 构建流程、外部依赖变更 (如升级 npm 包、修改打包配置等)' },
|
||||
|
// { value: 'ci', name: 'ci: 修改 CI 配置、脚本' },
|
||||
|
// { value: 'revert', name: 'revert: 回滚 commit' },
|
||||
|
// { value: 'chore', name: 'chore: 对构建过程或辅助工具和库的更改 (不影响源文件、测试用例)' },
|
||||
|
// { value: 'wip', name: 'wip: 正在开发中' },
|
||||
|
// { value: 'workflow', name: 'workflow: 工作流程改进' },
|
||||
|
// { value: 'types', name: 'types: 类型定义文件修改' },
|
||||
|
// ],
|
||||
|
// emptyScopesAlias: 'empty: 不填写',
|
||||
|
// customScopesAlias: 'custom: 自定义',
|
||||
|
}, |
||||
|
}; |
||||
@ -0,0 +1,15 @@ |
|||||
|
|
||||
|
*.sh |
||||
|
node_modules |
||||
|
*.md |
||||
|
*.woff |
||||
|
*.ttf |
||||
|
.vscode |
||||
|
.idea |
||||
|
dist |
||||
|
/public |
||||
|
/docs |
||||
|
.husky |
||||
|
.local |
||||
|
/bin |
||||
|
Dockerfile |
||||
@ -0,0 +1,4 @@ |
|||||
|
module.exports = { |
||||
|
root: true, |
||||
|
extends: ['@vben'], |
||||
|
}; |
||||
@ -0,0 +1,10 @@ |
|||||
|
dist |
||||
|
.local |
||||
|
.output.js |
||||
|
node_modules |
||||
|
|
||||
|
**/*.svg |
||||
|
**/*.sh |
||||
|
|
||||
|
public |
||||
|
.npmrc |
||||
@ -0,0 +1,19 @@ |
|||||
|
module.exports = { |
||||
|
printWidth: 100, |
||||
|
semi: true, |
||||
|
vueIndentScriptAndStyle: true, |
||||
|
singleQuote: true, |
||||
|
trailingComma: 'all', |
||||
|
proseWrap: 'never', |
||||
|
htmlWhitespaceSensitivity: 'strict', |
||||
|
endOfLine: 'auto', |
||||
|
plugins: ['prettier-plugin-packagejson'], |
||||
|
overrides: [ |
||||
|
{ |
||||
|
files: '.*rc', |
||||
|
options: { |
||||
|
parser: 'json', |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
@ -0,0 +1,2 @@ |
|||||
|
dist |
||||
|
public |
||||
@ -0,0 +1,4 @@ |
|||||
|
module.exports = { |
||||
|
root: true, |
||||
|
extends: ['@vben/stylelint-config'], |
||||
|
}; |
||||
@ -0,0 +1,10 @@ |
|||||
|
import { defineBuildConfig } from 'unbuild'; |
||||
|
|
||||
|
export default defineBuildConfig({ |
||||
|
clean: true, |
||||
|
entries: ['src/index'], |
||||
|
declaration: true, |
||||
|
rollup: { |
||||
|
emitCJS: true, |
||||
|
}, |
||||
|
}); |
||||
@ -0,0 +1,54 @@ |
|||||
|
{ |
||||
|
"name": "@vben/vite-config", |
||||
|
"version": "1.0.0", |
||||
|
"private": true, |
||||
|
"homepage": "https://github.com/vbenjs/vue-vben-admin", |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/vbenjs/vue-vben-admin/issues" |
||||
|
}, |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/vbenjs/vue-vben-admin.git", |
||||
|
"directory": "internal/vite-config" |
||||
|
}, |
||||
|
"license": "MIT", |
||||
|
"exports": { |
||||
|
".": { |
||||
|
"types": "./dist/index.d.ts", |
||||
|
"import": "./dist/index.mjs", |
||||
|
"require": "./dist/index.cjs" |
||||
|
} |
||||
|
}, |
||||
|
"main": "./dist/index.cjs", |
||||
|
"module": "./dist/index.mjs", |
||||
|
"types": "./dist/index.d.ts", |
||||
|
"files": [ |
||||
|
"dist" |
||||
|
], |
||||
|
"scripts": { |
||||
|
"clean": "pnpm rimraf .turbo node_modules dist", |
||||
|
"lint": "pnpm eslint .", |
||||
|
"stub": "pnpm unbuild --stub" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"vite": "^4.3.0-beta.1" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@types/fs-extra": "^11.0.1", |
||||
|
"ant-design-vue": "^3.2.16", |
||||
|
"dayjs": "^1.11.7", |
||||
|
"dotenv": "^16.0.3", |
||||
|
"fs-extra": "^11.1.1", |
||||
|
"less": "^4.1.3", |
||||
|
"picocolors": "^1.0.0", |
||||
|
"pkg-types": "^1.0.2", |
||||
|
"rollup-plugin-visualizer": "^5.9.0", |
||||
|
"sass": "^1.60.0", |
||||
|
"vite-plugin-compression": "^0.5.1", |
||||
|
"vite-plugin-html": "^3.2.0", |
||||
|
"vite-plugin-mock": "^2.9.6", |
||||
|
"vite-plugin-purge-icons": "^0.9.2", |
||||
|
"vite-plugin-svg-icons": "^2.0.1", |
||||
|
"vite-plugin-windicss": "^1.8.10" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,116 @@ |
|||||
|
import { type UserConfig, defineConfig, mergeConfig, loadEnv } from 'vite'; |
||||
|
import { resolve } from 'node:path'; |
||||
|
import { readPackageJSON } from 'pkg-types'; |
||||
|
import { generateModifyVars } from '../utils/modifyVars'; |
||||
|
import { commonConfig } from './common'; |
||||
|
import { createPlugins } from '../plugins'; |
||||
|
import dayjs from 'dayjs'; |
||||
|
|
||||
|
interface DefineOptions { |
||||
|
overrides?: UserConfig; |
||||
|
options?: {}; |
||||
|
} |
||||
|
|
||||
|
function defineApplicationConfig(defineOptions: DefineOptions = {}) { |
||||
|
const { overrides = {} } = defineOptions; |
||||
|
|
||||
|
return defineConfig(async ({ command, mode }) => { |
||||
|
const root = process.cwd(); |
||||
|
const isBuild = command === 'build'; |
||||
|
const { VITE_USE_MOCK, VITE_BUILD_COMPRESS, VITE_ENABLE_ANALYZE } = loadEnv(mode, root); |
||||
|
|
||||
|
const defineData = await createDefineData(root); |
||||
|
const plugins = await createPlugins({ |
||||
|
isBuild, |
||||
|
root, |
||||
|
enableAnalyze: VITE_ENABLE_ANALYZE === 'true', |
||||
|
enableMock: VITE_USE_MOCK === 'true', |
||||
|
compress: VITE_BUILD_COMPRESS, |
||||
|
}); |
||||
|
|
||||
|
const pathResolve = (pathname: string) => resolve(root, '.', pathname); |
||||
|
|
||||
|
const applicationConfig: UserConfig = { |
||||
|
optimizeDeps: { |
||||
|
include: [ |
||||
|
'@iconify/iconify', |
||||
|
'ant-design-vue/es/locale/zh_CN', |
||||
|
'ant-design-vue/es/locale/en_US', |
||||
|
], |
||||
|
}, |
||||
|
resolve: { |
||||
|
alias: [ |
||||
|
{ |
||||
|
find: 'vue-i18n', |
||||
|
replacement: 'vue-i18n/dist/vue-i18n.cjs.js', |
||||
|
}, |
||||
|
// /@/xxxx => src/xxxx
|
||||
|
{ |
||||
|
find: /\/@\//, |
||||
|
replacement: pathResolve('src') + '/', |
||||
|
}, |
||||
|
// /#/xxxx => types/xxxx
|
||||
|
{ |
||||
|
find: /\/#\//, |
||||
|
replacement: pathResolve('types') + '/', |
||||
|
}, |
||||
|
// @/xxxx => src/xxxx
|
||||
|
{ |
||||
|
find: /@\//, |
||||
|
replacement: pathResolve('src') + '/', |
||||
|
}, |
||||
|
// #/xxxx => types/xxxx
|
||||
|
{ |
||||
|
find: /#\//, |
||||
|
replacement: pathResolve('types') + '/', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
define: defineData, |
||||
|
build: { |
||||
|
target: 'es2015', |
||||
|
cssTarget: 'chrome80', |
||||
|
rollupOptions: { |
||||
|
output: { |
||||
|
manualChunks: { |
||||
|
vue: ['vue', 'pinia', 'vue-router'], |
||||
|
antdv: ['ant-design-vue', '@ant-design/icons-vue'], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
css: { |
||||
|
preprocessorOptions: { |
||||
|
less: { |
||||
|
modifyVars: generateModifyVars(), |
||||
|
javascriptEnabled: true, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
plugins, |
||||
|
}; |
||||
|
|
||||
|
const mergedConfig = mergeConfig(commonConfig, applicationConfig); |
||||
|
|
||||
|
return mergeConfig(mergedConfig, overrides); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
async function createDefineData(root: string) { |
||||
|
try { |
||||
|
const pkgJson = await readPackageJSON(root); |
||||
|
const { dependencies, devDependencies, name, version } = pkgJson; |
||||
|
|
||||
|
const __APP_INFO__ = { |
||||
|
pkg: { dependencies, devDependencies, name, version }, |
||||
|
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
||||
|
}; |
||||
|
return { |
||||
|
__APP_INFO__: JSON.stringify(__APP_INFO__), |
||||
|
}; |
||||
|
} catch (error) { |
||||
|
return {}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export { defineApplicationConfig }; |
||||
@ -0,0 +1,20 @@ |
|||||
|
import { type UserConfig } from 'vite'; |
||||
|
|
||||
|
const commonConfig: UserConfig = { |
||||
|
server: { |
||||
|
host: true, |
||||
|
}, |
||||
|
esbuild: { |
||||
|
drop: ['console', 'debugger'], |
||||
|
}, |
||||
|
build: { |
||||
|
reportCompressedSize: false, |
||||
|
chunkSizeWarningLimit: 1500, |
||||
|
rollupOptions: { |
||||
|
// TODO: Prevent memory overflow
|
||||
|
maxParallelFileOps: 3, |
||||
|
}, |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export { commonConfig }; |
||||
@ -0,0 +1,5 @@ |
|||||
|
function definePackageConfig() { |
||||
|
// TODO:
|
||||
|
} |
||||
|
|
||||
|
export { definePackageConfig }; |
||||
@ -0,0 +1 @@ |
|||||
|
export * from './config/application'; |
||||
@ -0,0 +1,94 @@ |
|||||
|
import { type PluginOption } from 'vite'; |
||||
|
import { getEnvConfig } from '../utils/env'; |
||||
|
import { createContentHash } from '../utils/hash'; |
||||
|
import { readPackageJSON } from 'pkg-types'; |
||||
|
import colors from 'picocolors'; |
||||
|
|
||||
|
const GLOBAL_CONFIG_FILE_NAME = '_app.config.js'; |
||||
|
const PLUGIN_NAME = 'app-config'; |
||||
|
|
||||
|
async function createAppConfigPlugin({ |
||||
|
root, |
||||
|
isBuild, |
||||
|
}: { |
||||
|
root: string; |
||||
|
isBuild: boolean; |
||||
|
}): Promise<PluginOption> { |
||||
|
let publicPath: string; |
||||
|
let source: string; |
||||
|
if (!isBuild) { |
||||
|
return { |
||||
|
name: PLUGIN_NAME, |
||||
|
}; |
||||
|
} |
||||
|
const { version = '' } = await readPackageJSON(root); |
||||
|
|
||||
|
return { |
||||
|
name: PLUGIN_NAME, |
||||
|
async configResolved(_config) { |
||||
|
const appTitle = _config?.env?.VITE_GLOB_APP_SHORT_NAME ?? ''; |
||||
|
publicPath = _config.base; |
||||
|
source = await getConfigSource(appTitle); |
||||
|
}, |
||||
|
async transformIndexHtml(html) { |
||||
|
publicPath = publicPath.endsWith('/') ? publicPath : `${publicPath}/`; |
||||
|
|
||||
|
const appConfigSrc = `${ |
||||
|
publicPath || '/' |
||||
|
}${GLOBAL_CONFIG_FILE_NAME}?v=${version}-${createContentHash(source)}}`;
|
||||
|
|
||||
|
return { |
||||
|
html, |
||||
|
tags: [ |
||||
|
{ |
||||
|
tag: 'script', |
||||
|
attrs: { |
||||
|
src: appConfigSrc, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
}, |
||||
|
async generateBundle() { |
||||
|
try { |
||||
|
this.emitFile({ |
||||
|
type: 'asset', |
||||
|
fileName: GLOBAL_CONFIG_FILE_NAME, |
||||
|
source, |
||||
|
}); |
||||
|
|
||||
|
console.log(colors.cyan(`✨configuration file is build successfully!`)); |
||||
|
} catch (error) { |
||||
|
console.log( |
||||
|
colors.red('configuration file configuration file failed to package:\n' + error), |
||||
|
); |
||||
|
} |
||||
|
}, |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the configuration file variable name |
||||
|
* @param env |
||||
|
*/ |
||||
|
const getVariableName = (title: string) => { |
||||
|
return `__PRODUCTION__${title || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, ''); |
||||
|
}; |
||||
|
|
||||
|
async function getConfigSource(appTitle: string) { |
||||
|
const config = await getEnvConfig(); |
||||
|
const variableName = getVariableName(appTitle); |
||||
|
const windowVariable = `window.${variableName}`; |
||||
|
// Ensure that the variable will not be modified
|
||||
|
let source = `${windowVariable}=${JSON.stringify(config)};`; |
||||
|
source += ` |
||||
|
Object.freeze(${windowVariable}); |
||||
|
Object.defineProperty(window, "${variableName}", { |
||||
|
configurable: false, |
||||
|
writable: false, |
||||
|
}); |
||||
|
`.replace(/\s/g, '');
|
||||
|
return source; |
||||
|
} |
||||
|
|
||||
|
export { createAppConfigPlugin }; |
||||
@ -0,0 +1,13 @@ |
|||||
|
/** |
||||
|
* Plugin to minimize and use ejs template syntax in index.html. |
||||
|
* https://github.com/anncwb/vite-plugin-html
|
||||
|
*/ |
||||
|
import type { PluginOption } from 'vite'; |
||||
|
import { createHtmlPlugin } from 'vite-plugin-html'; |
||||
|
|
||||
|
export function configHtmlPlugin({ isBuild }: { isBuild: boolean }) { |
||||
|
const htmlPlugin: PluginOption[] = createHtmlPlugin({ |
||||
|
minify: isBuild, |
||||
|
}); |
||||
|
return htmlPlugin; |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
import { type PluginOption } from 'vite'; |
||||
|
import { configHtmlPlugin } from './html'; |
||||
|
import { configMockPlugin } from './mock'; |
||||
|
import { configCompressPlugin } from './compress'; |
||||
|
import { configVisualizerConfig } from './visualizer'; |
||||
|
import { configSvgIconsPlugin } from './svgSprite'; |
||||
|
import { createAppConfigPlugin } from './appConfig'; |
||||
|
import vue from '@vitejs/plugin-vue'; |
||||
|
import vueJsx from '@vitejs/plugin-vue-jsx'; |
||||
|
import purgeIcons from 'vite-plugin-purge-icons'; |
||||
|
import windiCSS from 'vite-plugin-windicss'; |
||||
|
|
||||
|
interface Options { |
||||
|
isBuild: boolean; |
||||
|
root: string; |
||||
|
compress: string; |
||||
|
enableMock?: boolean; |
||||
|
enableAnalyze?: boolean; |
||||
|
} |
||||
|
|
||||
|
async function createPlugins({ isBuild, root, enableMock, compress, enableAnalyze }: Options) { |
||||
|
const vitePlugins: (PluginOption | PluginOption[])[] = [vue(), vueJsx()]; |
||||
|
|
||||
|
const appConfigPlugin = await createAppConfigPlugin({ root, isBuild }); |
||||
|
vitePlugins.push(appConfigPlugin); |
||||
|
|
||||
|
// vite-plugin-windicss
|
||||
|
vitePlugins.push(windiCSS()); |
||||
|
|
||||
|
// vite-plugin-html
|
||||
|
vitePlugins.push(configHtmlPlugin({ isBuild })); |
||||
|
|
||||
|
// vite-plugin-svg-icons
|
||||
|
vitePlugins.push(configSvgIconsPlugin({ isBuild })); |
||||
|
|
||||
|
// vite-plugin-purge-icons
|
||||
|
vitePlugins.push(purgeIcons()); |
||||
|
|
||||
|
// The following plugins only work in the production environment
|
||||
|
if (isBuild) { |
||||
|
// rollup-plugin-gzip
|
||||
|
vitePlugins.push( |
||||
|
configCompressPlugin({ |
||||
|
compress, |
||||
|
}), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// rollup-plugin-visualizer
|
||||
|
if (enableAnalyze) { |
||||
|
vitePlugins.push(configVisualizerConfig()); |
||||
|
} |
||||
|
|
||||
|
// vite-plugin-mock
|
||||
|
if (enableMock) { |
||||
|
vitePlugins.push(configMockPlugin({ isBuild })); |
||||
|
} |
||||
|
|
||||
|
return vitePlugins; |
||||
|
} |
||||
|
|
||||
|
export { createPlugins }; |
||||
@ -0,0 +1,14 @@ |
|||||
|
/** |
||||
|
* Package file volume analysis |
||||
|
*/ |
||||
|
import { type PluginOption } from 'vite'; |
||||
|
import visualizer from 'rollup-plugin-visualizer'; |
||||
|
|
||||
|
export function configVisualizerConfig() { |
||||
|
return visualizer({ |
||||
|
filename: './node_modules/.cache/visualizer/stats.html', |
||||
|
open: true, |
||||
|
gzipSize: true, |
||||
|
brotliSize: true, |
||||
|
}) as PluginOption; |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
import dotenv from 'dotenv'; |
||||
|
import { readFile } from 'fs-extra'; |
||||
|
import { join } from 'node:path'; |
||||
|
|
||||
|
/** |
||||
|
* 获取当前环境下生效的配置文件名 |
||||
|
*/ |
||||
|
function getConfFiles() { |
||||
|
const script = process.env.npm_lifecycle_script as string; |
||||
|
const reg = new RegExp('--mode ([a-z_\\d]+)'); |
||||
|
const result = reg.exec(script); |
||||
|
if (result) { |
||||
|
const mode = result[1]; |
||||
|
return ['.env', `.env.${mode}`]; |
||||
|
} |
||||
|
return ['.env', '.env.production']; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the environment variables starting with the specified prefix |
||||
|
* @param match prefix |
||||
|
* @param confFiles ext |
||||
|
*/ |
||||
|
export async function getEnvConfig(match = 'VITE_GLOB_', confFiles = getConfFiles()) { |
||||
|
let envConfig = {}; |
||||
|
|
||||
|
for (const confFile of confFiles) { |
||||
|
try { |
||||
|
const envPath = await readFile(join(process.cwd(), confFile), { encoding: 'utf8' }); |
||||
|
const env = dotenv.parse(envPath); |
||||
|
envConfig = { ...envConfig, ...env }; |
||||
|
} catch (e) { |
||||
|
console.error(`Error in parsing ${confFile}`, e); |
||||
|
} |
||||
|
} |
||||
|
const reg = new RegExp(`^(${match})`); |
||||
|
Object.keys(envConfig).forEach((key) => { |
||||
|
if (!reg.test(key)) { |
||||
|
Reflect.deleteProperty(envConfig, key); |
||||
|
} |
||||
|
}); |
||||
|
return envConfig; |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
import { createHash } from 'node:crypto'; |
||||
|
|
||||
|
function createContentHash(content: string, hashLSize = 12) { |
||||
|
const hash = createHash('sha256').update(content); |
||||
|
return hash.digest('hex').slice(0, hashLSize); |
||||
|
} |
||||
|
|
||||
|
export { createContentHash }; |
||||
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"$schema": "https://json.schemastore.org/tsconfig", |
||||
|
"extends": "@vben/ts-config/node.json", |
||||
|
"include": ["src"] |
||||
|
} |
||||
File diff suppressed because it is too large
@ -1,3 +1,4 @@ |
|||||
packages: |
packages: |
||||
- 'internal/*' |
- 'internal/*' |
||||
- 'packages/*' |
- 'packages/*' |
||||
|
- 'apps/*' |
||||
|
|||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
File diff suppressed because it is too large
@ -1,95 +1,24 @@ |
|||||
import type { UserConfig, ConfigEnv } from 'vite'; |
import { defineApplicationConfig } from '@vben/vite-config'; |
||||
import pkg from './package.json'; |
|
||||
import dayjs from 'dayjs'; |
|
||||
import { loadEnv } from 'vite'; |
|
||||
import { resolve } from 'path'; |
|
||||
import { generateModifyVars } from './build/generate/generateModifyVars'; |
|
||||
import { createProxy } from './build/vite/proxy'; |
|
||||
import { wrapperEnv } from './build/utils'; |
|
||||
import { createVitePlugins } from './build/vite/plugin'; |
|
||||
import { OUTPUT_DIR } from './build/constant'; |
|
||||
|
|
||||
function pathResolve(dir: string) { |
export default defineApplicationConfig({ |
||||
return resolve(process.cwd(), '.', dir); |
overrides: { |
||||
} |
|
||||
|
|
||||
const { dependencies, devDependencies, name, version } = pkg; |
|
||||
const __APP_INFO__ = { |
|
||||
pkg: { dependencies, devDependencies, name, version }, |
|
||||
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
|
||||
}; |
|
||||
|
|
||||
export default async ({ command, mode }: ConfigEnv): Promise<UserConfig> => { |
|
||||
const root = process.cwd(); |
|
||||
|
|
||||
const env = loadEnv(mode, root); |
|
||||
|
|
||||
// The boolean type read by loadEnv is a string. This function can be converted to boolean type
|
|
||||
const viteEnv = wrapperEnv(env); |
|
||||
|
|
||||
const { VITE_PUBLIC_PATH, VITE_PROXY } = viteEnv; |
|
||||
|
|
||||
const isBuild = command === 'build'; |
|
||||
|
|
||||
return { |
|
||||
base: VITE_PUBLIC_PATH, |
|
||||
root, |
|
||||
resolve: { |
|
||||
alias: [ |
|
||||
{ |
|
||||
find: 'vue-i18n', |
|
||||
replacement: 'vue-i18n/dist/vue-i18n.cjs.js', |
|
||||
}, |
|
||||
// /@/xxxx => src/xxxx
|
|
||||
{ |
|
||||
find: /\/@\//, |
|
||||
replacement: pathResolve('src') + '/', |
|
||||
}, |
|
||||
// /#/xxxx => types/xxxx
|
|
||||
{ |
|
||||
find: /\/#\//, |
|
||||
replacement: pathResolve('types') + '/', |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
server: { |
server: { |
||||
host: true, |
proxy: { |
||||
// Load proxy configuration from .env
|
'/basic-api': { |
||||
proxy: createProxy(VITE_PROXY), |
target: 'http://localhost:3000', |
||||
}, |
changeOrigin: true, |
||||
esbuild: { |
ws: true, |
||||
drop: ['console', 'debugger'], |
rewrite: (path) => path.replace(new RegExp(`^/basic-api`), ''), |
||||
}, |
// only https
|
||||
build: { |
// secure: false
|
||||
target: 'es2015', |
}, |
||||
cssTarget: 'chrome80', |
'/upload': { |
||||
outDir: OUTPUT_DIR, |
target: 'http://localhost:3300/upload', |
||||
reportCompressedSize: false, |
changeOrigin: true, |
||||
chunkSizeWarningLimit: 2000, |
ws: true, |
||||
}, |
rewrite: (path) => path.replace(new RegExp(`^/upload`), ''), |
||||
define: { |
|
||||
__APP_INFO__: JSON.stringify(__APP_INFO__), |
|
||||
}, |
|
||||
|
|
||||
css: { |
|
||||
preprocessorOptions: { |
|
||||
less: { |
|
||||
modifyVars: generateModifyVars(), |
|
||||
javascriptEnabled: true, |
|
||||
}, |
}, |
||||
}, |
}, |
||||
}, |
}, |
||||
|
}, |
||||
// The vite plugin used by the project. The quantity is large, so it is separately extracted and managed
|
}); |
||||
plugins: await createVitePlugins(viteEnv, isBuild), |
|
||||
|
|
||||
optimizeDeps: { |
|
||||
// @iconify/iconify: The dependency is dynamically and virtually loaded by @purge-icons/generated, so it needs to be specified explicitly
|
|
||||
include: [ |
|
||||
'@iconify/iconify', |
|
||||
'ant-design-vue/es/locale/zh_CN', |
|
||||
'ant-design-vue/es/locale/en_US', |
|
||||
], |
|
||||
}, |
|
||||
}; |
|
||||
}; |
|
||||
|
|||||
Loading…
Reference in new issue