init 初始化脚手架

This commit is contained in:
bootx
2024-02-10 21:52:30 +08:00
commit 17b06dc9c0
131 changed files with 13067 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
/**
* 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: 'gzip' | 'brotli' | 'none',
deleteOriginFile = false
): PluginOption | 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;
}

46
build/vite/plugin/html.ts Normal file
View File

@@ -0,0 +1,46 @@
/**
* 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()}`;
};
// 当执行 yarn build 构建项目之后,会自动生成 _app.config.js 文件并插入 index.html
// _app.config.js 用于项目在打包后,需要动态修改配置的需求,如接口地址
// 不用重新进行打包,可在打包后修改 /dist/_app.config.js 内的变量,刷新即可更新代码内的局部变量
const htmlPlugin: PluginOption[] = createHtmlPlugin({
minify: isBuild,
inject: {
// Inject data into ejs template
// 需要注入 index.html ejs 模版的数据 使用在 html 中 <div><%= title %></div>
data: {
title: VITE_GLOB_APP_TITLE,
},
// Embed the generated app.config.js file 需要注入的标签列表
tags: isBuild
? [
{
tag: 'script',
attrs: {
src: getAppConfigSrc(),
},
},
]
: [],
},
});
return htmlPlugin;
}

View File

@@ -0,0 +1,62 @@
import type { PluginOption } from 'vite'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from 'unplugin-vue-components/resolvers'
import vue from '@vitejs/plugin-vue'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import WindiCSS from 'vite-plugin-windicss'
import { configHtmlPlugin } from './html'
import { configCompressPlugin } from './compress'
import { configVisualizerConfig } from './visualizer'
import { configSvgIconsPlugin } from './svgSprite'
/**
* 配置 vite 插件
* @param viteEnv vite 环境变量配置文件键值队 object
* @param isBuild 是否是 build 环境 true/false
* @returns vitePlugins[]
*/
export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
// VITE_BUILD_COMPRESS 是否启用 gzip 压缩或 brotli 压缩
// 可选: gzip | brotli | none
// 如果你需要多种形式,你可以用','来分隔
// VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE 打包使用压缩时是否删除原始文件,默认为 false
const { VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv
const vitePlugins: (PluginOption | PluginOption[])[] = [
// have to
vue(),
// support name https://github.com/vbenjs/vite-plugin-vue-setup-extend
vueSetupExtend(),
// 按需引入VantUi且自动创建组件声明
Components({
dts: true,
resolvers: [VantResolver()],
types: [],
}),
]
// vite-plugin-windicss
vitePlugins.push(WindiCSS())
// 加载 html 插件 vite-plugin-html
vitePlugins.push(configHtmlPlugin(viteEnv, isBuild))
// rollup-plugin-visualizer
vitePlugins.push(configVisualizerConfig())
// vite-plugin-svg-icons
vitePlugins.push(configSvgIconsPlugin(isBuild))
if (isBuild) {
// rollup-plugin-gzip
// 加载 gzip 打包
vitePlugins.push(
configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE),
)
}
return vitePlugins
}

View File

@@ -0,0 +1,19 @@
/**
* Vite Plugin for fast creating SVG sprites.
* https://github.com/anncwb/vite-plugin-svg-icons
*/
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
import path from 'path';
export function configSvgIconsPlugin(isBuild: boolean) {
// 指定需要缓存的图标文件夹
const svgIconsPlugin = createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
// 是否压缩
svgoOptions: isBuild,
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
});
return svgIconsPlugin;
}

View File

@@ -0,0 +1,18 @@
/**
* Package file volume analysis
*/
import visualizer from 'rollup-plugin-visualizer';
import type { PluginOption } from 'vite';
import { isReportMode } from '../../utils';
export function configVisualizerConfig() {
if (isReportMode()) {
return visualizer({
filename: './node_modules/.cache/visualizer/stats.html',
open: true,
gzipSize: true,
brotliSize: true,
}) as PluginOption;
}
return [];
}

52
build/vite/proxy.ts Normal file
View File

@@ -0,0 +1,52 @@
/**
* 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 & { rewrite: (path: string) => string }>;
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
// 如果您secure="true"只允许来自 HTTPS 的请求则secure="false"意味着允许来自 HTTP 和 HTTPS 的请求。
...(isHttps ? { secure: false } : {}),
};
}
return ret;
// ret
// {
// '/test/api': {
// target: 'http://localhost:3080/test/api',
// changeOrigin: true,
// ws: true,
// rewrite: (path) => path.replace(new RegExp(/^\/test/api/), ''),
// },
// '/upload': {
// target: 'http://localhost:8001/upload',
// changeOrigin: true,
// ws: true,
// rewrite: (path) => path.replace(new RegExp(/^\/upload/), ''),
// }
// }
}