chore: optimize JavaScript bundle (#5495)

This commit is contained in:
Michael Geers 2022-12-18 21:59:01 +01:00 • committed by GitHub
parent 8cb8444774
commit e9236fc095
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 1929 additions and 2218 deletions

1
.gitignore vendored
View file

@ -30,3 +30,4 @@ fly.toml
.idea
vendor/*
QEMU_EFI.fd
asset-stats.html

View file

@ -1,8 +1,6 @@
import { defineSetupVue3 } from "@histoire/plugin-vue";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
import smoothscroll from "smoothscroll-polyfill";
import VueNumber from "vue-number-animation";
import setupI18n from "./js/i18n";
import "./css/app.css";
import { watchThemeChanges } from "./js/theme";
@ -13,5 +11,4 @@ watchThemeChanges();
export const setupVue3 = defineSetupVue3(({ app }) => {
app.config.globalProperties.$hiddenFeatures = true;
app.use(setupI18n());
app.use(VueNumber);
});

View file

@ -1,11 +1,9 @@
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
import smoothscroll from "smoothscroll-polyfill";
import "../css/app.css";
import { createApp, h } from "vue";
import { createMetaManager, plugin as metaPlugin } from "vue-meta";
import App from "./views/App.vue";
import VueNumber from "vue-number-animation";
import setupRouter from "./router";
import setupI18n from "./i18n";
import featureflags from "./featureflags";
@ -70,7 +68,6 @@ app.use(setupRouter(i18n));
app.use(createMetaManager());
app.use(metaPlugin);
app.use(featureflags);
app.use(VueNumber);
window.app = app.mount("#app");
watchThemeChanges();

View file

@ -1,30 +1,46 @@
<template>
<number :to="to" :format="format" :duration="animationDuration" />
<span />
</template>
<script>
import { CountUp } from "countup.js";
const DURATION = 0.5;
export default {
name: "AnimatedNumber",
props: {
to: { type: Number },
format: { type: Function },
noAnimation: { type: Boolean },
format: { type: Function, required: true },
duration: { type: Number, default: DURATION },
},
data() {
return { activeDuration: 0 };
},
computed: {
animationDuration() {
return this.noAnimation ? 0 : this.activeDuration;
},
return {
instance: null,
};
},
watch: {
to: function () {
this.activeDuration = this.duration;
to(value) {
this.instance?.update(value);
},
},
mounted() {
if (this.instance) {
return;
}
this.instance = new CountUp(this.$el, this.to, {
startVal: this.to,
formattingFn: this.format,
duration: this.duration,
decimalPlaces: 2,
});
if (this.instance.error) {
console.error(this.instance.error);
}
},
unmounted() {
this.instance = null;
},
};
</script>
<style lang="less" scoped></style>

View file

@ -5,8 +5,7 @@
icon="car"
:title="$t('footer.community.power')"
:value="chargePower"
:valueFmt="numberAnimationFmt"
:animationDuration="animationDuration"
:valueFmt="fmtAnimation"
unit="kW"
:sub1="$t('footer.community.powerSub1', { totalClients, activeClients })"
:sub2="$t('footer.community.powerSub2')"
@ -17,8 +16,7 @@
icon="sun"
:title="$t('footer.community.greenShare')"
:value="greenShare"
:valueFmt="numberAnimationFmt"
:animationDuration="animationDuration"
:valueFmt="fmtAnimationDecimal"
unit="%"
:sub1="$t('footer.community.greenShareSub1')"
:sub2="$t('footer.community.greenShareSub2')"
@ -29,8 +27,7 @@
icon="eco"
:title="$t('footer.community.greenEnergy')"
:value="greenEnergyMWh"
:valueFmt="numberAnimationFmt"
:animationDuration="animationDuration"
:valueFmt="fmtAnimationDecimal"
unit="MWh"
:sub1="$t('footer.community.greenEnergySub1')"
:sub2="$t('footer.community.greenEnergySub2')"
@ -55,7 +52,6 @@ export default {
return {
refresh: null,
result: {},
animationDuration: 0.5,
};
},
computed: {
@ -84,9 +80,6 @@ export default {
async mounted() {
this.refresh = setInterval(this.update, UPDATE_INTERVAL_SECONDS * 1e3);
await this.update();
this.$nextTick(() => {
this.animationDuration = UPDATE_INTERVAL_SECONDS;
});
},
unmounted() {
clearInterval(this.refresh);
@ -100,7 +93,10 @@ export default {
console.error(err);
}
},
numberAnimationFmt(number) {
fmtAnimation(number) {
return this.fmtNumber(number, 0);
},
fmtAnimationDecimal(number) {
return this.fmtNumber(number, 1);
},
},

View file

@ -1,9 +1,8 @@
<template>
<button
type="button"
data-bs-toggle="modal"
:data-bs-target="`#loadpointSettingsModal_${id}`"
class="btn btn-sm btn-outline-secondary position-relative border-0 p-2 evcc-gray"
@click="openModal"
>
<shopicon-regular-adjust size="s"></shopicon-regular-adjust>
</button>
@ -11,11 +10,20 @@
<script>
import "@h2d2/shopicons/es/regular/adjust";
import Modal from "bootstrap/js/dist/modal";
export default {
name: "LoadpointSettingsButton",
props: {
id: [String, Number],
},
methods: {
openModal() {
const modal = Modal.getOrCreateInstance(
document.getElementById(`loadpointSettingsModal_${this.id}`)
);
modal.show();
},
},
};
</script>

View file

@ -2,8 +2,7 @@
<div>
<button
class="btn btn-link pe-0 text-decoration-none evcc-default-text text-nowrap d-flex align-items-end"
data-bs-toggle="modal"
data-bs-target="#savingsModal"
@click="openModal"
>
<span class="d-inline d-sm-none">{{
$t("footer.savings.footerShort", { percent })
@ -145,6 +144,7 @@
</template>
<script>
import Modal from "bootstrap/js/dist/modal";
import formatter from "../mixins/formatter";
import Sponsor from "./Sponsor.vue";
import SavingsTile from "./SavingsTile.vue";
@ -192,6 +192,10 @@ export default {
showMyData() {
this.communityView = false;
},
openModal() {
const modal = Modal.getOrCreateInstance(document.getElementById("savingsModal"));
modal.show();
},
},
};
</script>

View file

@ -16,12 +16,7 @@
<p class="my-0 fw-bold text-truncate">{{ title }}</p>
<strong class="d-flex align-items-baseline lh-sm">
<span class="fs-1">
<AnimatedNumber
v-if="valueFmt"
:to="value"
:format="valueFmt"
:duration="animationDuration"
/>
<AnimatedNumber v-if="valueFmt" :to="value" :format="valueFmt" />
<span v-else>{{ value }}</span>
</span>
<span class="ms-1 unit">{{ unit }}</span>
@ -51,7 +46,6 @@ export default {
icon: String,
value: [String, Number],
valueFmt: Function,
animationDuration: Number,
unit: String,
sub1: String,
sub2: String,

View file

@ -93,7 +93,6 @@ export default {
scrollTo(e) {
const id = e.currentTarget.getAttribute("href").substring(1);
const el = document.getElementById(id);
console.log({ id, el });
if (el) {
el.scrollIntoView({ behavior: "smooth", block: "center" });
}

View file

@ -8,9 +8,8 @@
<button
class="btn btn-link p-0 value text-center"
:class="targetChargeEnabled ? 'evcc-default-text' : 'text-gray'"
data-bs-toggle="modal"
:data-bs-target="`#${modalId}`"
:disabled="disabled"
@click="openModal"
>
<strong v-if="targetChargeEnabled">{{ targetTimeLabel() }}</strong>
<span v-else>{{ $t("main.targetCharge.setTargetTime") }}</span>
@ -119,6 +118,7 @@
</template>
<script>
import Modal from "bootstrap/js/dist/modal";
import "@h2d2/shopicons/es/filled/plus";
import "@h2d2/shopicons/es/filled/edit";
import LabelAndValue from "./LabelAndValue.vue";
@ -243,6 +243,10 @@ export default {
removeTargetTime: function () {
this.$emit("target-time-removed");
},
openModal() {
const modal = Modal.getOrCreateInstance(document.getElementById(this.modalId));
modal.show();
},
},
};
</script>

View file

@ -16,11 +16,7 @@
class="text-decoration-underline"
:class="{ 'text-gray fw-normal': !targetEnergy }"
>
<AnimatedNumber
:to="targetEnergy"
:format="fmtEnergy"
:no-animation="!targetEnergy"
/>
<AnimatedNumber :to="targetEnergy" :format="fmtEnergy" />
</span>
</label>

View file

@ -8,7 +8,7 @@
</option>
</select>
<span class="text-decoration-underline">
<AnimatedNumber :to="targetSoc" :format="formatSoC" />
<AnimatedNumber :to="77" :format="formatSoC" />
</span>
</label>

View file

@ -75,7 +75,7 @@ export default {
}
try {
const response = await api.get("settings/telemetry");
this.enabled = response.data.result;
settings.telemetry = response.data.result;
} catch (err) {
console.error(err);
}

View file

@ -1,12 +1,10 @@
<template>
<div>
<button
id="topNavigatonDropdown"
type="button"
data-bs-toggle="dropdown"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
class="btn btn-sm btn-outline-secondary position-relative border-0 menu-button"
>
<span
@ -17,7 +15,7 @@
</span>
<shopicon-regular-menu></shopicon-regular-menu>
</button>
<ul class="dropdown-menu dropdown-menu-end">
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="topNavigatonDropdown">
<li>
<router-link class="dropdown-item" to="/sessions">
{{ $t("header.sessions") }}
@ -25,12 +23,7 @@
</li>
<li>
<button
type="button"
class="dropdown-item"
data-bs-toggle="modal"
data-bs-target="#globalSettingsModal"
>
<button type="button" class="dropdown-item" @click="openSettingsModal">
{{ $t("header.settings") }}
</button>
</li>
@ -104,6 +97,10 @@
</template>
<script>
import Modal from "bootstrap/js/dist/modal";
import Dropdown from "bootstrap/js/dist/dropdown";
import "@h2d2/shopicons/es/regular/gift";
import "@h2d2/shopicons/es/regular/moonstars";
import "@h2d2/shopicons/es/regular/menu";
import "@h2d2/shopicons/es/regular/newtab";
import GlobalSettingsModal from "./GlobalSettingsModal.vue";
@ -135,6 +132,12 @@ export default {
}));
},
},
mounted() {
this.dropdown = new Dropdown(document.getElementById("topNavigatonDropdown"));
},
unmounted() {
this.dropdown?.dispose();
},
methods: {
handleProviderAuthorization: async function (provider) {
if (!provider.loggedIn) {
@ -145,6 +148,10 @@ export default {
baseAPI.post(provider.logoutPath);
}
},
openSettingsModal() {
const modal = Modal.getOrCreateInstance(document.getElementById("globalSettingsModal"));
modal.show();
},
},
};
</script>

View file

@ -1,17 +1,15 @@
<template>
<div>
<div
:id="dropdownId"
role="button"
tabindex="0"
data-bs-toggle="dropdown"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
>
<slot />
</div>
<ul class="dropdown-menu dropdown-menu-start">
<ul class="dropdown-menu dropdown-menu-start" :aria-labelledby="dropdownId">
<li>
<h6 class="dropdown-header">{{ $t("main.vehicle.changeVehicle") }}</h6>
</li>
@ -31,14 +29,27 @@
<script>
import "@h2d2/shopicons/es/filled/options";
import Dropdown from "bootstrap/js/dist/dropdown";
export default {
name: "VehicleOptions",
props: {
id: [String, Number],
vehicles: Array,
isUnknown: Boolean,
},
emits: ["change-vehicle", "remove-vehicle"],
computed: {
dropdownId() {
return `vehicleOptionsDropdown${this.id}`;
},
},
mounted() {
this.dropdown = new Dropdown(document.getElementById(this.dropdownId));
},
unmounted() {
this.dropdown?.dispose();
},
methods: {
changeVehicle(index) {
this.$emit("change-vehicle", index);

View file

@ -50,7 +50,7 @@
</template>
<script>
import { Tooltip } from "bootstrap";
import Tooltip from "bootstrap/js/dist/tooltip";
export default {
name: "VehicleSoc",

View file

@ -19,6 +19,7 @@
></shopicon-regular-cablecharge>
<VehicleOptions
v-if="showOptions"
:id="id"
class="options"
:vehicles="otherVehicles"
:is-unknown="isUnknown"
@ -40,7 +41,7 @@
import "@h2d2/shopicons/es/regular/refresh";
import "@h2d2/shopicons/es/regular/cablecharge";
import VehicleIcon from "./VehicleIcon";
import { Tooltip } from "bootstrap";
import Tooltip from "bootstrap/js/dist/tooltip";
import VehicleOptions from "./VehicleOptions.vue";
@ -48,6 +49,7 @@ export default {
name: "VehicleTitle",
components: { VehicleOptions, VehicleIcon },
props: {
id: [String, Number],
vehiclePresent: Boolean,
vehicleTitle: String,
vehicleIcon: String,

View file

@ -13,9 +13,8 @@
<button
v-else-if="newVersionAvailable"
href="#"
data-bs-toggle="modal"
data-bs-target="#updateModal"
class="btn btn-link ps-0 text-decoration-none evcc-default-text text-nowrap d-flex align-items-end"
@click="openModal"
>
<shopicon-regular-gift class="me-2"></shopicon-regular-gift>
v{{ installed }}
@ -131,11 +130,11 @@
</template>
<script>
import api from "../api";
import Logo from "./Logo.vue";
import Modal from "bootstrap/js/dist/modal";
import "@h2d2/shopicons/es/regular/gift";
import "@h2d2/shopicons/es/regular/moonstars";
import api from "../api";
import Logo from "./Logo.vue";
export default {
name: "Version",
@ -181,6 +180,10 @@ export default {
releaseNotesUrl: function (version) {
return `https://github.com/evcc-io/evcc/releases/tag/${version}`;
},
openModal() {
const modal = Modal.getOrCreateInstance(document.getElementById("updateModal"));
modal.show();
},
},
};
</script>

View file

@ -1,6 +1,6 @@
import settings from "./settings";
const darkModeMatcher = window.matchMedia("(prefers-color-scheme: dark)");
const darkModeMatcher = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)");
const THEME_AUTO = "auto";
const THEME_LIGHT = "light";
@ -27,7 +27,7 @@ function updateTheme() {
let theme = getThemePreference();
if (theme === THEME_AUTO) {
theme = darkModeMatcher.matches ? THEME_DARK : THEME_LIGHT;
theme = darkModeMatcher?.matches ? THEME_DARK : THEME_LIGHT;
}
// update iOS title bar color
@ -47,6 +47,6 @@ function updateTheme() {
}
export function watchThemeChanges() {
darkModeMatcher.addEventListener("change", updateTheme);
darkModeMatcher?.addEventListener("change", updateTheme);
updateTheme();
}

File diff suppressed because one or more lines are too long

119
dist/assets/index.9371aa6f.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
dist/index.html vendored
View file

@ -20,8 +20,8 @@
<meta name="theme-color" content="#020318" />
<title>evcc</title>
<script type="module" crossorigin src="./assets/index.43115d36.js"></script>
<link rel="stylesheet" href="./assets/index.24d10a15.css">
<script type="module" crossorigin src="./assets/index.9371aa6f.js"></script>
<link rel="stylesheet" href="./assets/index.df824c11.css">
</head>
<body>

3729
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -11,26 +11,16 @@
},
"main": "index.js",
"dependencies": {
"@babel/core": "^7.17.2",
"@h2d2/shopicons": "^1.2.0",
"@histoire/plugin-vue": "^0.11.6",
"@popperjs/core": "^2.11.5",
"@vitejs/plugin-vue": "^3.0.1",
"axios": "^0.27.2",
"@vue/compiler-sfc": "^3.2.30",
"axios": "^1.2.1",
"bootstrap": "^5.2.2",
"canvas-confetti": "^1.4.0",
"smoothscroll-polyfill": "^0.4.4",
"toml": "^3.0.0",
"vite-plugin-toml": "^0.5.0",
"vue": "^3.2.29",
"vue-hot-reload-api": "^2.3.4",
"vue-i18n": "^9.2.2",
"vue-meta": "^3.0.0-alpha.2",
"vue-number-animation": "^1.1.2",
"vue-router": "^4.0.12"
},
"devDependencies": {
"@babel/core": "^7.17.2",
"@histoire/plugin-vue": "^0.11.6",
"@vue/compiler-sfc": "^3.2.30",
"countup.js": "^2.3.2",
"eslint": "^8.27.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.25.3",
@ -41,9 +31,17 @@
"histoire": "^0.11.6",
"prettier": "^2.5.1",
"prettier-plugin-toml": "^0.3.1",
"rollup-plugin-analyzer": "^4.0.0",
"vite": "^3.0.4",
"vue-eslint-parser": "^9.1.0"
"rollup-plugin-visualizer": "^5.8.3",
"smoothscroll-polyfill": "^0.4.4",
"toml": "^3.0.0",
"vite": "^3.2.5",
"vite-plugin-toml": "^0.5.0",
"vue": "^3.2.29",
"vue-eslint-parser": "^9.1.0",
"vue-hot-reload-api": "^2.3.4",
"vue-i18n": "^9.2.2",
"vue-meta": "^3.0.0-alpha.2",
"vue-router": "^4.0.12"
},
"engines": {
"npm": ">=8.0.0",

View file

@ -1,7 +1,7 @@
import { defineConfig } from "vite";
import vuePlugin from "@vitejs/plugin-vue";
import { ViteToml } from "vite-plugin-toml";
//import analyze from "rollup-plugin-analyzer";
import { visualizer } from "rollup-plugin-visualizer";
export default defineConfig({
root: "./assets",
@ -35,6 +35,6 @@ export default defineConfig({
},
}),
ViteToml(),
//analyze(),
visualizer({ filename: "asset-stats.html" }),
],
});