新增前端vue
This commit is contained in:
23
web-vue/packages/vite/README.md
Normal file
23
web-vue/packages/vite/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
- 官方网站:<https://jeesite.com>
|
||||
- 使用文档:<https://jeesite.com/docs>
|
||||
- 后端代码:<https://gitee.com/thinkgem/jeesite5>
|
||||
- 前端代码:<https://gitee.com/thinkgem/jeesite-vue>
|
||||
|
||||
------
|
||||
|
||||
<div align="center">
|
||||
如果你喜欢 JeeSite,请给她一个 ⭐️ Star,您的支持将是我们前行的动力。
|
||||
</div>
|
||||
|
||||
------
|
||||
|
||||
- 问题反馈:<https://gitee.com/thinkgem/jeesite-vue/issues> [【新手必读】](https://gitee.com/thinkgem/jeesite5/issues/I18ARR)
|
||||
- 需求收集:<https://gitee.com/thinkgem/jeesite-vue/issues/new>
|
||||
- QQ 群:`127515876`、`209330483`、`223507718`、`709534275`、`730390092`、`1373527`、`183903863(外包)`
|
||||
- 微信群:添加客服微信 <http://s.jeesite.com> 邀请您进群
|
||||
- 关注微信公众号,了解最新动态:
|
||||
|
||||
<p style="padding-left:40px">
|
||||
<img alt="JeeSite微信公众号" src="https://jeesite.com/assets/images/mp.png" width="220" height="220">
|
||||
</p>
|
||||
7
web-vue/packages/vite/build.config.ts
Normal file
7
web-vue/packages/vite/build.config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineBuildConfig } from 'unbuild';
|
||||
|
||||
export default defineBuildConfig({
|
||||
clean: true,
|
||||
declaration: true,
|
||||
entries: ['./index', './config/getEnvConfigName', './theme/themeConfig'],
|
||||
});
|
||||
78
web-vue/packages/vite/config/appConfig.ts
Normal file
78
web-vue/packages/vite/config/appConfig.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import { PackageJson } from 'pkg-types';
|
||||
import { getEnvConfig } from './index';
|
||||
import { getEnvConfigName } from './getEnvConfigName';
|
||||
import { version } from '../package.json';
|
||||
import colors from 'picocolors';
|
||||
|
||||
const PLUGIN_NAME = 'app-config';
|
||||
const APP_CONFIG_FILE_NAME = '_app.config.js';
|
||||
|
||||
export function appConfigPlugin(isBuild: boolean, viteEnv: ViteEnv): PluginOption {
|
||||
if (!isBuild) {
|
||||
return {
|
||||
name: PLUGIN_NAME,
|
||||
};
|
||||
}
|
||||
|
||||
let publicPath: string;
|
||||
let appConfigContent: string;
|
||||
|
||||
return {
|
||||
name: PLUGIN_NAME,
|
||||
async configResolved(_config) {
|
||||
publicPath = _config.base;
|
||||
appConfigContent = await getConfigContent(viteEnv);
|
||||
},
|
||||
async transformIndexHtml(html) {
|
||||
publicPath = (publicPath.endsWith('/') ? publicPath : `${publicPath}/`) || '/';
|
||||
const src = `${publicPath}${APP_CONFIG_FILE_NAME}?v=${version}-${new Date().getTime()}`;
|
||||
return { html, tags: [{ tag: 'script', attrs: { src } }] };
|
||||
},
|
||||
async generateBundle() {
|
||||
try {
|
||||
this.emitFile({
|
||||
type: 'asset',
|
||||
fileName: APP_CONFIG_FILE_NAME,
|
||||
source: appConfigContent,
|
||||
});
|
||||
this.emitFile({
|
||||
type: 'asset',
|
||||
fileName: 'timestamp.txt',
|
||||
source: `${new Date().getTime()}`,
|
||||
});
|
||||
console.log(colors.cyan(`✨configuration file is build successfully!`));
|
||||
} catch (error) {
|
||||
console.log(colors.red('configuration file configuration file failed to package:\n' + error));
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function getConfigContent(env: ViteEnv) {
|
||||
const config = await getEnvConfig();
|
||||
const envConfigName = getEnvConfigName(env);
|
||||
const windowVariable = `window.${envConfigName}`;
|
||||
// Ensure that the variable will not be modified
|
||||
let source = `${windowVariable}=${JSON.stringify(config)};`;
|
||||
source += `
|
||||
Object.freeze(${windowVariable});
|
||||
Object.defineProperty(window, "${envConfigName}", {
|
||||
configurable: false,
|
||||
writable: false,
|
||||
});
|
||||
var _hmt = _hmt || [];
|
||||
(function() {
|
||||
var hm = document.createElement("script");
|
||||
hm.src = "https://hm.baidu.com/hm.js?65b88e88a94e0118de2962f328f17622";
|
||||
var s = document.getElementsByTagName("script")[0];
|
||||
s.parentNode.insertBefore(hm, s);
|
||||
})();
|
||||
`.replace(/(?!var|\b)\s/g, '');
|
||||
return source;
|
||||
}
|
||||
8
web-vue/packages/vite/config/getEnvConfigName.ts
Normal file
8
web-vue/packages/vite/config/getEnvConfigName.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
export const getEnvConfigName = (env: Record<string, any>) => {
|
||||
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`.toUpperCase().replace(/\s/g, '');
|
||||
};
|
||||
75
web-vue/packages/vite/config/index.ts
Normal file
75
web-vue/packages/vite/config/index.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import fs from 'fs-extra';
|
||||
import dotenv from 'dotenv';
|
||||
import { join } from 'node:path';
|
||||
|
||||
// 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_PORT') {
|
||||
realName = Number(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 getEnvConfigFiles() {
|
||||
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 async function getEnvConfig(match = 'VITE_(GLOB|FILE)_', confFiles = getEnvConfigFiles()) {
|
||||
let envConfig = {};
|
||||
for (const item of confFiles) {
|
||||
try {
|
||||
const envPath = await fs.readFile(join(process.cwd(), item), { encoding: 'utf8' });
|
||||
const env = dotenv.parse(envPath);
|
||||
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;
|
||||
}
|
||||
8
web-vue/packages/vite/index.ts
Normal file
8
web-vue/packages/vite/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
export * from './config';
|
||||
export * from './options';
|
||||
export * from './plugins';
|
||||
42
web-vue/packages/vite/options/build.ts
Normal file
42
web-vue/packages/vite/options/build.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import type { BuildOptions } from 'vite';
|
||||
|
||||
// 现代浏览器支持列表 https://cn.vitejs.dev/config/build-options.html#build-target
|
||||
export const viteTarget = ['chrome107', 'edge107', 'firefox104', 'safari16'];
|
||||
// 低版本浏览器支持列表,VITE_LEGACY 参数开启时有效 https://www.npmjs.com/package/@vitejs/plugin-legacy
|
||||
export const legacyTargets = ['chrome>=87', 'edge>=88', 'firefox>=78', 'safari>=14'];
|
||||
|
||||
export function createBuildOptions(viteEnv: ViteEnv): BuildOptions {
|
||||
const timestamp = new Date().getTime();
|
||||
return {
|
||||
target: viteTarget,
|
||||
cssTarget: viteTarget,
|
||||
outDir: viteEnv.VITE_OUTPUT_DIR ?? 'dist',
|
||||
// 启用 terser 缩小器,当设置 terserOptions 时才会有效
|
||||
// minify: 'terser',
|
||||
// terserOptions: {
|
||||
// compress: {
|
||||
// keep_infinity: true,
|
||||
// drop_console: viteEnv.VITE_DROP_CONSOLE,
|
||||
// },
|
||||
// },
|
||||
// 禁用报告压缩块大小,可以稍微提高构建速度
|
||||
reportCompressedSize: false,
|
||||
chunkSizeWarningLimit: 9000,
|
||||
rollupOptions: {
|
||||
maxParallelFileOps: 50,
|
||||
output: {
|
||||
entryFileNames: `assets/[name]-[hash]-${timestamp}.js`,
|
||||
experimentalMinChunkSize: 12288,
|
||||
// manualChunks: {
|
||||
// vue: ['vue', 'vue-router'],
|
||||
// antd: ['ant-design-vue', '@ant-design/icons-vue'],
|
||||
// },
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
18
web-vue/packages/vite/options/css.ts
Normal file
18
web-vue/packages/vite/options/css.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import type { CSSOptions } from 'vite';
|
||||
import { generateModifyVars } from '../theme/modifyVars';
|
||||
|
||||
export function createCSSOptions(): CSSOptions {
|
||||
return {
|
||||
preprocessorOptions: {
|
||||
less: {
|
||||
modifyVars: generateModifyVars(),
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
43
web-vue/packages/vite/options/define.ts
Normal file
43
web-vue/packages/vite/options/define.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { PackageJson, readPackageJSON } from 'pkg-types';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
export async function createDefineOptions(): Promise<Record<string, any>> {
|
||||
const rootPkg: PackageJson = await readPackageJSON(process.cwd() + '/../');
|
||||
const buildPkg: PackageJson = await readPackageJSON(process.cwd() + '/../build');
|
||||
const corePkg: PackageJson = await readPackageJSON(process.cwd() + '/../packages/core');
|
||||
try {
|
||||
const __APP_INFO__ = {
|
||||
pkg: {
|
||||
dependencies: Object.fromEntries(
|
||||
Object.entries({
|
||||
...rootPkg.dependencies,
|
||||
...buildPkg.dependencies,
|
||||
...corePkg.dependencies,
|
||||
}).filter(([key]) => !key.endsWith('-lib')),
|
||||
),
|
||||
devDependencies: Object.fromEntries(
|
||||
Object.entries({
|
||||
...rootPkg.devDependencies,
|
||||
...buildPkg.devDependencies,
|
||||
...corePkg.devDependencies,
|
||||
}).filter(([key]) => !key.endsWith('-lib')),
|
||||
),
|
||||
name: rootPkg.name,
|
||||
version: rootPkg.version,
|
||||
},
|
||||
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||||
};
|
||||
return {
|
||||
// __INTLIFY_PROD_DEVTOOLS__: 'false',
|
||||
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||
};
|
||||
} catch (error) {
|
||||
console.log('createDefine', error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
12
web-vue/packages/vite/options/esBuild.ts
Normal file
12
web-vue/packages/vite/options/esBuild.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import type { ESBuildOptions } from 'vite';
|
||||
|
||||
export function createEsBuildOptions(viteEnv: ViteEnv): ESBuildOptions {
|
||||
return {
|
||||
drop: viteEnv.VITE_DROP_CONSOLE ? ['console', 'debugger'] : [],
|
||||
};
|
||||
}
|
||||
10
web-vue/packages/vite/options/index.ts
Normal file
10
web-vue/packages/vite/options/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
export * from './build';
|
||||
export * from './css';
|
||||
export * from './define';
|
||||
export * from './esBuild';
|
||||
export * from './server';
|
||||
50
web-vue/packages/vite/options/server.ts
Normal file
50
web-vue/packages/vite/options/server.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import type { ServerOptions, ProxyOptions } from 'vite';
|
||||
import { IncomingMessage } from 'node:http';
|
||||
|
||||
type ProxyItem = [string, string, boolean];
|
||||
type ProxyList = ProxyItem[];
|
||||
type ProxyTargetList = Record<string, ProxyOptions>;
|
||||
const httpsRE = /^https:\/\//;
|
||||
|
||||
export function createServerOptions(viteEnv: ViteEnv): ServerOptions {
|
||||
return {
|
||||
https: false as any,
|
||||
open: false,
|
||||
host: true,
|
||||
port: viteEnv.VITE_PORT,
|
||||
proxy: createProxy(viteEnv.VITE_PROXY),
|
||||
warmup: {
|
||||
clientFiles: ['./index.html', './src/{views,components}/*'],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to parse the .env.development proxy configuration
|
||||
*/
|
||||
export function createProxy(list: ProxyList = []) {
|
||||
const ret: ProxyTargetList = {};
|
||||
for (const [prefix, target, changeOrigin] of list) {
|
||||
const isHttps = httpsRE.test(target);
|
||||
// https://github.com/http-party/node-http-proxy#options
|
||||
ret[prefix] = {
|
||||
target: target,
|
||||
changeOrigin,
|
||||
ws: true,
|
||||
// https is require secure=false
|
||||
...(isHttps ? { secure: false } : {}),
|
||||
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
|
||||
bypass: (req: IncomingMessage) => {
|
||||
if (req.method === 'GET') {
|
||||
req['url'] = req['originalUrl'];
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
69
web-vue/packages/vite/package.json
Normal file
69
web-vue/packages/vite/package.json
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "@jeesite/vite",
|
||||
"version": "5.14.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"stub": "pnpm unbuild --stub",
|
||||
"type:check": "vue-tsc --noEmit --skipLibCheck",
|
||||
"lint:eslint": "eslint --cache --max-warnings 0 \"./**/*.{vue,ts,tsx}\" --fix",
|
||||
"lint:all": "pnpm type:check && pnpm lint:eslint",
|
||||
"uninstall": "rimraf node_modules",
|
||||
"update": "ncu -u"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"main": "./dist/index.mjs",
|
||||
"module": "./dist/index.mjs",
|
||||
"typings": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts"
|
||||
},
|
||||
"./config/getEnvConfigName": {
|
||||
"import": "./config/getEnvConfigName.ts",
|
||||
"types": "./config/getEnvConfigName.ts"
|
||||
},
|
||||
"./theme/themeConfig": {
|
||||
"import": "./theme/themeConfig.ts",
|
||||
"types": "./theme/themeConfig.ts"
|
||||
},
|
||||
"./dist/*": "./dist/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"picocolors": "1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@vitejs/plugin-legacy": "7.2.1",
|
||||
"@vitejs/plugin-vue": "6.0.1",
|
||||
"@vitejs/plugin-vue-jsx": "5.1.1",
|
||||
"dotenv": "17.2.3",
|
||||
"fs-extra": "11.3.2",
|
||||
"pkg-types": "2.3.0",
|
||||
"rollup-plugin-visualizer": "6.0.4",
|
||||
"unbuild": "3.6.1",
|
||||
"unocss": "66.5.3",
|
||||
"vite-plugin-compression": "0.5.1",
|
||||
"vite-plugin-html": "3.2.2",
|
||||
"vite-plugin-mkcert": "1.17.9",
|
||||
"vite-plugin-monaco-editor-esm": "2.0.2",
|
||||
"vite-plugin-theme-vite3": "2.0.1",
|
||||
"vite-plugin-vue-setup-extend": "0.4.0"
|
||||
},
|
||||
"homepage": "https://jeesite.com",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://gitee.com/thinkgem/jeesite-vue.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://gitee.com/thinkgem/jeesite-vue/issues"
|
||||
},
|
||||
"author": {
|
||||
"name": "ThinkGem",
|
||||
"email": "thinkgem@163.com",
|
||||
"url": "https://gitee.com/thinkgem"
|
||||
}
|
||||
}
|
||||
42
web-vue/packages/vite/plugins/compress.ts
Normal file
42
web-vue/packages/vite/plugins/compress.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import compressPlugin from 'vite-plugin-compression';
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
export function configCompressPlugin(isBuild: boolean, viteEnv: ViteEnv): PluginOption {
|
||||
if (!isBuild) {
|
||||
return [];
|
||||
}
|
||||
const plugins: PluginOption = [];
|
||||
const compress: 'gzip' | 'brotli' | 'none' = viteEnv.VITE_BUILD_COMPRESS;
|
||||
const deleteOriginFile = viteEnv.VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE || false;
|
||||
|
||||
const compressList = compress.split(',');
|
||||
|
||||
if (compressList.includes('gzip')) {
|
||||
plugins.push(
|
||||
compressPlugin({
|
||||
ext: '.gz',
|
||||
deleteOriginFile,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if (compressList.includes('brotli')) {
|
||||
plugins.push(
|
||||
compressPlugin({
|
||||
ext: '.br',
|
||||
algorithm: 'brotliCompress',
|
||||
deleteOriginFile,
|
||||
}),
|
||||
);
|
||||
}
|
||||
return plugins;
|
||||
}
|
||||
17
web-vue/packages/vite/plugins/html.ts
Normal file
17
web-vue/packages/vite/plugins/html.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import { createHtmlPlugin } from 'vite-plugin-html';
|
||||
|
||||
/**
|
||||
* Plugin to minimize and use ejs template syntax in index.html.
|
||||
* https://github.com/anncwb/vite-plugin-html
|
||||
*/
|
||||
export function configHtmlPlugin(isBuild: boolean): PluginOption {
|
||||
return createHtmlPlugin({
|
||||
minify: isBuild,
|
||||
});
|
||||
}
|
||||
66
web-vue/packages/vite/plugins/index.ts
Normal file
66
web-vue/packages/vite/plugins/index.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
|
||||
import vitePluginCertificate from 'vite-plugin-mkcert';
|
||||
import { appConfigPlugin } from '../config/appConfig';
|
||||
import { configCompressPlugin } from './compress';
|
||||
import { configHtmlPlugin } from './html';
|
||||
import { configLegacyPlugin } from './legacy';
|
||||
import { configThemePlugin } from '../theme';
|
||||
import { configUnoCSSPlugin } from './unocss';
|
||||
import { configMonacoEditorPlugin } from './monacoEditor';
|
||||
import { configVisualizerPlugin } from './visualizer';
|
||||
|
||||
export function createVitePlugins(isBuild: boolean, viteEnv: ViteEnv) {
|
||||
const vitePlugins: PluginOption[] = [
|
||||
vue(),
|
||||
vueJsx(),
|
||||
vueSetupExtend(),
|
||||
vitePluginCertificate({
|
||||
source: 'coding',
|
||||
}),
|
||||
];
|
||||
|
||||
// app-config-plugin
|
||||
vitePlugins.push(appConfigPlugin(isBuild, viteEnv));
|
||||
|
||||
// UnoCSS-vite-plugin
|
||||
vitePlugins.push(configUnoCSSPlugin());
|
||||
|
||||
// vite-plugin-html
|
||||
vitePlugins.push(configHtmlPlugin(isBuild));
|
||||
|
||||
// vite-plugin-monaco-editor
|
||||
vitePlugins.push(configMonacoEditorPlugin());
|
||||
|
||||
// rollup-plugin-visualizer
|
||||
vitePlugins.push(configVisualizerPlugin());
|
||||
|
||||
// vite-plugin-theme-vite3
|
||||
vitePlugins.push(configThemePlugin(isBuild));
|
||||
|
||||
// rollup-plugin-gzip
|
||||
vitePlugins.push(configCompressPlugin(isBuild, viteEnv));
|
||||
|
||||
// @vitejs/plugin-legacy
|
||||
vitePlugins.push(configLegacyPlugin(isBuild, viteEnv));
|
||||
|
||||
return vitePlugins;
|
||||
}
|
||||
|
||||
export {
|
||||
appConfigPlugin,
|
||||
configCompressPlugin,
|
||||
configHtmlPlugin,
|
||||
configLegacyPlugin,
|
||||
configThemePlugin,
|
||||
configUnoCSSPlugin,
|
||||
configMonacoEditorPlugin,
|
||||
configVisualizerPlugin,
|
||||
};
|
||||
18
web-vue/packages/vite/plugins/legacy.ts
Normal file
18
web-vue/packages/vite/plugins/legacy.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import legacy from '@vitejs/plugin-legacy';
|
||||
import { legacyTargets } from '../options/build';
|
||||
|
||||
export function configLegacyPlugin(isBuild: boolean, viteEnv: ViteEnv): PluginOption {
|
||||
if (!(isBuild && viteEnv.VITE_LEGACY)) {
|
||||
return [];
|
||||
}
|
||||
return legacy({
|
||||
targets: legacyTargets,
|
||||
modernPolyfills: true,
|
||||
});
|
||||
}
|
||||
15
web-vue/packages/vite/plugins/monacoEditor.ts
Normal file
15
web-vue/packages/vite/plugins/monacoEditor.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import type { PluginOption } from 'vite';
|
||||
import monacoEditorPlugin from 'vite-plugin-monaco-editor-esm';
|
||||
|
||||
export function configMonacoEditorPlugin(): PluginOption {
|
||||
return monacoEditorPlugin({
|
||||
languageWorkers: ['editorWorkerService', 'json', 'html'],
|
||||
customDistPath: (root, buildOutDir) => `${buildOutDir}/monaco`,
|
||||
publicPath: 'monaco',
|
||||
});
|
||||
}
|
||||
12
web-vue/packages/vite/plugins/unocss.ts
Normal file
12
web-vue/packages/vite/plugins/unocss.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import UnoCSS from 'unocss/vite';
|
||||
import UnoCSSConfig from '../../../uno.config';
|
||||
|
||||
export function configUnoCSSPlugin(): PluginOption {
|
||||
return UnoCSS(UnoCSSConfig);
|
||||
}
|
||||
23
web-vue/packages/vite/plugins/visualizer.ts
Normal file
23
web-vue/packages/vite/plugins/visualizer.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import visualizer from 'rollup-plugin-visualizer';
|
||||
|
||||
export function isReportMode(): boolean {
|
||||
return process.env.REPORT === 'true';
|
||||
}
|
||||
|
||||
export function configVisualizerPlugin(): PluginOption {
|
||||
if (!isReportMode()) {
|
||||
return [];
|
||||
}
|
||||
return visualizer({
|
||||
filename: './node_modules/.cache/visualizer/stats.html',
|
||||
open: true,
|
||||
gzipSize: true,
|
||||
brotliSize: true,
|
||||
});
|
||||
}
|
||||
122
web-vue/packages/vite/theme/index.ts
Normal file
122
web-vue/packages/vite/theme/index.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { type PluginOption } from 'vite';
|
||||
import path from 'path';
|
||||
import { viteThemePlugin, antdDarkThemePlugin } from 'vite-plugin-theme-vite3';
|
||||
import { mixLighten, mixDarken, tinycolor } from 'vite-plugin-theme-vite3/es/colorUtils';
|
||||
import { getThemeColors, generateColors } from './themeConfig';
|
||||
import { generateModifyVars } from './modifyVars';
|
||||
|
||||
/**
|
||||
* Vite plugin for website theme color switching
|
||||
* https://gitee.com/thinkgem/vite-plugin-theme-vite3
|
||||
*/
|
||||
export function configThemePlugin(isBuild: boolean): PluginOption[] {
|
||||
const colors = generateColors({
|
||||
mixDarken,
|
||||
mixLighten,
|
||||
tinycolor,
|
||||
});
|
||||
// console.log(
|
||||
// [...getThemeColors(), ...colors]
|
||||
// .map((e) => `<a style="background:${e}">${e}</a>`)
|
||||
// .join(' '),
|
||||
// );
|
||||
// 抽取出viteThemePlugin插件,下方会根据不同环境设置enforce
|
||||
const vite_theme_plugin = viteThemePlugin({
|
||||
injectClientPath: JSON.stringify(path.resolve(__dirname, '../node_modules/vite-plugin-theme-vite3/es/client')),
|
||||
resolveSelector: (s) => {
|
||||
s = s.trim();
|
||||
if (s.includes('const __vite__css = "')) {
|
||||
return s.replace(/(.*)const __vite__css = "/g, '');
|
||||
}
|
||||
return s;
|
||||
// switch (s) {
|
||||
// case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon':
|
||||
// return '.ant-steps-item-icon > .ant-steps-icon';
|
||||
// case '.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled)':
|
||||
// case '.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):hover':
|
||||
// case '.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled):active':
|
||||
// case '.ant-steps-item-icon > .ant-steps-icon':
|
||||
// case '.ant-select-item-option-selected:not(.ant-select-item-option-disabled)':
|
||||
// case '.ant-menu-item-selected':
|
||||
// case '.ant-drawer .jeesite-basic-drawer .ant-drawer-body':
|
||||
// case '.jeesite-basic-drawer-footer':
|
||||
// return s;
|
||||
// default:
|
||||
// // 按钮被重新定制过,需要过滤掉class防止覆盖
|
||||
// if (s.indexOf('.ant-btn') >= 0) {
|
||||
// return s;
|
||||
// }
|
||||
// }
|
||||
// return s.startsWith('[data-theme') ? s : `[data-theme] ${s}`;
|
||||
},
|
||||
colorVariables: [...getThemeColors(), ...colors],
|
||||
});
|
||||
//console.log('vite_theme_plugin:'+JSON.stringify(vite_theme_plugin));
|
||||
((vite_theme_plugin || []) as any[]).forEach(function (item) {
|
||||
//对vite:theme插件特殊配置
|
||||
if ('vite:theme' === item.name) {
|
||||
//console.log(item);
|
||||
// 打包时去除enforce: "post",vite 2.6.x适配,否则生成app-theme-style为空,
|
||||
// 因为 async transform(code, id) { 的code没有正确获取
|
||||
if (isBuild) {
|
||||
delete item.enforce;
|
||||
}
|
||||
//console.log(item);
|
||||
}
|
||||
});
|
||||
//console.log('vite_theme_plugin后:'+JSON.stringify(vite_theme_plugin));
|
||||
const plugin = [
|
||||
vite_theme_plugin,
|
||||
antdDarkThemePlugin({
|
||||
// preloadFiles: [
|
||||
// // path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.less'),
|
||||
// // path.resolve(process.cwd(), 'node_modules/ant-design-vue/dist/antd.dark.less'),
|
||||
// path.resolve(process.cwd(), 'src/design/index.less'),
|
||||
// ],
|
||||
// filter: (id) => (isBuild ? !id.endsWith('antd.less') : true),
|
||||
// extractCss: false,
|
||||
darkModifyVars: {
|
||||
...generateModifyVars(true),
|
||||
// 'text-color': '#c9d1d9',
|
||||
// 'primary-1': 'rgb(255 255 255 / 8%)',
|
||||
// 'text-color-base': '#c9d1d9',
|
||||
// 'component-background': '#151515',
|
||||
// 'heading-color': 'rgb(255 255 255 / 65%)',
|
||||
// // black: '#0e1117',
|
||||
// // #8b949e
|
||||
// 'text-color-secondary': '#8b949e',
|
||||
// 'border-color-base': '#303030',
|
||||
// // 'border-color-split': '#30363d',
|
||||
// 'item-active-bg': '#111b26',
|
||||
// // 'tree-node-selected-bg': '#11263c',
|
||||
// 'alert-success-border-color': '#274916',
|
||||
// 'alert-success-bg-color': '#162312',
|
||||
// 'alert-success-icon-color': '#49aa19',
|
||||
// 'alert-info-border-color': '#153450',
|
||||
// 'alert-info-bg-color': '#111b26',
|
||||
// 'alert-info-icon-color': '#177ddc',
|
||||
// 'alert-warning-border-color': '#594214',
|
||||
// 'alert-warning-bg-color': '#2b2111',
|
||||
// 'alert-warning-icon-color': '#d89614',
|
||||
// 'alert-error-border-color': '#58181c',
|
||||
// 'alert-error-bg-color': '#2a1215',
|
||||
// 'alert-error-icon-color': '#a61d24',
|
||||
'content-bg': '#141414',
|
||||
'content-bg-striped': '#1e1e1e',
|
||||
'button-cancel-color': '#c9d1d9',
|
||||
'button-cancel-bg-color': '#2d2d2d',
|
||||
'button-cancel-border-color': '#303030',
|
||||
'button-cancel-hover-color': '#c9d1d9',
|
||||
'button-cancel-hover-bg-color': '#4a4a4a',
|
||||
'button-cancel-hover-border-color': '#4a4a4a',
|
||||
'header-light-bottom-border-color': '#303030',
|
||||
},
|
||||
} as any),
|
||||
];
|
||||
return plugin as unknown as PluginOption[];
|
||||
}
|
||||
49
web-vue/packages/vite/theme/modifyVars.ts
Normal file
49
web-vue/packages/vite/theme/modifyVars.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { generateAntColors, primaryColor, darkPrimaryColor } from './themeConfig';
|
||||
// import { getThemeVariables } from 'ant-design-vue/dist/theme';
|
||||
|
||||
import { theme } from 'ant-design-vue';
|
||||
import convertLegacyToken from 'ant-design-vue/lib/theme/convertLegacyToken';
|
||||
|
||||
/**
|
||||
* less global variable
|
||||
*/
|
||||
export function generateModifyVars(dark = false) {
|
||||
const palettes = generateAntColors(primaryColor);
|
||||
const primary = dark ? darkPrimaryColor : palettes[5];
|
||||
|
||||
// const primaryColorObj: Record<string, string> = {};
|
||||
// for (let index = 0; index < 10; index++) {
|
||||
// primaryColorObj[`primary-${index + 1}`] = palettes[index];
|
||||
// }
|
||||
|
||||
// const modifyVars = getThemeVariables({ dark: false });
|
||||
const { darkAlgorithm, defaultAlgorithm, defaultSeed } = theme;
|
||||
const mapToken = dark ? darkAlgorithm(defaultSeed) : defaultAlgorithm(defaultSeed);
|
||||
const modifyVars = convertLegacyToken(mapToken);
|
||||
// const modifyVars = convertLegacyToken(mapToken);
|
||||
// !!dark && console.log('modifyVars', dark, modifyVars);
|
||||
|
||||
return {
|
||||
...modifyVars,
|
||||
// Used for global import to avoid the need to import each style file separately
|
||||
// reference: Avoid repeated references
|
||||
// hack: `${modifyVars.hack} @import (reference) "${__dirname + '/../../core/design/var/index.less'}";`,
|
||||
hack: `true; @import (reference) "${__dirname + '/../../core/design/var/index.less'}";`,
|
||||
// ...primaryColorObj,
|
||||
'primary-color': primary,
|
||||
'link-color': primary,
|
||||
'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
|
||||
// 'content-bg-striped': '#fafafa',
|
||||
};
|
||||
}
|
||||
84
web-vue/packages/vite/theme/themeConfig.ts
Normal file
84
web-vue/packages/vite/theme/themeConfig.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
|
||||
* No deletion without permission, or be held responsible to law.
|
||||
* @author ThinkGem
|
||||
*/
|
||||
import { generate } from '@ant-design/colors';
|
||||
// import { APP_PRESET_COLOR_LIST } from '../../../src/settings/designSetting';
|
||||
|
||||
export const primaryColor = '#2a50ec'; // APP_PRESET_COLOR_LIST[0];
|
||||
export const darkPrimaryColor = '#2a50ec';
|
||||
|
||||
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 primary = color || primaryColor;
|
||||
const lightColors = generateAntColors(primary);
|
||||
const darkPrimary = darkPrimaryColor; //lightColors[5];
|
||||
const darkColors = generateAntColors(darkPrimary, 'dark');
|
||||
return [...lightColors, ...darkColors];
|
||||
}
|
||||
|
||||
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);
|
||||
})
|
||||
.filter((item) => !item.includes('-'));
|
||||
|
||||
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');
|
||||
|
||||
// console.log('lightens', lightens);
|
||||
// console.log('darkens', darkens);
|
||||
// console.log('alphaColors', alphaColors);
|
||||
// console.log('shortAlphaColors', shortAlphaColors);
|
||||
// console.log('tinycolorLightens', tinycolorLightens);
|
||||
// console.log('tinycolorDarkens', tinycolorDarkens);
|
||||
|
||||
return [...lightens, ...darkens, ...alphaColors, ...shortAlphaColors, ...tinycolorDarkens, ...tinycolorLightens];
|
||||
}
|
||||
19
web-vue/packages/vite/tsconfig.json
Normal file
19
web-vue/packages/vite/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@jeesite/vite/*": ["./*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*.ts",
|
||||
"./**/*.tsx",
|
||||
"./**/*.vue"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"vite.config.ts",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user