build(webui): upgrade vue cli to v5

This commit is contained in:
Gauthier Roebroeck 2023-09-13 15:14:28 +08:00
parent 854098cdda
commit 9ef46b3ae7
9 changed files with 17357 additions and 20858 deletions

View File

@ -155,7 +155,7 @@ jobs:
- name: Build
uses: gradle/gradle-build-action@v2
with:
arguments: :komga:copyWebDist :komga:bootJar :komga-tray:jar
arguments: :komga:prepareThymeLeaf :komga:bootJar :komga-tray:jar
- name: Generate OpenAPI docs
uses: gradle/gradle-build-action@v2
with:

View File

@ -40,7 +40,8 @@ The backend project uses `gradle` to run all the necessary tasks. If your IDE do
Here is a list of useful tasks:
- `bootRun`: run the application locally, useful for testing your changes.
- `copyWebDist`: build the frontend, and copy the bundle to `/resources/public`. You need to run this manually if you want to test the latest frontend build hosted by Spring.
- `prepareThymeLeaf`: build the frontend, and copy the bundle to `/resources/public`. You need to run this manually if
you want to test the latest frontend build hosted by Spring.
- `test`: run automated tests. Always run this before committing.
- `jooq-codegen-primary`: generates the jOOQ DSL.
@ -67,6 +68,7 @@ Make sure you start the backend with the `dev` profile, else the frontend reques
## Docker
To build the Docker image, you need to:
- have the webui built and copied to `/resources/public`. To do so, run `./gradlew copyWebDist`
- have the webui built and copied to `/resources/public`. To do so, run `./gradlew prepareThymeLeaf`
- prepare the docker image via JReleaser. To do so, run `./gradlew jreleaserPackage`
- the `Dockerfile` will be available in `komga/build/jreleaser/package/docker/`

View File

@ -1,38 +1,3 @@
module.exports = {
moduleFileExtensions: [
'js',
'jsx',
'json',
'vue',
'ts',
'tsx',
],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.tsx?$': 'ts-jest',
},
transformIgnorePatterns: [
'/node_modules/',
],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
snapshotSerializers: [
'jest-serializer-vue',
],
setupFiles: ['jest-canvas-mock'],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)',
],
testURL: 'http://localhost/',
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
globals: {
'ts-jest': {
babelConfig: true,
},
},
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
}

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
"@saekitominaga/isbn-verify": "^1.4.1",
"axios": "^0.26.1",
"chart.js": "^2.9.4",
"core-js": "^3.22.2",
"core-js": "^3.8.3",
"date-fns": "^2.28.0",
"filesize": "^8.0.7",
"js-file-downloader": "^1.1.24",
@ -36,40 +36,41 @@
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
"@babel/core": "^7.16.12",
"@mdi/font": "^6.5.95",
"@types/chart.js": "^2.9.36",
"@types/jest": "^24.9.1",
"@types/jest": "^27.0.1",
"@types/lodash": "^4.14.182",
"@types/vue-chartkick": "^0.5.1",
"@types/vuelidate": "^0.7.15",
"@types/webpack": "^4.41.32",
"@typescript-eslint/eslint-plugin": "^4.33.0",
"@typescript-eslint/parser": "^4.33.0",
"@vue/cli-plugin-babel": "^4.5.15",
"@vue/cli-plugin-eslint": "^4.5.15",
"@vue/cli-plugin-router": "^4.5.15",
"@vue/cli-plugin-typescript": "^4.5.15",
"@vue/cli-plugin-unit-jest": "^4.5.15",
"@vue/cli-plugin-vuex": "^4.5.15",
"@vue/cli-service": "^4.5.15",
"@vue/eslint-config-standard": "^5.1.2",
"@vue/eslint-config-typescript": "^7.0.0",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@vue/cli-plugin-babel": "^5.0.8",
"@vue/cli-plugin-eslint": "^5.0.8",
"@vue/cli-plugin-router": "^5.0.8",
"@vue/cli-plugin-typescript": "^5.0.8",
"@vue/cli-plugin-unit-jest": "^5.0.8",
"@vue/cli-plugin-vuex": "^5.0.8",
"@vue/cli-service": "^5.0.8",
"@vue/eslint-config-standard": "^6.1.0",
"@vue/eslint-config-typescript": "^9.1.0",
"@vue/test-utils": "1.3.0",
"eslint": "^6.8.0",
"@vue/vue2-jest": "^27.0.0",
"babel-jest": "^27.0.6",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.3.1",
"eslint-plugin-vue": "^7.12.1",
"html-webpack-inject-attributes-plugin": "^1.0.6",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-vue": "^8.0.3",
"jest": "^27.0.5",
"jest-canvas-mock": "^2.3.1",
"sass": "^1.32.13",
"sass-loader": "^10.2.0",
"ts-jest": "^24.3.0",
"ts-jest": "^27.0.4",
"typeface-roboto": "1.1.13",
"typescript": "^3.9.10",
"vue-cli-plugin-i18n": "~2.3.1",
"vue-cli-plugin-vuetify": "^2.4.8",
"typescript": "~4.5.5",
"vue-cli-plugin-i18n": "~2.3.2",
"vue-cli-plugin-vuetify": "~2.5.8",
"vue-template-compiler": "^2.6.14",
"vuetify-loader": "^1.7.3"
}

View File

@ -7,13 +7,13 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<title>Komga</title>
<link rel="icon" href="/favicon.ico" th:href="@{/favicon.ico}">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" th:href="@{/apple-touch-icon.png}">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" th:href="@{/favicon-32x32.png}">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" th:href="@{/favicon-16x16.png}">
<link rel="icon" href="/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<meta name="msapplication-TileColor" content="#08397f">
<meta name="msapplication-TileImage" th:content="@{/mstile-144x144.png}" content="/mstile-144x144.png">
<link rel="manifest" th:href="@{/manifest.json}" href="/manifest.json">
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
<link rel="manifest" href="/manifest.json">
<script th:inline="javascript">
/*<![CDATA[*/
window.resourceBaseUrl = /*[(<%="$"%>{"'" + baseUrl + "'"})]*/ '/'

View File

@ -9,6 +9,7 @@
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"useUnknownInCatchVariables": false,
"baseUrl": ".",
"types": [
"webpack-env",
@ -35,7 +36,5 @@
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
"exclude": []
}

View File

@ -1,42 +1,8 @@
const htmlInject = require('html-webpack-inject-attributes-plugin')
const _ = require('lodash')
// vue.config.js
module.exports = {
publicPath: '/',
chainWebpack: (config) => {
config.plugins.delete('prefetch') // conflicts with htmlInject
config.plugins.delete('preload') // conflicts with htmlInject
config.plugin('html')
.tap(args => {
args[0].attributes = {
'th:href': function (tag) {
if (_.has(tag, 'attributes.href')) {
return `@{${tag.attributes.href}}`
}
return false
},
'th:content': function (tag) {
if (_.has(tag, 'attributes.content')) {
return `@{${tag.attributes.content}}`
}
return false
},
'th:src': function (tag) {
if (_.has(tag, 'attributes.src')) {
return `@{${tag.attributes.src}}`
}
return false
},
}
return args
})
config.plugin('html-inject')
.after('html')
.use(htmlInject)
},
// with './' the dev server cannot load any arbitrary path
// with '/' the prod build generates some url(/fonts…) calls in the css chunks, which doesn't work with a servlet context path
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
pluginOptions: {
i18n: {

View File

@ -1,6 +1,7 @@
import org.apache.tools.ant.taskdefs.condition.Os
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.util.prefixIfNot
plugins {
run {
@ -202,11 +203,24 @@ tasks {
into("$projectDir/src/main/resources/public/")
}
// modifies index.html to inject ThymeLeaf th: tags
register<Copy>("prepareThymeLeaf") {
group = "web"
dependsOn("copyWebDist")
from("$webui/dist/index.html")
into("$projectDir/src/main/resources/public/")
filter { line ->
line.replace("((?:src|content|href)=\")([\\w]*/.*?)(\")".toRegex()) {
it.groups[0]?.value + " th:" + it.groups[1]?.value + "@{" + it.groups[2]?.value?.prefixIfNot("/") + "}" + it.groups[3]?.value
}
}
}
withType<ProcessResources> {
filesMatching("application*.yml") {
expand(project.properties)
}
mustRunAfter(getByName("copyWebDist"))
mustRunAfter(getByName("prepareThymeLeaf"))
}
register<Test>("benchmark") {