From 8e586811ecc8bb59b3b1c5b0b645ac8dc8115190 Mon Sep 17 00:00:00 2001 From: Kevin Date: Mon, 23 Feb 2026 20:53:19 +0100 Subject: [PATCH] Feat: vite & upgraded dependencies (#100) * On every route change, update local variables from query params * ResultSection is keyed to query to force re-render * Resolved lint warnings * replace webpack w/ vite * update all imports with alias @ and scss * vite environment variables, also typed * upgraded eslint, defined new rules & added ignore comments * resolved linting issues * moved index.html to project root * updated dockerfile w/ build stage before runtime image definition * sign drone config --- .drone.yml | 21 +- .env.example | 7 +- .eslintrc | 31 - .gitignore | 1 + Dockerfile | 36 +- eslint.config.mjs | 67 + src/index.html => index.html | 4 +- nginx.conf | 2 +- package.json | 60 +- src/App.vue | 11 +- src/api.ts | 23 +- src/components/CastList.vue | 3 +- src/components/LandingBanner.vue | 4 +- src/components/PageHeader.vue | 6 +- src/components/Popup.vue | 6 +- src/components/ResultsList.vue | 4 +- src/components/ResultsListItem.vue | 6 +- src/components/ResultsSection.vue | 2 +- .../header/AutocompleteDropdown.vue | 19 +- src/components/header/NavigationHeader.vue | 4 +- src/components/header/NavigationIcon.vue | 11 +- src/components/header/NavigationIcons.vue | 2 +- src/components/header/SearchInput.vue | 24 +- src/components/popup/ActionButton.vue | 2 +- src/components/popup/Description.vue | 3 +- src/components/popup/Detail.vue | 2 +- src/components/popup/Movie.vue | 37 +- src/components/popup/Person.vue | 8 +- src/components/profile/ChangePassword.vue | 2 +- .../torrent/TorrentSearchResults.vue | 11 +- src/components/torrent/TorrentTable.vue | 6 +- .../torrent/TruncatedTorrentResults.vue | 2 +- src/components/ui/Hamburger.vue | 2 +- src/components/ui/Loader.vue | 2 +- src/components/ui/LoadingPlaceholder.vue | 2 +- src/components/ui/SeasonedButton.vue | 9 +- src/components/ui/SeasonedInput.vue | 4 +- src/components/ui/SeasonedMessages.vue | 4 +- src/components/ui/ToggleButton.vue | 2 +- src/directives/v-formatDate.js | 2 + src/directives/v-image.js | 12 +- src/interfaces/IAutocompleteSearch.ts | 1 - src/interfaces/IGraph.ts | 8 +- src/interfaces/IList.ts | 16 +- src/interfaces/INavigationIcon.ts | 2 +- src/interfaces/IStateTorrent.ts | 2 +- src/interfaces/ITorrent.ts | 2 +- src/main.ts | 6 +- src/modules/darkmodeModule.ts | 5 +- src/modules/documentTitle.ts | 3 +- src/modules/hamburger.ts | 1 + src/modules/popup.ts | 9 +- src/modules/torrentModule.ts | 13 +- src/pages/404Page.vue | 4 +- src/pages/ActivityPage.vue | 2 +- src/pages/ProfilePage.vue | 4 +- src/pages/RegisterPage.vue | 2 +- src/pages/SearchPage.vue | 2 +- src/pages/SettingsPage.vue | 4 +- src/pages/SigninPage.vue | 2 +- src/plugins/Toast/ToastComponent.vue | 4 +- src/routes.ts | 5 +- src/scss/elements.scss | 4 +- src/scss/loading-placeholder.scss | 2 +- src/scss/main.scss | 2 +- src/scss/media-queries.scss | 78 +- src/scss/variables.scss | 2 +- src/store.ts | 2 +- src/utils.ts | 12 +- src/vite-env.d.ts | 9 + tsconfig.json | 3 +- vite.config.ts | 14 + webpack.config.js | 157 - yarn.lock | 12741 ++++------------ 74 files changed, 3007 insertions(+), 10582 deletions(-) delete mode 100644 .eslintrc create mode 100644 eslint.config.mjs rename src/index.html => index.html (91%) create mode 100644 src/vite-env.d.ts create mode 100644 vite.config.ts delete mode 100644 webpack.config.js diff --git a/.drone.yml b/.drone.yml index 41de1c4..939dfdb 100644 --- a/.drone.yml +++ b/.drone.yml @@ -25,7 +25,7 @@ steps: path: /cache - name: Frontend install - image: node:18.2.0 + image: node:24.13.1 commands: - node -v - yarn --version @@ -42,8 +42,14 @@ steps: - name: cache path: /cache + - name: Lint project using eslint + image: node:24.13.1 + commands: + - yarn lint + failure: ignore + - name: Frontend build - image: node:18.2.0 + image: node:24.13.1 commands: - yarn build environment: @@ -56,12 +62,6 @@ steps: SEASONED_DOMAIN: from_secret: SEASONED_DOMAIN - - name: Lint project using eslint - image: node:18.2.0 - commands: - - yarn lint - failure: ignore - - name: Build and publish docker image image: plugins/docker settings: @@ -105,3 +105,8 @@ trigger: include: - push # - pull_request +--- +kind: signature +hmac: 6f10b2871d2bd6b5cd26ddf72796325991ba211ba1eb62b657baf993e9d549c8 + +... diff --git a/.env.example b/.env.example index 78b073f..da0dc81 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,3 @@ -SEASONED_API= -ELASTIC= -ELASTIC_INDEX=shows,movies -SEASONED_DOMAIN= \ No newline at end of file +SEASONED_API=http://localhost:31459 +ELASTIC_URL=http://elastic.local:9200/tmdb-movies-shows +ELASTIC_API_KEY= diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index cbeec6e..0000000 --- a/.eslintrc +++ /dev/null @@ -1,31 +0,0 @@ -{ - "root": true, - "parser": "vue-eslint-parser", - "parserOptions": { - "parser": "@typescript-eslint/parser", - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "@vue/eslint-config-airbnb", - "plugin:vue/recommended", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended", - ], - "rules": { - "vue/no-v-model-argument": "off", - "no-underscore-dangle": "off", - "vue/multi-word-component-names": "off", - "no-shadow": "off", - "@typescript-eslint/no-shadow": ["error"], - }, - "settings": { - "import/resolver": { - webpack: { - config: "./webpack.config.js" - } - } - } -} diff --git a/.gitignore b/.gitignore index 93bd3be..e75c9fe 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ src/config.json # Build directory dist/ +lib/ # Node packages node_modules/ diff --git a/Dockerfile b/Dockerfile index fa3e0f3..3187dbd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,39 @@ -FROM nginx:latest +FROM node:24.13.1 AS build -COPY public /usr/share/nginx/html +# Set the working directory for the build stage +WORKDIR /app + +# Install dependencies +COPY package.json yarn.lock . +RUN yarn install --frozen-lockfile + +# Copy source files that the build depends on +COPY index.html . +COPY public/ public/ +COPY src/ src/ +COPY tsconfig.json vite.config.ts . + +ARG SEASONED_API=http://localhost:31459 +ENV VITE_SEASONED_API=$SEASONED_API + +ARG ELASTIC_URL=http://elastic.local:9200/tmdb-movies-shows +ENV VITE_ELASTIC_URL=$ELASTIC_URL +ARG ELASTIC_API_KEY= +ENV VITE_ELASTIC_API_KEY=$ELASTIC_API_KEY + +RUN yarn build + +FROM nginx:1.29.5 + +# Copy the static build from the previous stage +COPY index.html /usr/share/nginx/html +COPY public/ /usr/share/nginx/html +COPY --from=build /app/dist /usr/share/nginx/html + +# Copy nginx config file COPY nginx.conf /etc/nginx/conf.d/default.conf.template + +# Manual entrypoint after nginx substring COPY docker-entrypoint.sh /docker-entrypoint.d/05-docker-entrypoint.sh RUN chmod +x /docker-entrypoint.d/05-docker-entrypoint.sh diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..6a8cafc --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,67 @@ +import path from "node:path"; + +import { includeIgnoreFile } from "@eslint/compat"; +import js from "@eslint/js"; +import { defineConfig } from "eslint/config"; +import { configs, plugins } from "eslint-config-airbnb-extended"; +import { rules as prettierConfigRules } from "eslint-config-prettier"; +import prettierPlugin from "eslint-plugin-prettier"; + +const CUSTOM_RULES = { + "vue/no-v-model-argument": "off", + "no-underscore-dangle": "off", + "vue/multi-word-component-names": "off", + "no-shadow": "off", + "@typescript-eslint/no-shadow": ["error"] +}; + +const gitignorePath = path.resolve(".", ".gitignore"); + +// ESLint recommended config +const jsConfig = defineConfig([ + { + name: "js/config", + ...js.configs.recommended + }, + plugins.stylistic, + plugins.importX, + ...configs.base.recommended // Airbnb base recommended config +]); + +// Node & Airbnb recommended config +const nodeConfig = defineConfig([plugins.node, ...configs.node.recommended]); + +// Typescript & Airbnb base TS config +const typescriptConfig = defineConfig([ + plugins.typescriptEslint, + ...configs.base.typescript +]); + +// Prettier config +const prettierConfig = defineConfig([ + { + name: "prettier/plugin/config", + plugins: { + prettier: prettierPlugin + } + }, + { + name: "prettier/config", + rules: { + ...prettierConfigRules, + "prettier/prettier": "error" + } + } +]); + +export default defineConfig([ + // Ignore files and folders listed in .gitignore + includeIgnoreFile(gitignorePath), + ...jsConfig, + ...nodeConfig, + ...typescriptConfig, + ...prettierConfig, + { + rules: CUSTOM_RULES + } +]); diff --git a/src/index.html b/index.html similarity index 91% rename from src/index.html rename to index.html index 021490c..555c1b7 100644 --- a/src/index.html +++ b/index.html @@ -24,7 +24,9 @@ -
+
+ + diff --git a/src/components/ui/SeasonedButton.vue b/src/components/ui/SeasonedButton.vue index e51df58..2f82c50 100644 --- a/src/components/ui/SeasonedButton.vue +++ b/src/components/ui/SeasonedButton.vue @@ -23,8 +23,8 @@