ddd1020a3a
Решение «Vite не трогать» пересмотрено по данным, а не по желанию обновиться.
`pnpm audit --prod` (то, на что смотрит gate сборки) был чист, но полный audit
показывал в build-цепочке два critical и rollup GHSA DOM clobbering — а он
затрагивает ГЕНЕРИРУЕМЫЙ bundle, то есть уезжает в production. Vite 4.3.1 тянул
rollup 3 без исправления.
Взята 7.3.6 — последняя линия до Rolldown. Vite 8 по-прежнему не берётся: это
смена бандлера, отдельная работа с собственной приёмкой.
Вместе с Vite обновлена цепочка плагинов (@vitejs/plugin-vue 4 -> 6,
unplugin-* и unocss с версий 2022-2023 годов) и линтеры (@typescript-eslint
5 -> 8, prettier 2 -> 3, stylelint 15 -> 17). Новый @typescript-eslint нашёл 7
настоящих замечаний — исправлены по существу, а не подавлением правил; среди
них подавление несуществующего правила ban-types и `{}` вместо `object`.
Отдельно — три мёртвых редактора. Outbounds уже был разобран, здесь то же
самое для ImputMultiple (ACME-домены, inline ACL) и MapAdd (параметры ACME DNS,
заголовки masquerade): оба редактировали конфиг Hysteria в форме с
:disabled="true", получали значения без v-model и эмитили события, которых
никто не слушает, на странице без единого маршрута записи.
Цена ImputMultiple была измеримой. vuedraggable поставляется UMD-сборкой,
поэтому её require("vue") разрешался в vue/dist/vue.cjs.prod.js — полную сборку
Vue с рантайм-компилятором шаблонов. В бандл уезжало ~500 КБ исходников
(vuedraggable + sortablejs + compiler-core + compiler-dom) ради перетаскивания
тегов в недоступной для редактирования форме.
Разбор bundle через sourcemap нашёл и вторую потерю: @vueuse/core собирался
дважды — наш 13.9.0 и 14.4.0 из element-plus. Версии сведены.
bundle: 2 813 525 против 2 404 202 на исходной базовой линии (+17% за Vue 3.5,
Element Plus 2.14, echarts 6 и rollup 4). Промежуточное состояние без этих двух
исправлений было 3 046 172.
pnpm audit --prod: чисто. typecheck/eslint/stylelint: 0. go build с dist: OK.
100 lines
2.1 KiB
Vue
100 lines
2.1 KiB
Vue
<script setup lang="ts">
|
||
import { computed, watchEffect } from "vue";
|
||
import { useWindowSize } from "@vueuse/core";
|
||
import { AppMain, Navbar } from "./components/index";
|
||
import Sidebar from "./components/Sidebar/index.vue";
|
||
|
||
import { useAppStore } from "@/store/modules/app";
|
||
|
||
const { width } = useWindowSize();
|
||
|
||
/**
|
||
* Фиксированная ширина контейнера адаптивного layout
|
||
*
|
||
* Большой экран(>=1200px)
|
||
* Средний экран(>=992px)
|
||
* Малый экран(>=768px)
|
||
*/
|
||
const WIDTH = 992;
|
||
|
||
const appStore = useAppStore();
|
||
|
||
const classObj = computed(() => ({
|
||
hideSidebar: !appStore.sidebar.opened,
|
||
openSidebar: appStore.sidebar.opened,
|
||
withoutAnimation: appStore.sidebar.withoutAnimation,
|
||
mobile: appStore.device === "mobile",
|
||
}));
|
||
|
||
watchEffect(() => {
|
||
if (width.value < WIDTH) {
|
||
appStore.toggleDevice("mobile");
|
||
appStore.closeSideBar(true);
|
||
} else {
|
||
appStore.toggleDevice("desktop");
|
||
|
||
if (width.value >= 1200) {
|
||
//Большой экран
|
||
appStore.openSideBar(true);
|
||
} else {
|
||
appStore.closeSideBar(true);
|
||
}
|
||
}
|
||
});
|
||
|
||
function handleOutsideClick() {
|
||
appStore.closeSideBar(false);
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div :class="classObj" class="app-wrapper">
|
||
<!-- Overlay открытого бокового меню на мобильных устройствах -->
|
||
<div
|
||
v-if="classObj.mobile && classObj.openSidebar"
|
||
class="drawer-bg"
|
||
@click="handleOutsideClick"
|
||
></div>
|
||
|
||
<Sidebar class="sidebar-container" />
|
||
|
||
<div class="main-container">
|
||
<div class="layout-header">
|
||
<navbar />
|
||
</div>
|
||
|
||
<!--Основная страница-->
|
||
<app-main />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style lang="scss" scoped>
|
||
.app-wrapper {
|
||
&::after {
|
||
clear: both;
|
||
display: table;
|
||
content: "";
|
||
}
|
||
|
||
position: relative;
|
||
width: 100%;
|
||
height: 100%;
|
||
|
||
&.mobile.openSidebar {
|
||
position: fixed;
|
||
top: 0;
|
||
}
|
||
}
|
||
|
||
.drawer-bg {
|
||
position: absolute;
|
||
top: 0;
|
||
z-index: 999;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: #000;
|
||
opacity: 0.3;
|
||
}
|
||
</style>
|