mirror of
https://gitee.com/bootx/dax-pay-ui.git
synced 2025-09-05 19:58:20 +00:00
perf: Refactor vite configuration
This commit is contained in:
@@ -2,6 +2,15 @@
|
||||
"name": "@vben/eslint-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/eslint-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": {
|
||||
|
@@ -2,6 +2,15 @@
|
||||
"name": "@vben/stylelint-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/stylelint-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
".": {
|
||||
|
18
internal/ts-config/node-server.json
Normal file
18
internal/ts-config/node-server.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"display": "Node Server Config",
|
||||
"extends": "./base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"declaration": false,
|
||||
"removeComments": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es6",
|
||||
"sourceMap": false,
|
||||
"esModuleInterop": true,
|
||||
"outDir": "./dist",
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
}
|
@@ -4,9 +4,9 @@
|
||||
"extends": "./base.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"types": ["vite/client"],
|
||||
"noImplicitAny": true,
|
||||
"sourceMap": true,
|
||||
"noEmit": true
|
||||
"noEmit": true,
|
||||
"baseUrl": "./"
|
||||
}
|
||||
}
|
||||
|
@@ -2,11 +2,23 @@
|
||||
"name": "@vben/ts-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/ts-config"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"base.json",
|
||||
"node.json",
|
||||
"vue.json"
|
||||
"vue.json",
|
||||
"node-server.json"
|
||||
],
|
||||
"devDependencies": {}
|
||||
"dependencies": {
|
||||
"@types/node": "^18.15.11"
|
||||
}
|
||||
}
|
||||
|
107
internal/vite-config/.commitlintrc.js
Normal file
107
internal/vite-config/.commitlintrc.js
Normal file
@@ -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: 自定义',
|
||||
},
|
||||
};
|
15
internal/vite-config/.eslintignore
Normal file
15
internal/vite-config/.eslintignore
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
*.sh
|
||||
node_modules
|
||||
*.md
|
||||
*.woff
|
||||
*.ttf
|
||||
.vscode
|
||||
.idea
|
||||
dist
|
||||
/public
|
||||
/docs
|
||||
.husky
|
||||
.local
|
||||
/bin
|
||||
Dockerfile
|
4
internal/vite-config/.eslintrc.js
Normal file
4
internal/vite-config/.eslintrc.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@vben'],
|
||||
};
|
10
internal/vite-config/.prettierignore
Normal file
10
internal/vite-config/.prettierignore
Normal file
@@ -0,0 +1,10 @@
|
||||
dist
|
||||
.local
|
||||
.output.js
|
||||
node_modules
|
||||
|
||||
**/*.svg
|
||||
**/*.sh
|
||||
|
||||
public
|
||||
.npmrc
|
19
internal/vite-config/.prettierrc.js
Normal file
19
internal/vite-config/.prettierrc.js
Normal file
@@ -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',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
2
internal/vite-config/.stylelintignore
Normal file
2
internal/vite-config/.stylelintignore
Normal file
@@ -0,0 +1,2 @@
|
||||
dist
|
||||
public
|
4
internal/vite-config/.stylelintrc.js
Normal file
4
internal/vite-config/.stylelintrc.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@vben/stylelint-config'],
|
||||
};
|
10
internal/vite-config/build.config.ts
Normal file
10
internal/vite-config/build.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
|
||||
export default defineBuildConfig({
|
||||
clean: true,
|
||||
entries: ['src/index'],
|
||||
declaration: true,
|
||||
rollup: {
|
||||
emitCJS: true,
|
||||
},
|
||||
});
|
54
internal/vite-config/package.json
Normal file
54
internal/vite-config/package.json
Normal file
@@ -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"
|
||||
}
|
||||
}
|
116
internal/vite-config/src/config/application.ts
Normal file
116
internal/vite-config/src/config/application.ts
Normal file
@@ -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 };
|
20
internal/vite-config/src/config/common.ts
Normal file
20
internal/vite-config/src/config/common.ts
Normal file
@@ -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 };
|
5
internal/vite-config/src/config/package.ts
Normal file
5
internal/vite-config/src/config/package.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
function definePackageConfig() {
|
||||
// TODO:
|
||||
}
|
||||
|
||||
export { definePackageConfig };
|
1
internal/vite-config/src/index.ts
Normal file
1
internal/vite-config/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './config/application';
|
94
internal/vite-config/src/plugins/appConfig.ts
Normal file
94
internal/vite-config/src/plugins/appConfig.ts
Normal file
@@ -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 };
|
38
internal/vite-config/src/plugins/compress.ts
Normal file
38
internal/vite-config/src/plugins/compress.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
|
||||
* https://github.com/anncwb/vite-plugin-compression
|
||||
*/
|
||||
import type { PluginOption } from 'vite';
|
||||
import compressPlugin from 'vite-plugin-compression';
|
||||
|
||||
export function configCompressPlugin({
|
||||
compress,
|
||||
deleteOriginFile = false,
|
||||
}: {
|
||||
compress: string;
|
||||
deleteOriginFile?: boolean;
|
||||
}): PluginOption[] {
|
||||
const compressList = compress.split(',');
|
||||
|
||||
const plugins: PluginOption[] = [];
|
||||
|
||||
if (compressList.includes('gzip')) {
|
||||
plugins.push(
|
||||
compressPlugin({
|
||||
ext: '.gz',
|
||||
deleteOriginFile,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (compressList.includes('brotli')) {
|
||||
plugins.push(
|
||||
compressPlugin({
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
deleteOriginFile,
|
||||
}),
|
||||
);
|
||||
}
|
||||
return plugins;
|
||||
}
|
13
internal/vite-config/src/plugins/html.ts
Normal file
13
internal/vite-config/src/plugins/html.ts
Normal file
@@ -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;
|
||||
}
|
62
internal/vite-config/src/plugins/index.ts
Normal file
62
internal/vite-config/src/plugins/index.ts
Normal file
@@ -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 };
|
19
internal/vite-config/src/plugins/mock.ts
Normal file
19
internal/vite-config/src/plugins/mock.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Mock plugin for development and production.
|
||||
* https://github.com/anncwb/vite-plugin-mock
|
||||
*/
|
||||
import { viteMockServe } from 'vite-plugin-mock';
|
||||
|
||||
export function configMockPlugin({ isBuild }: { isBuild: boolean }) {
|
||||
return viteMockServe({
|
||||
ignore: /^_/,
|
||||
mockPath: 'mock',
|
||||
localEnabled: !isBuild,
|
||||
prodEnabled: isBuild,
|
||||
injectCode: `
|
||||
import { setupProdMockServer } from '../mock/_createProductionServer';
|
||||
|
||||
setupProdMockServer();
|
||||
`,
|
||||
});
|
||||
}
|
16
internal/vite-config/src/plugins/svgSprite.ts
Normal file
16
internal/vite-config/src/plugins/svgSprite.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Vite Plugin for fast creating SVG sprites.
|
||||
* https://github.com/anncwb/vite-plugin-svg-icons
|
||||
*/
|
||||
|
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
|
||||
import { resolve } from 'node:path';
|
||||
import type { PluginOption } from 'vite';
|
||||
|
||||
export function configSvgIconsPlugin({ isBuild }: { isBuild: boolean }) {
|
||||
const svgIconsPlugin = createSvgIconsPlugin({
|
||||
iconDirs: [resolve(process.cwd(), 'src/assets/icons')],
|
||||
svgoOptions: isBuild,
|
||||
});
|
||||
return svgIconsPlugin as PluginOption;
|
||||
}
|
14
internal/vite-config/src/plugins/visualizer.ts
Normal file
14
internal/vite-config/src/plugins/visualizer.ts
Normal file
@@ -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;
|
||||
}
|
43
internal/vite-config/src/utils/env.ts
Normal file
43
internal/vite-config/src/utils/env.ts
Normal file
@@ -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;
|
||||
}
|
8
internal/vite-config/src/utils/hash.ts
Normal file
8
internal/vite-config/src/utils/hash.ts
Normal file
@@ -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 };
|
44
internal/vite-config/src/utils/modifyVars.ts
Normal file
44
internal/vite-config/src/utils/modifyVars.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { generate } from '@ant-design/colors';
|
||||
import { resolve } from 'node:path';
|
||||
// @ts-ignore
|
||||
import { getThemeVariables } from 'ant-design-vue/dist/theme';
|
||||
|
||||
const primaryColor = '#0960bd';
|
||||
|
||||
function generateAntColors(color: string, theme: 'default' | 'dark' = 'default') {
|
||||
return generate(color, {
|
||||
theme,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* less global variable
|
||||
*/
|
||||
export function generateModifyVars() {
|
||||
const palettes = generateAntColors(primaryColor);
|
||||
const primary = palettes[5];
|
||||
|
||||
const primaryColorObj: Record<string, string> = {};
|
||||
|
||||
for (let index = 0; index < 10; index++) {
|
||||
primaryColorObj[`primary-${index + 1}`] = palettes[index];
|
||||
}
|
||||
|
||||
const modifyVars = getThemeVariables();
|
||||
return {
|
||||
...modifyVars,
|
||||
// reference: Avoid repeated references
|
||||
hack: `${modifyVars.hack} @import (reference) "${resolve('src/design/config.less')}";`,
|
||||
'primary-color': primary,
|
||||
...primaryColorObj,
|
||||
'info-color': primary,
|
||||
'processing-color': primary,
|
||||
'success-color': '#55D187', // Success color
|
||||
'error-color': '#ED6F6F', // False color
|
||||
'warning-color': '#EFBD47', // Warning color
|
||||
'font-size-base': '14px', // Main font size
|
||||
'border-radius-base': '2px', // Component/float fillet
|
||||
'link-color': primary, // Link color
|
||||
'app-content-background': '#fafafa', // Link color
|
||||
};
|
||||
}
|
5
internal/vite-config/tsconfig.json
Normal file
5
internal/vite-config/tsconfig.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/ts-config/node.json",
|
||||
"include": ["src"]
|
||||
}
|
Reference in New Issue
Block a user