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.
52 lines
1.8 KiB
Vue
52 lines
1.8 KiB
Vue
<template>
|
||
<div class="flex gap-2">
|
||
<el-tag v-for="entry in entries" :key="entry.key" size="large">
|
||
{{ entry.key }}: {{ entry.value }}
|
||
</el-tag>
|
||
<el-text v-if="!entries.length" type="info">—</el-text>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts">
|
||
export default {
|
||
name: "mapObject",
|
||
};
|
||
</script>
|
||
|
||
<script setup lang="ts">
|
||
import { PropType } from "vue";
|
||
|
||
/**
|
||
* Словарь «ключ — значение» из конфигурации: параметры ACME DNS-провайдера,
|
||
* заголовки masquerade.
|
||
*
|
||
* Как и ImputMultiple, компонент только показывает содержимое. Здесь был
|
||
* редактор с диалогом добавления, closable-тегами и `emit("update:mapObject")`,
|
||
* и он ничего не сохранял по тем же трём причинам: форма конфига Hysteria
|
||
* отрисована с `:disabled="true"`, значения передаются как
|
||
* `:map-object="dataForm.acme.dns.config"` без v-model, маршрутов записи
|
||
* серверного конфига в API нет.
|
||
*
|
||
* Значение показывается рядом с ключом: прежний вариант прятал его во второй
|
||
* диалог по клику на тег, что для read-only страницы лишний шаг — увидеть
|
||
* настройку сервера нужно сразу.
|
||
*/
|
||
const props = defineProps({
|
||
mapObject: {
|
||
required: false,
|
||
type: Object as PropType<{ [key: string]: string }>,
|
||
default: () => ({}),
|
||
},
|
||
});
|
||
|
||
const entries = computed(() =>
|
||
Object.entries(props.mapObject ?? {}).map(([key, value]) => ({ key, value }))
|
||
);
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.flex.gap-2 {
|
||
flex-wrap: wrap;
|
||
}
|
||
</style>
|