Browse Source

feat: 打包构建添加可选 `gzip` 与 `brotli` 压缩模式

i18n
xiaoxian521 2 years ago
parent
commit
fdf12660c1
  1. 7
      .env.production
  2. 7
      .env.staging
  3. 63
      build/compress.ts
  4. 3
      build/index.ts
  5. 5
      build/plugins.ts
  6. 1
      package.json
  7. 18
      pnpm-lock.yaml
  8. 19
      src/views/permission/button/index.vue
  9. 15
      src/views/permission/page/index.vue
  10. 10
      types/global.d.ts
  11. 3
      vite.config.ts

7
.env.production

@ -11,4 +11,9 @@ VITE_PROXY_DOMAIN_REAL = ""
VITE_LEGACY = false
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
VITE_CDN = false
VITE_CDN = false
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
VITE_COMPRESSION = "none"

7
.env.staging

@ -14,4 +14,9 @@ VITE_PROXY_DOMAIN_REAL = ""
VITE_LEGACY = false
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
VITE_CDN = false
VITE_CDN = false
# 是否启用gzip压缩或brotli压缩(分两种情况,删除原始文件和不删除原始文件)
# 压缩时不删除原始文件的配置:gzip、brotli、both(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
# 压缩时删除原始文件的配置:gzip-clear、brotli-clear、both-clear(同时开启 gzip 与 brotli 压缩)、none(不开启压缩,默认)
VITE_COMPRESSION = "none"

63
build/compress.ts

@ -0,0 +1,63 @@
import type { Plugin } from "vite";
import { isArray } from "@pureadmin/utils";
import compressPlugin from "vite-plugin-compression";
export const configCompressPlugin = (
compress: ViteCompression
): Plugin | Plugin[] => {
if (compress === "none") return null;
const gz = {
// 生成的压缩包后缀
ext: ".gz",
// 体积大于threshold才会被压缩
threshold: 0,
// 默认压缩.js|mjs|json|css|html后缀文件,设置成true,压缩全部文件
filter: () => true,
// 压缩后是否删除原始文件
deleteOriginFile: false
};
const br = {
ext: ".br",
algorithm: "brotliCompress",
threshold: 0,
filter: () => true,
deleteOriginFile: false
};
const codeList = [
{ k: "gzip", v: gz },
{ k: "brotli", v: br },
{ k: "both", v: [gz, br] }
];
const plugins: Plugin[] = [];
codeList.forEach(item => {
if (compress.includes(item.k)) {
if (compress.includes("clear")) {
if (isArray(item.v)) {
item.v.forEach(vItem => {
plugins.push(
compressPlugin(Object.assign(vItem, { deleteOriginFile: true }))
);
});
} else {
plugins.push(
compressPlugin(Object.assign(item.v, { deleteOriginFile: true }))
);
}
} else {
if (isArray(item.v)) {
item.v.forEach(vItem => {
plugins.push(compressPlugin(vItem));
});
} else {
plugins.push(compressPlugin(item.v));
}
}
}
});
return plugins;
};

3
build/index.ts

@ -8,7 +8,8 @@ const warpperEnv = (envConf: Recordable): ViteEnv => {
VITE_PROXY_DOMAIN_REAL: "",
VITE_ROUTER_HISTORY: "",
VITE_LEGACY: false,
VITE_CDN: false
VITE_CDN: false,
VITE_COMPRESSION: "none"
};
for (const envName of Object.keys(envConf)) {

5
build/plugins.ts

@ -6,6 +6,7 @@ import svgLoader from "vite-svg-loader";
import legacy from "@vitejs/plugin-legacy";
import vueJsx from "@vitejs/plugin-vue-jsx";
import { viteMockServe } from "vite-plugin-mock";
import { configCompressPlugin } from "./compress";
import VueI18n from "@intlify/vite-plugin-vue-i18n";
// import ElementPlus from "unplugin-element-plus/vite";
import { visualizer } from "rollup-plugin-visualizer";
@ -17,7 +18,8 @@ import DefineOptions from "unplugin-vue-define-options/vite";
export function getPluginsList(
command: string,
VITE_LEGACY: boolean,
VITE_CDN: boolean
VITE_CDN: boolean,
VITE_COMPRESSION: ViteCompression
) {
const prodMock = true;
const lifecycle = process.env.npm_lifecycle_event;
@ -32,6 +34,7 @@ export function getPluginsList(
// jsx、tsx语法支持
vueJsx(),
VITE_CDN ? cdn : null,
configCompressPlugin(VITE_COMPRESSION),
DefineOptions(),
// 线上环境删除console
removeConsole({ external: ["src/assets/iconfont/iconfont.js"] }),

1
package.json

@ -117,6 +117,7 @@
"unplugin-vue-define-options": "0.7.3",
"vite": "^3.1.8",
"vite-plugin-cdn-import": "^0.3.5",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-remove-console": "^1.1.0",
"vite-svg-loader": "^3.6.0",

18
pnpm-lock.yaml

@ -82,6 +82,7 @@ specifiers:
unplugin-vue-define-options: 0.7.3
vite: ^3.1.8
vite-plugin-cdn-import: ^0.3.5
vite-plugin-compression: ^0.5.1
vite-plugin-mock: ^2.9.6
vite-plugin-remove-console: ^1.1.0
vite-svg-loader: ^3.6.0
@ -184,6 +185,7 @@ devDependencies:
unplugin-vue-define-options: 0.7[email protected][email protected]
vite: 3.1[email protected][email protected]
vite-plugin-cdn-import: 0.3.5
vite-plugin-compression: 0.5[email protected]
vite-plugin-mock: 2.9[email protected][email protected]
vite-plugin-remove-console: 1.1.0
vite-svg-loader: 3.6.0
@ -7538,6 +7540,22 @@ packages:
- rollup
dev: true
/vite-plugin-compression/[email protected]:
resolution:
{
integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==
}
peerDependencies:
vite: ">=2.0.0"
dependencies:
chalk: 4.1.2
debug: 4.3.4
fs-extra: 10.1.0
vite: 3.1[email protected][email protected]
transitivePeerDependencies:
- supports-color
dev: true
/vite-plugin-mock/[email protected][email protected]:
resolution:
{

19
src/views/permission/button/index.vue

@ -6,20 +6,21 @@ defineOptions({
name: "PermissionButton"
});
let width = computed((): CSSProperties => {
let elStyle = computed((): CSSProperties => {
return {
width: "85vw"
width: "85vw",
justifyContent: "start"
};
});
</script>
<template>
<el-space direction="vertical" size="large">
<el-tag :style="width" size="large" effect="dark">
<el-tag :style="elStyle" size="large" effect="dark">
当前拥有的code列表{{ getAuths() }}
</el-tag>
<el-card shadow="never" :style="width">
<el-card shadow="never" :style="elStyle">
<template #header>
<div class="card-header">组件方式判断权限</div>
</template>
@ -36,7 +37,7 @@ let width = computed((): CSSProperties => {
</Auth>
</el-card>
<el-card shadow="never" :style="width">
<el-card shadow="never" :style="elStyle">
<template #header>
<div class="card-header">函数方式判断权限</div>
</template>
@ -54,7 +55,7 @@ let width = computed((): CSSProperties => {
</el-button>
</el-card>
<el-card shadow="never" :style="width">
<el-card shadow="never" :style="elStyle">
<template #header>
<div class="card-header">
指令方式判断权限该方式不能动态修改权限
@ -72,9 +73,3 @@ let width = computed((): CSSProperties => {
</el-card>
</el-space>
</template>
<style lang="scss" scoped>
:deep(.el-tag) {
justify-content: start;
}
</style>

15
src/views/permission/page/index.vue

@ -8,9 +8,10 @@ defineOptions({
name: "PermissionPage"
});
let width = computed((): CSSProperties => {
let elStyle = computed((): CSSProperties => {
return {
width: "85vw"
width: "85vw",
justifyContent: "start"
};
});
@ -41,10 +42,10 @@ function onChange() {
<template>
<el-space direction="vertical" size="large">
<el-tag :style="width" size="large" effect="dark">
<el-tag :style="elStyle" size="large" effect="dark">
模拟后台根据不同角色返回对应路由具体参考完整版pure-admin代码
</el-tag>
<el-card shadow="never" :style="width">
<el-card shadow="never" :style="elStyle">
<template #header>
<div class="card-header">
<span>当前角色{{ username }}</span>
@ -61,9 +62,3 @@ function onChange() {
</el-card>
</el-space>
</template>
<style lang="scss" scoped>
:deep(.el-tag) {
justify-content: start;
}
</style>

10
types/global.d.ts

@ -74,6 +74,15 @@ declare global {
__: unknown;
}
type ViteCompression =
| "none"
| "gzip"
| "brotli"
| "both"
| "gzip-clear"
| "brotli-clear"
| "both-clear";
declare interface ViteEnv {
VITE_PORT: number;
VITE_PUBLIC_PATH: string;
@ -82,6 +91,7 @@ declare global {
VITE_ROUTER_HISTORY: string;
VITE_LEGACY: boolean;
VITE_CDN: boolean;
VITE_COMPRESSION: ViteCompression;
}
declare interface ServerConfigs {

3
vite.config.ts

@ -30,6 +30,7 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
VITE_CDN,
VITE_PORT,
VITE_LEGACY,
VITE_COMPRESSION,
VITE_PUBLIC_PATH,
VITE_PROXY_DOMAIN,
VITE_PROXY_DOMAIN_REAL
@ -60,7 +61,7 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
}
: null
},
plugins: getPluginsList(command, VITE_LEGACY, VITE_CDN),
plugins: getPluginsList(command, VITE_LEGACY, VITE_CDN, VITE_COMPRESSION),
optimizeDeps: {
include: ["pinia", "vue-i18n", "lodash-es", "@vueuse/core", "dayjs"],
exclude: ["@pureadmin/theme/dist/browser-utils"]

Loading…
Cancel
Save