فهرست منبع

feat(webapp): migrate to `vite`

Vite is faster than the old `vue-cli`. For new `vue` projects it is the default build system.

https://vitejs.dev/
---
docker: change env vars to `vite` schema

* Replace prefix `VUE_` by `VITE_`.
* Update option to not delete output dir.
* Remove unused environment variables
Rotzbua 1 سال پیش
والد
کامیت
59e5d87884

+ 6 - 8
docker-compose.dev.yml

@@ -70,15 +70,13 @@ services:
     volumes:
     - ./www/webapp/:/usr/src/app/
     working_dir: /usr/src/app/
-    command: bash -c "npm install && npm run serve --fix"
+    command: bash -c "npm install && npm run dev -- --host"
     environment:
-    - CODESANDBOX_SSE=1  # so that ws: protocol ends up as auto: in node_modules/@vue/cli-service/lib/commands/serve.js
-    - CYPRESS_CACHE_FOLDER=/tmp/.cache  # https://github.com/cypress-io/cypress/issues/1281#issuecomment-404823001
-    - VUE_APP_DESECSTACK_NS=${DESECSTACK_NS}
-    - VUE_APP_DESECSTACK_API_SEPA_CREDITOR_ID=${DESECSTACK_API_SEPA_CREDITOR_ID}
-    - VUE_APP_DESECSTACK_API_SEPA_CREDITOR_NAME=${DESECSTACK_API_SEPA_CREDITOR_NAME}
-    - VUE_APP_LOCAL_PUBLIC_SUFFIXES=dedyn.${DESECSTACK_DOMAIN}
-    - VUE_APP_EMAIL=support@desec.${DESECSTACK_DOMAIN}
+    - VITE_APP_DESECSTACK_NS=${DESECSTACK_NS}
+    - VITE_APP_DESECSTACK_API_SEPA_CREDITOR_ID=${DESECSTACK_API_SEPA_CREDITOR_ID}
+    - VITE_APP_DESECSTACK_API_SEPA_CREDITOR_NAME=${DESECSTACK_API_SEPA_CREDITOR_NAME}
+    - VITE_APP_LOCAL_PUBLIC_SUFFIXES=dedyn.${DESECSTACK_DOMAIN}
+    - VITE_APP_EMAIL=support@desec.${DESECSTACK_DOMAIN}
     networks:
     - rearwebapp
     logging:

+ 6 - 6
www/Dockerfile

@@ -14,14 +14,14 @@ ARG DESECSTACK_API_SEPA_CREDITOR_ID
 ARG DESECSTACK_API_SEPA_CREDITOR_NAME
 ARG DESECSTACK_DOMAIN
 ARG DESECSTACK_NS
-ENV VUE_APP_DESECSTACK_NS=${DESECSTACK_NS} \
-    VUE_APP_DESECSTACK_API_SEPA_CREDITOR_ID=${DESECSTACK_API_SEPA_CREDITOR_ID} \
-    VUE_APP_DESECSTACK_API_SEPA_CREDITOR_NAME=${DESECSTACK_API_SEPA_CREDITOR_NAME} \
-    VUE_APP_LOCAL_PUBLIC_SUFFIXES=dedyn.${DESECSTACK_DOMAIN} \
-    VUE_APP_EMAIL=support@desec.${DESECSTACK_DOMAIN}
+ENV VITE_APP_DESECSTACK_NS=${DESECSTACK_NS} \
+    VITE_APP_DESECSTACK_API_SEPA_CREDITOR_ID=${DESECSTACK_API_SEPA_CREDITOR_ID} \
+    VITE_APP_DESECSTACK_API_SEPA_CREDITOR_NAME=${DESECSTACK_API_SEPA_CREDITOR_NAME} \
+    VITE_APP_LOCAL_PUBLIC_SUFFIXES=dedyn.${DESECSTACK_DOMAIN} \
+    VITE_APP_EMAIL=support@desec.${DESECSTACK_DOMAIN}
 
 COPY webapp/ /usr/src/app/
-RUN npm run build -- --no-clean
+RUN npm run build -- --emptyOutDir false
 
 
 FROM nginx:mainline-alpine

+ 0 - 1
www/webapp/.eslintrc.js

@@ -5,7 +5,6 @@ module.exports = {
   root: true,
   env: {
     browser: true,
-    node: true, // Can be removed after migration to vite.
     es2024: true,
   },
   parserOptions: {

+ 2 - 2
www/webapp/README.md

@@ -7,7 +7,7 @@ npm install
 
 ### Compiles and hot-reloads for development
 ```
-npm run serve
+npm run dev
 ```
 
 ### Compiles and minifies for production
@@ -21,4 +21,4 @@ npm run lint
 ```
 
 ### Customize configuration
-See [Configuration Reference](https://cli.vuejs.org/config/).
+See [Configuration Reference](https://vitejs.dev/config/).

+ 0 - 5
www/webapp/babel.config.js

@@ -1,5 +0,0 @@
-module.exports = {
-  presets: [
-    '@vue/cli-plugin-babel/preset'
-  ]
-}

+ 3 - 2
www/webapp/public/index.html → www/webapp/index.html

@@ -3,8 +3,8 @@
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <link rel="icon" href="<%= BASE_URL %>favicon.svg" sizes="any">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <link rel="icon" href="/favicon.svg" sizes="any">
+    <link rel="icon" href="/favicon.ico">
     <title>deSEC – Free Secure DNS</title>
   </head>
   <body>
@@ -26,6 +26,7 @@
       </p>
     </noscript>
     <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
     <!-- built files will be auto injected -->
   </body>
 </html>

+ 9 - 12
www/webapp/package.json

@@ -3,8 +3,9 @@
   "version": "0.1.0",
   "private": true,
   "scripts": {
-    "serve": "vue-cli-service serve",
-    "build": "vue-cli-service build",
+    "dev": "vite",
+    "serve": "vite preview",
+    "build": "vite build",
     "lint": "eslint --ignore-path .gitignore --no-fix src/**/*.{vue,js,json}",
     "lint:fix": "eslint --ignore-path .gitignore --fix src/**/*.{vue,js,json}"
   },
@@ -13,27 +14,23 @@
     "@mdi/font": "^7.2.96",
     "@mdi/js": "~7.2.96",
     "axios": "^1.4.0",
-    "core-js": "^3.27.1",
     "date-fns": "^2.30.0",
     "pinia": "^2.0.30",
     "vue": "~2.7.14",
     "vue-router": "~3.6.5",
     "vuelidate": "^0.7.7",
-    "vuetify": "^2.6.13"
+    "vuetify": "^2.7.0"
   },
   "devDependencies": {
-    "@vue/cli-plugin-babel": "^5.0.8",
-    "@vue/cli-plugin-router": "^5.0.8",
-    "@vue/cli-service": "^5.0.8",
-    "eslint": "^8.31.0",
+    "@vitejs/plugin-vue2": "^2.2.0",
+    "eslint": "^8.45.0",
     "eslint-import-resolver-alias": "^1.1.2",
     "eslint-plugin-import": "^2.27.5",
-    "eslint-plugin-vue": "^9.8.0",
+    "eslint-plugin-vue": "^9.15.1",
     "eslint-plugin-vuetify": "^1.1.0",
     "sass": "~1.64.2",
-    "sass-loader": "^13.2.0",
-    "vue-cli-plugin-vuetify": "^2.5.8",
-    "vue-template-compiler": "^2.7.14",
+    "unplugin-vue-components": "^0.25.1",
+    "vite": "^4.4.5",
     "vuetify-loader": "~1.9.1"
   }
 }

+ 0 - 5
www/webapp/postcss.config.js

@@ -1,5 +0,0 @@
-module.exports = {
-  plugins: {
-    autoprefixer: {}
-  }
-}

+ 1 - 1
www/webapp/src/App.vue

@@ -199,7 +199,7 @@ export default {
   data: () => ({
     user: useUserStore(),
     drawer: false,
-    email: process.env.VUE_APP_EMAIL,
+    email: import.meta.env.VITE_APP_EMAIL,
     mdiHeart,
     mdiMenuDown,
     tabmenu: {

+ 1 - 1
www/webapp/src/components/ActivateAccountActionHandler.vue

@@ -78,7 +78,7 @@
     data: () => ({
       auto_submit: true,
       captchaWorking: false,
-      LOCAL_PUBLIC_SUFFIXES: process.env.VUE_APP_LOCAL_PUBLIC_SUFFIXES.split(' '),
+      LOCAL_PUBLIC_SUFFIXES: import.meta.env.VITE_APP_LOCAL_PUBLIC_SUFFIXES.split(' '),
       captcha: null,
       captcha_required: false,
 

+ 2 - 2
www/webapp/src/components/DonateDirectDebitForm.vue

@@ -128,8 +128,8 @@
       mdiEmail,
 
       /* from env */
-      creditorid: process.env.VUE_APP_DESECSTACK_API_SEPA_CREDITOR_ID,
-      creditorname: process.env.VUE_APP_DESECSTACK_API_SEPA_CREDITOR_NAME,
+      creditorid: import.meta.env.VITE_APP_DESECSTACK_API_SEPA_CREDITOR_ID,
+      creditorname: import.meta.env.VITE_APP_DESECSTACK_API_SEPA_CREDITOR_NAME,
 
       /* account holder name field */
       name: '',

+ 1 - 1
www/webapp/src/router/index.js

@@ -141,7 +141,7 @@ const routes = [
 
 const router = new VueRouter({
   mode: 'history',
-  base: process.env.BASE_URL,
+  base: import.meta.env.BASE_URL,
   scrollBehavior (to, from) {
     // Skip if destination full path has query parameters and differs in no other way from previous
     if (from && Object.keys(to.query).length) {

+ 2 - 2
www/webapp/src/views/DomainSetup.vue

@@ -154,7 +154,7 @@ export default {
     },
     ns: {
       type: Array,
-      default: () => process.env.VUE_APP_DESECSTACK_NS.split(' '),
+      default: () => import.meta.env.VITE_APP_DESECSTACK_NS.split(' '),
     },
   },
   data: () => ({
@@ -171,7 +171,7 @@ export default {
     snackbar_text: '',
     tab1: 'ns',
     tab2: 'ds',
-    LOCAL_PUBLIC_SUFFIXES: process.env.VUE_APP_LOCAL_PUBLIC_SUFFIXES.split(' '),
+    LOCAL_PUBLIC_SUFFIXES: import.meta.env.VITE_APP_LOCAL_PUBLIC_SUFFIXES.split(' '),
   }),
   computed: {
     tabs: function () {

+ 1 - 1
www/webapp/src/views/DynSetup.vue

@@ -191,7 +191,7 @@
       errors: [],
       ips: undefined,
       token: undefined,
-      LOCAL_PUBLIC_SUFFIXES: process.env.VUE_APP_LOCAL_PUBLIC_SUFFIXES.split(' '),
+      LOCAL_PUBLIC_SUFFIXES: import.meta.env.VITE_APP_LOCAL_PUBLIC_SUFFIXES.split(' '),
       lastChanged: undefined,
     }),
     async mounted() {

+ 1 - 1
www/webapp/src/views/HomePage.vue

@@ -246,7 +246,7 @@ export default {
   },
   data: () => ({
     mdiEmail,
-    contact_email: process.env.VUE_APP_EMAIL,
+    contact_email: import.meta.env.VITE_APP_EMAIL,
     contact_subject: 'Adopting of a Frontend Server',
     contact_body: 'Dear deSEC,\n\nI would like to adopt a frontend server in your networks!',
     domainType: null,

+ 1 - 1
www/webapp/src/views/ImpressumPage.vue

@@ -23,7 +23,7 @@
   export default {
     name: 'ImpressumPage',
     data: () => ({
-      email: process.env.VUE_APP_EMAIL,
+      email: import.meta.env.VITE_APP_EMAIL,
     }),
   }
 </script>

+ 1 - 1
www/webapp/src/views/PrivacyPolicy.vue

@@ -96,7 +96,7 @@
   export default {
     name: 'PrivacyPolicy',
     data: () => ({
-      email: process.env.VUE_APP_EMAIL,
+      email: import.meta.env.VITE_APP_EMAIL,
       privacy_policy: [
         {
           title: 'Visiting this Website',

+ 1 - 1
www/webapp/src/views/SignUp.vue

@@ -178,7 +178,7 @@
   import {digestError} from '@/utils';
   import ErrorAlert from "@/components/ErrorAlert.vue";
 
-  const LOCAL_PUBLIC_SUFFIXES = process.env.VUE_APP_LOCAL_PUBLIC_SUFFIXES.split(' ');
+  const LOCAL_PUBLIC_SUFFIXES = import.meta.env.VITE_APP_LOCAL_PUBLIC_SUFFIXES.split(' ');
 
   const HTTP = axios.create({
     baseURL: '/api/v1/',

+ 24 - 0
www/webapp/vite.config.js

@@ -0,0 +1,24 @@
+/* eslint-env node */
+import {defineConfig} from 'vite'
+import {resolve} from 'node:path';
+import Components from 'unplugin-vue-components/vite'
+import {VuetifyResolver} from 'unplugin-vue-components/resolvers'
+import vue from '@vitejs/plugin-vue2'
+
+export default defineConfig({
+    plugins: [
+        vue(),
+        Components({
+            resolvers: [VuetifyResolver()],
+        }),
+    ],
+    server: {
+        port: 8080,
+    },
+    resolve: {
+        alias: [{
+            find: '@', replacement: resolve(__dirname, 'src')
+        }],
+        extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
+    },
+})

+ 0 - 17
www/webapp/vue.config.js

@@ -1,17 +0,0 @@
-/** @type {import('@vue/cli-service').ProjectOptions} */
-module.exports = {
-  configureWebpack: {
-    devServer: {
-      allowedHosts: 'all',
-    },
-  },
-  chainWebpack: config => {
-    config.module
-      .rule('fonts')
-      .set('parser', {
-        dataUrlCondition: {
-          maxSize: 0 // Disable inline font to improve FCP (first contentful paint).
-        }
-      });
-  },
-};