Skip to content

Commit

Permalink
Refactor and upgrade the frontend vue code to work with vite instead …
Browse files Browse the repository at this point in the history
…of webpack.

- Upgrade eslint and fix a massive number (~2500!) of linting errors from new rules.
- Upgrade babel core frontend dev dependency.
- Upgrade UI lib and other frontend deps.
- Refactor the Vue admin app to use `vite` instead of `webpack`.
- This was an extremely tedious and painstaking, trial-and-error
  alchemy job. My disdain for the Javascript "ecosystem" grows.
- Re-add custom admin appearance endpoints to the refactored Vue page.
- Remove obsolete vue-cli config.
- Re-auto-format all .vue files again to work with new linters.
  • Loading branch information
knadh committed Dec 25, 2023
1 parent 51af75c commit af8b420
Show file tree
Hide file tree
Showing 51 changed files with 2,853 additions and 6,945 deletions.
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ FRONTEND_DIST = frontend/dist
FRONTEND_DEPS = \
$(FRONTEND_YARN_MODULES) \
frontend/package.json \
frontend/vue.config.js \
frontend/babel.config.js \
frontend/vite.config.js \
frontend/.eslintrc.js \
$(shell find frontend/fontello frontend/public frontend/src -type f)

BIN := listmonk
Expand Down Expand Up @@ -57,7 +57,7 @@ build-frontend: $(FRONTEND_DIST)
# Run the JS frontend server in dev mode.
.PHONY: run-frontend
run-frontend:
export VUE_APP_VERSION="${VERSION}" && cd frontend && $(YARN) serve
export VUE_APP_VERSION="${VERSION}" && cd frontend && $(YARN) dev

# Run Go tests.
.PHONY: test
Expand Down
25 changes: 19 additions & 6 deletions frontend/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,29 @@ module.exports = {
root: true,
env: {
node: true,
// es2022: true,
},
plugins: ['vue'],
extends: [
'eslint:recommended',
'plugin:vue/essential',
'@vue/airbnb',
'plugin:vue/strongly-recommended',
'@vue/eslint-config-airbnb',
],
parserOptions: {
parser: '@babel/eslint-parser',
},
parser: 'vue-eslint-parser',
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'class-methods-use-this': 'off',
'vue/multi-word-component-names': 'off',
'vue/quote-props': 'off',
'vue/first-attribute-linebreak': 'off',
'vue/no-child-content': 'off',
'vue/max-attributes-per-line': 'off',
'vue/html-indent': 'off',
'vue/html-closing-bracket-newline': 'off',
'vue/max-len': ['error', {
code: 200,
template: 200,
comments: 200,
}],
},
};
2 changes: 1 addition & 1 deletion frontend/cypress/support/e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ beforeEach(() => {
req.destroy();
});

cy.intercept('GET', '/api/health/**', (req) => {
cy.intercept('GET', '/api/health', (req) => {
req.reply({});
});
});
21 changes: 21 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="/admin/static/favicon.png" />
<link href="/admin/custom.css" rel="stylesheet" type="text/css">
<script src="/admin/custom.js" async defer></script>
<title>listmonk</title>
</head>
<body>
<noscript>
<strong>We're sorry but listmonk doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>

<div id="app"></div>

<script type="module" src="/src/main.js"></script>
</body>
</html>
8 changes: 8 additions & 0 deletions frontend/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules", "dist"]
}
41 changes: 19 additions & 22 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,42 @@
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build-report": "vue-cli-service build --report",
"lint": "vue-cli-service lint"
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore src",
"prebuild": "eslint --ext .js,.vue --ignore-path .gitignore src"
},
"dependencies": {
"@tinymce/tinymce-vue": "^3",
"axios": "^1.6.0",
"buefy": "^0.9.10",
"axios": "^1.6.2",
"buefy": "^0.9.25",
"bulma": "^0.9.4",
"c3": "^0.7.20",
"codeflask": "^1.4.1",
"core-js": "^3.12.1",
"dayjs": "^1.10.4",
"dayjs": "^1.11.10",
"indent.js": "^0.3.5",
"qs": "^6.10.1",
"textversionjs": "^1.1.3",
"tinymce": "^5.10.9",
"turndown": "^7.0.0",
"vue": "^2.6.12",
"vue-i18n": "^8.22.2",
"turndown": "^7.1.2",
"vue": "^2.7.14",
"vue-i18n": "^8.28.2",
"vue-router": "^3.2.0",
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.23.3",
"@babel/eslint-parser": "^7.23.3",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"@vue/eslint-config-airbnb": "^5.3.0",
"@vitejs/plugin-vue2": "^2.3.1",
"@vue/eslint-config-airbnb": "^7.0.1",
"cypress": "13.6.1",
"cypress-file-upload": "^5.0.2",
"eslint": "^7.27.0",
"eslint": "^8.56.0",
"eslint-define-config": "^2.0.0",
"eslint-plugin-import": "^2.23.3",
"eslint-plugin-vue": "^7.9.0",
"eslint-plugin-vue": "^9.19.2",
"sass": "^1.34.0",
"sass-loader": "^10.2.0",
"vite": "^5.0.10",
"vue-eslint-parser": "^9.3.2",
"vue-template-compiler": "^2.6.12"
}
}
19 changes: 0 additions & 19 deletions frontend/public/index.html

This file was deleted.

55 changes: 24 additions & 31 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,37 +1,30 @@
<template>
<div id="app">
<b-navbar :fixed-top="true" v-if="$root.isLoaded">
<template #brand>
<div class="logo">
<router-link :to="{name: 'dashboard'}">
<img class="full" src="@/assets/logo.svg"/>
<img class="favicon" src="@/assets/favicon.png"/>
</router-link>
</div>
</template>
<template #end>
<navigation v-if="isMobile" :isMobile="isMobile"
:activeItem="activeItem" :activeGroup="activeGroup" @toggleGroup="toggleGroup"
@doLogout="doLogout" />
<b-navbar-item v-else tag="div">
<a href="#" @click.prevent="doLogout">{{ $t('users.logout') }}</a>
</b-navbar-item>
</template>
<template #brand>
<div class="logo">
<router-link :to="{ name: 'dashboard' }">
<img class="full" src="@/assets/logo.svg" alt="" />
<img class="favicon" src="@/assets/favicon.png" alt="" />
</router-link>
</div>
</template>
<template #end>
<navigation v-if="isMobile" :is-mobile="isMobile" :active-item="activeItem" :active-group="activeGroup"
@toggleGroup="toggleGroup" @doLogout="doLogout" />
<b-navbar-item v-else tag="div">
<a href="#" @click.prevent="doLogout">{{ $t('users.logout') }}</a>
</b-navbar-item>
</template>
</b-navbar>

<div class="wrapper" v-if="$root.isLoaded">
<section class="sidebar">
<b-sidebar
position="static"
mobile="hide"
:fullheight="true"
:open="true"
:can-cancel="false"
>
<b-sidebar position="static" mobile="hide" :fullheight="true" :open="true" :can-cancel="false">
<div>
<b-menu :accordion="false">
<navigation v-if="!isMobile" :isMobile="isMobile"
:activeItem="activeItem" :activeGroup="activeGroup" @toggleGroup="toggleGroup" />
<navigation v-if="!isMobile" :is-mobile="isMobile" :active-item="activeItem" :active-group="activeGroup"
@toggleGroup="toggleGroup" />
</b-menu>
</div>
</b-sidebar>
Expand All @@ -43,15 +36,15 @@
<div class="global-notices" v-if="serverConfig.needs_restart || serverConfig.update">
<div v-if="serverConfig.needs_restart" class="notification is-danger">
{{ $t('settings.needsRestart') }}
&mdash;
&mdash;
<b-button class="is-primary" size="is-small"
@click="$utils.confirm($t('settings.confirmRestart'), reloadApp)">
{{ $t('settings.restart') }}
{{ $t('settings.restart') }}
</b-button>
</div>
<div v-if="serverConfig.update" class="notification is-success">
{{ $t('settings.updateAvailable', { version: serverConfig.update.version }) }}
<a :href="serverConfig.update.url" target="_blank">View</a>
<a :href="serverConfig.update.url" target="_blank" rel="noopener noreferer">View</a>
</div>
</div>

Expand Down Expand Up @@ -157,7 +150,7 @@ export default Vue.extend({
...mapState(['serverConfig']),
version() {
return process.env.VUE_APP_VERSION;
return import.meta.env.VUE_APP_VERSION;
},
isMobile() {
Expand All @@ -180,6 +173,6 @@ export default Vue.extend({
</script>

<style lang="scss">
@import "assets/style.scss";
@import "assets/icons/fontello.css";
@import "assets/style.scss";
@import "assets/icons/fontello.css";
</style>
Loading

0 comments on commit af8b420

Please sign in to comment.