feat(projects): 1.0 beta

This commit is contained in:
Soybean
2023-11-17 08:45:00 +08:00
parent 1ea4817f6a
commit e918a2c0f5
499 changed files with 15918 additions and 24708 deletions

View File

@ -1,8 +0,0 @@
import dayjs from 'dayjs';
/** 项目构建时间 */
const PROJECT_BUILD_TIME = JSON.stringify(dayjs().format('YYYY-MM-DD HH:mm:ss'));
export const viteDefine = {
PROJECT_BUILD_TIME
};

View File

@ -1,2 +1 @@
export * from './define';
export * from './proxy';

View File

@ -1,20 +1,38 @@
import type { ProxyOptions } from 'vite';
import { createServiceConfig, createProxyPattern } from '../../env.config';
/**
* 设置网络代理
* @param isOpenProxy - 是否开启代理
* @param envConfig - env环境配置
* set http proxy
* @param env - the current env
*/
export function createViteProxy(isOpenProxy: boolean, envConfig: ServiceEnvConfigWithProxyPattern) {
if (!isOpenProxy) return undefined;
export function createViteProxy(env: Env.ImportMeta) {
const isEnableHttpProxy = env.VITE_HTTP_PROXY === 'Y';
const proxy: Record<string, string | ProxyOptions> = {
[envConfig.proxyPattern]: {
target: envConfig.url,
if (!isEnableHttpProxy) return undefined;
const { baseURL, otherBaseURL } = createServiceConfig(env);
const defaultProxyPattern = createProxyPattern();
const proxy: Record<string, ProxyOptions> = {
[defaultProxyPattern]: {
target: baseURL,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${envConfig.proxyPattern}`), '')
rewrite: path => path.replace(new RegExp(`^${defaultProxyPattern}`), '')
}
};
const otherURLEntries = Object.entries(otherBaseURL);
for (const [key, url] of otherURLEntries) {
const proxyPattern = createProxyPattern(key);
proxy[proxyPattern] = {
target: url,
changeOrigin: true,
rewrite: path => path.replace(new RegExp(`^${proxyPattern}`), '')
};
}
return proxy;
}

View File

@ -1,3 +0,0 @@
export * from './plugins';
export * from './config';
export * from './utils';

View File

@ -1,6 +0,0 @@
import ViteCompression from 'vite-plugin-compression';
export default (viteEnv: ImportMetaEnv) => {
const { VITE_COMPRESS_TYPE = 'gzip' } = viteEnv;
return ViteCompression({ algorithm: VITE_COMPRESS_TYPE });
};

View File

@ -1,22 +1,14 @@
import type { PluginOption } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import unocss from '@unocss/vite';
import progress from 'vite-plugin-progress';
import VueDevtools from 'vite-plugin-vue-devtools';
import pageRoute from '@soybeanjs/vite-plugin-vue-page-route';
import unplugin from './unplugin';
import mock from './mock';
import visualizer from './visualizer';
import compress from './compress';
import pwa from './pwa';
import progress from 'vite-plugin-progress';
import { setupElegantRouter } from './router';
import { setupUnocss } from './unocss';
import { setupUnplugin } from './unplugin';
/**
* vite插件
* @param viteEnv - 环境变量配置
*/
export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | PluginOption[])[] {
const plugins = [
export function setupVitePlugins(viteEnv: Env.ImportMeta) {
const plugins: PluginOption = [
vue({
script: {
defineModel: true
@ -24,24 +16,11 @@ export function setupVitePlugins(viteEnv: ImportMetaEnv): (PluginOption | Plugin
}),
vueJsx(),
VueDevtools(),
...unplugin(viteEnv),
unocss(),
mock(viteEnv),
setupElegantRouter(),
setupUnocss(viteEnv),
...setupUnplugin(viteEnv),
progress()
];
if (viteEnv.VITE_VISUALIZER === 'Y') {
plugins.push(visualizer as PluginOption);
}
if (viteEnv.VITE_COMPRESS === 'Y') {
plugins.push(compress(viteEnv));
}
if (viteEnv.VITE_PWA === 'Y' || viteEnv.VITE_VERCEL === 'Y') {
plugins.push(pwa());
}
if (viteEnv.VITE_SOYBEAN_ROUTE_PLUGIN === 'Y') {
plugins.push(pageRoute());
}
return plugins;
}

View File

@ -1,14 +0,0 @@
import { viteMockServe } from 'vite-plugin-mock';
export default (viteEnv: ImportMetaEnv) => {
const prodMock = viteEnv.VITE_PROD_MOCK === 'Y';
return viteMockServe({
mockPath: 'mock',
prodEnabled: prodMock,
injectCode: `
import { setupMockServer } from '../mock';
setupMockServer();
`
});
};

View File

@ -1,31 +0,0 @@
import { VitePWA } from 'vite-plugin-pwa';
export default function setupVitePwa() {
return VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.ico'],
manifest: {
name: 'SoybeanAdmin',
short_name: 'SoybeanAdmin',
theme_color: '#fff',
icons: [
{
src: '/logo.png',
sizes: '192x192',
type: 'image/png'
},
{
src: '/logo.png',
sizes: '512x512',
type: 'image/png'
},
{
src: '/logo.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable'
}
]
}
});
}

41
build/plugins/router.ts Normal file
View File

@ -0,0 +1,41 @@
import type { RouteMeta } from 'vue-router';
import ElegantVueRouter from '@elegant-router/vue/vite';
import type { RouteKey } from '@elegant-router/types';
export function setupElegantRouter() {
return ElegantVueRouter({
layouts: {
base: 'src/layouts/base-layout/index.vue',
blank: 'src/layouts/blank-layout/index.vue'
},
routePathTransformer(routeName, routePath) {
const key = routeName as RouteKey;
if (key === 'login') {
const modules: UnionKey.LoginModule[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat'];
const moduleReg = modules.join('|');
return `/login/:module(${moduleReg})?`;
}
return routePath;
},
onRouteMetaGen(routeName) {
const key = routeName as RouteKey;
const constantRoutes: RouteKey[] = ['login', '403', '404', '500'];
const meta: Partial<RouteMeta> = {
title: key,
i18nKey: `route.${key}` as App.I18n.I18nKey
};
if (constantRoutes.includes(key)) {
meta.constant = true;
}
return meta;
}
});
}

33
build/plugins/unocss.ts Normal file
View File

@ -0,0 +1,33 @@
import path from 'node:path';
import unocss from '@unocss/vite';
import presetIcons from '@unocss/preset-icons';
import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders';
export function setupUnocss(viteEnv: Env.ImportMeta) {
const { VITE_ICON_PREFIX, VITE_ICON_LOCAL_PREFIX } = viteEnv;
const localIconPath = path.join(process.cwd(), 'src/assets/svg-icon');
/**
* the name of the local icon collection
*/
const collectionName = VITE_ICON_LOCAL_PREFIX.replace(`${VITE_ICON_PREFIX}-`, '');
return unocss({
presets: [
presetIcons({
prefix: `${VITE_ICON_PREFIX}-`,
scale: 1,
extraProperties: {
display: 'inline-block'
},
collections: {
[collectionName]: FileSystemIconLoader(localIconPath, svg =>
svg.replace(/^<svg\s/, '<svg width="1em" height="1em" ')
)
},
warn: true
})
]
});
}

View File

@ -1,21 +1,23 @@
import path from 'node:path';
import type { PluginOption } from 'vite';
import Icons from 'unplugin-icons/vite';
import IconsResolver from 'unplugin-icons/resolver';
import Components from 'unplugin-vue-components/vite';
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers';
import { AntDesignVueResolver, NaiveUiResolver } from 'unplugin-vue-components/resolvers';
import { FileSystemIconLoader } from 'unplugin-icons/loaders';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import { getSrcPath } from '../utils';
export default function unplugin(viteEnv: ImportMetaEnv) {
export function setupUnplugin(viteEnv: Env.ImportMeta) {
const { VITE_ICON_PREFIX, VITE_ICON_LOCAL_PREFIX } = viteEnv;
const srcPath = getSrcPath();
const localIconPath = `${srcPath}/assets/svg-icon`;
const localIconPath = path.join(process.cwd(), 'src/assets/svg-icon');
/** 本地svg图标集合名称 */
/**
* the name of the local icon collection
*/
const collectionName = VITE_ICON_LOCAL_PREFIX.replace(`${VITE_ICON_PREFIX}-`, '');
return [
const plugins: PluginOption[] = [
Icons({
compiler: 'vue3',
customCollections: {
@ -30,6 +32,9 @@ export default function unplugin(viteEnv: ImportMetaEnv) {
dts: 'src/typings/components.d.ts',
types: [{ from: 'vue-router', names: ['RouterLink', 'RouterView'] }],
resolvers: [
AntDesignVueResolver({
importStyle: false
}),
NaiveUiResolver(),
IconsResolver({ customCollections: [collectionName], componentPrefix: VITE_ICON_PREFIX })
]
@ -41,4 +46,6 @@ export default function unplugin(viteEnv: ImportMetaEnv) {
customDomId: '__SVG_ICON_LOCAL__'
})
];
return plugins;
}

View File

@ -1,7 +0,0 @@
import { visualizer } from 'rollup-plugin-visualizer';
export default visualizer({
gzipSize: true,
brotliSize: true,
open: true
});

View File

@ -1,20 +0,0 @@
import path from 'path';
/**
* 获取项目根路径
* @descrition 末尾不带斜杠
*/
export function getRootPath() {
return path.resolve(process.cwd());
}
/**
* 获取项目src路径
* @param srcName - src目录名称(默认: "src")
* @descrition 末尾不带斜杠
*/
export function getSrcPath(srcName = 'src') {
const rootPath = getRootPath();
return `${rootPath}/${srcName}`;
}