Repository: owncloud/web
Pull request #12327: chore: use prettier config instead of plugin
Author: login: LukasHirt
Created: 2025-03-18T10:27:50Z | Merged: 2025-03-18T11:58:16Z

## Description

Using the plugin hurts performance of eslint too much.

## Related Issue

- Fixes https://github.com/owncloud/web/issues/12051

## Motivation and Context

Faster linting

## How Has This Been Tested?

- test environment: 🤖 

## Types of changes

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [ ] Tests
- [ ] Documentation
- [x] Maintenance (e.g. dependency updates or tooling)



Diff:
diff --git a/.drone.star b/.drone.star
index 0bcd0568c48..b0a2dd628d5 100644
--- a/.drone.star
+++ b/.drone.star
@@ -279,7 +279,8 @@ def pnpmlint(ctx):
         "steps": skipIfUnchanged(ctx, "lint") +
                  restoreBuildArtifactCache(ctx, "pnpm", ".pnpm-store") +
                  installPnpm() +
-                 lint(),
+                 lint() +
+                 checkFormatting(),
         "trigger": {
             "ref": [
                 "refs/heads/master",
@@ -745,6 +746,15 @@ def lint():
         ],
     }]
 
+def checkFormatting():
+    return [{
+        "name": "check-formatting",
+        "image": OC_CI_NODEJS,
+        "commands": [
+            "pnpm check:format",
+        ],
+    }]
+
 def buildDockerImage():
     return [{
         "name": "docker",
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000000..2797b7e2a14
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1 @@
+**/src/graph/generated
\ No newline at end of file
diff --git a/generate-qa-activity-report.js b/generate-qa-activity-report.js
index 89436fde20d..8b72702e54b 100644
--- a/generate-qa-activity-report.js
+++ b/generate-qa-activity-report.js
@@ -68,8 +68,13 @@ async function getRecentChanges() {
       ['Test-Type', 'Date', 'Tests Added', 'Tests Changed', 'Tests Deleted', 'commit-ID']
     ]
 
-    for (const log of logs.all) {      
-      const e2eDiff = await git.diff([`${log.hash}~1`, log.hash, '--', 'tests/e2e/cucumber/features'])
+    for (const log of logs.all) {
+      const e2eDiff = await git.diff([
+        `${log.hash}~1`,
+        log.hash,
+        '--',
+        'tests/e2e/cucumber/features'
+      ])
       const unitDiff = await git.diff([`${log.hash}~1`, log.hash, '--', 'packages/**/*.spec.ts'])
 
       const e2eRow = analyzeE2eDiff(e2eDiff, log)
@@ -84,7 +89,7 @@ async function getRecentChanges() {
       }
     }
 
-    const csvContent = csvRows.map(row => row.join(',')).join('\n')
+    const csvContent = csvRows.map((row) => row.join(',')).join('\n')
     const reportsDir = path.join(__dirname, 'reports')
 
     if (!fs.existsSync(reportsDir)) {
@@ -99,7 +104,6 @@ async function getRecentChanges() {
         console.log(`CSV report generated successfully. You can find it in , ${reportFilePath}`)
       }
     })
-
   } catch (error) {
     console.error('Error:', error)
   }
@@ -129,20 +133,13 @@ function analyzeE2eDiff(diff, log) {
       if (line.includes('Scenario:')) {
         commitDeletedTests++
       }
-    } else if ((line.includes('@@ Feature:')) && currentFile) {
+    } else if (line.includes('@@ Feature:') && currentFile) {
       // if line contains 'Feature', that is test change. Example @@ -17,8 +17,8 @@ Feature: Download
       commitChangedTests++
     }
   }
   if (commitAddedTests || commitChangedTests || commitDeletedTests) {
-    return [
-      'UI Test',
-      log.date,
-      commitAddedTests,
-      commitChangedTests,
-      commitDeletedTests,
-      log.hash
-    ]
+    return ['UI Test', log.date, commitAddedTests, commitChangedTests, commitDeletedTests, log.hash]
   }
 }
 
@@ -157,7 +154,7 @@ function analyzeUnitDiff(diff, log) {
   let inTest = false
 
   for (let i = 0; i < diffLines.length; i++) {
-    const line = diffLines[i];
+    const line = diffLines[i]
 
     // Detect the file being diffed
     if (line.startsWith('diff --git')) {
diff --git a/package.json b/package.json
index 652b09efffe..48fbb5e2020 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,9 @@
     "licenses:save": "license-checker-rseidelsohn --relativeLicensePath --out /dev/null --files ./third-party-licenses/third-party-licenses",
     "vite": "vue-demi-fix && vite",
     "check:types": "pnpm build:tokens && vue-tsc --noEmit",
-    "check:all": "pnpm check:types && pnpm lint --fix && pnpm test:unit"
+    "check:format": "prettier --check \"./**/*.{ts,js,vue}\"",
+    "check:all": "pnpm check:types && pnpm lint --fix && pnpm check:format && pnpm test:unit",
+    "format": "prettier --write \"./**/*.{ts,js,vue}\""
   },
   "browserslist": [
     "last 1 year",
@@ -68,6 +70,7 @@
     "node-fetch": "3.3.2",
     "pino": "9.6.0",
     "pino-pretty": "13.0.0",
+    "prettier": "^3.0.0",
     "qs": "6.14.0",
     "requirejs": "2.3.7",
     "rollup-plugin-gzip": "^4.0.0",
diff --git a/packages/eslint-config/index.js b/packages/eslint-config/index.js
index a3d5ac0e120..35ce9e57ef9 100644
--- a/packages/eslint-config/index.js
+++ b/packages/eslint-config/index.js
@@ -1,5 +1,5 @@
 import unusedImports from 'eslint-plugin-unused-imports'
-import eslintConfigPrettier from 'eslint-plugin-prettier/recommended'
+import eslintConfigPrettier from 'eslint-config-prettier/flat'
 import tseslint from 'typescript-eslint'
 import globals from 'globals'
 import pluginVue from 'eslint-plugin-vue'
diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json
index 033be8864f2..cf51139d534 100644
--- a/packages/eslint-config/package.json
+++ b/packages/eslint-config/package.json
@@ -18,16 +18,15 @@
   "dependencies": {
     "@babel/eslint-parser": "^7.25.8",
     "@typescript-eslint/parser": "^8.0.0",
-    "eslint-config-prettier": "^10.0.0",
+    "eslint-config-prettier": "^10.1.1",
     "eslint-plugin-n": "^17.0.0",
-    "eslint-plugin-prettier": "^5.0.0",
     "eslint-plugin-promise": "^7.0.0",
     "eslint-plugin-unused-imports": "^4.0.0",
     "eslint-plugin-vue": "^10.0.0",
     "eslint-plugin-vuejs-accessibility": "^2.2.0",
     "globals": "^16.0.0",
-    "typescript-eslint": "^8.4.0",
-    "typescript": "^5.6.3"
+    "typescript": "^5.6.3",
+    "typescript-eslint": "^8.4.0"
   },
   "peerDependencies": {
     "eslint": "^9.0.0"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7d6d264fc16..fd3005d110f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -133,6 +133,9 @@ importers:
       pino-pretty:
         specifier: 13.0.0
         version: 13.0.0
+      prettier:
+        specifier: ^3.0.0
+        version: 3.5.3
       qs:
         specifier: 6.14.0
         version: 6.14.0
@@ -370,14 +373,11 @@ importers:
         specifier: ^9.0.0
         version: 9.22.0
       eslint-config-prettier:
-        specifier: ^10.0.0
+        specifier: ^10.1.1
         version: 10.1.1(eslint@9.22.0)
       eslint-plugin-n:
         specifier: ^17.0.0
         version: 17.16.2(eslint@9.22.0)
-      eslint-plugin-prettier:
-        specifier: ^5.0.0
-        version: 5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@10.1.1(eslint@9.22.0))(eslint@9.22.0)(prettier@3.5.3)
       eslint-plugin-promise:
         specifier: ^7.0.0
         version: 7.2.1(eslint@9.22.0)
@@ -2486,10 +2486,6 @@ packages:
     resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
     engines: {node: '>=14'}
 
-  '@pkgr/core@0.1.1':
-    resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==}
-    engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
-
   '@playwright/test@1.51.0':
     resolution: {integrity: sha512-dJ0dMbZeHhI+wb77+ljx/FeC8VBP6j/rj9OAojO08JI80wTZy6vRk9KvHKiDCUh4iMpEiseMgqRBIeW+eKX6RA==}
     engines: {node: '>=18'}
@@ -3967,20 +3963,6 @@ packages:
     peerDependencies:
       eslint: '>=8.23.0'
 
-  eslint-plugin-prettier@5.2.3:
-    resolution: {integrity: sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==}
-    engines: {node: ^14.18.0 || >=16.0.0}
-    peerDependencies:
-      '@types/eslint': '>=8.0.0'
-      eslint: '>=8.0.0'
-      eslint-config-prettier: '*'
-      prettier: '>=3.0.0'
-    peerDependenciesMeta:
-      '@types/eslint':
-        optional: true
-      eslint-config-prettier:
-        optional: true
-
   eslint-plugin-promise@7.2.1:
     resolution: {integrity: sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -4118,9 +4100,6 @@ packages:
   fast-deep-equal@3.1.3:
     resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
 
-  fast-diff@1.3.0:
-    resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
-
   fast-glob@3.3.3:
     resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
     engines: {node: '>=8.6.0'}
@@ -5620,10 +5599,6 @@ packages:
     resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
     engines: {node: '>= 0.8.0'}
 
-  prettier-linter-helpers@1.0.0:
-    resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
-    engines: {node: '>=6.0.0'}
-
   prettier@3.5.3:
     resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
     engines: {node: '>=14'}
@@ -6236,10 +6211,6 @@ packages:
   symbol-tree@3.2.4:
     resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
 
-  synckit@0.9.2:
-    resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==}
-    engines: {node: ^14.18.0 || >=16.0.0}
-
   tabbable@6.2.0:
     resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
 
@@ -8637,8 +8608,6 @@ snapshots:
   '@pkgjs/parseargs@0.11.0':
     optional: true
 
-  '@pkgr/core@0.1.1': {}
-
   '@playwright/test@1.51.0':
     dependencies:
       playwright: 1.51.0
@@ -10301,16 +10270,6 @@ snapshots:
       minimatch: 9.0.5
       semver: 7.7.1
 
-  eslint-plugin-prettier@5.2.3(@types/eslint@9.6.1)(eslint-config-prettier@10.1.1(eslint@9.22.0))(eslint@9.22.0)(prettier@3.5.3):
-    dependencies:
-      eslint: 9.22.0
-      prettier: 3.5.3
-      prettier-linter-helpers: 1.0.0
-      synckit: 0.9.2
-    optionalDependencies:
-      '@types/eslint': 9.6.1
-      eslint-config-prettier: 10.1.1(eslint@9.22.0)
-
   eslint-plugin-promise@7.2.1(eslint@9.22.0):
     dependencies:
       '@eslint-community/eslint-utils': 4.5.0(eslint@9.22.0)
@@ -10480,8 +10439,6 @@ snapshots:
 
   fast-deep-equal@3.1.3: {}
 
-  fast-diff@1.3.0: {}
-
   fast-glob@3.3.3:
     dependencies:
       '@nodelib/fs.stat': 2.0.5
@@ -11985,10 +11942,6 @@ snapshots:
 
   prelude-ls@1.2.1: {}
 
-  prettier-linter-helpers@1.0.0:
-    dependencies:
-      fast-diff: 1.3.0
-
   prettier@3.5.3: {}
 
   prismjs@1.30.0: {}
@@ -12659,11 +12612,6 @@ snapshots:
 
   symbol-tree@3.2.4: {}
 
-  synckit@0.9.2:
-    dependencies:
-      '@pkgr/core': 0.1.1
-      tslib: 2.8.1
-
   tabbable@6.2.0: {}
 
   table@6.9.0:
diff --git a/web.d.ts b/web.d.ts
index 088ccf4ffec..c99069e2155 100644
--- a/web.d.ts
+++ b/web.d.ts
@@ -22,7 +22,7 @@ declare module 'vue' {
 
   interface GlobalComponents {
     // https://github.com/LinusBorg/portal-vue/issues/380
-    Portal: typeof import('portal-vue')['Portal']
-    PortalTarget: typeof import('portal-vue')['PortalTarget']
+    Portal: (typeof import('portal-vue'))['Portal']
+    PortalTarget: (typeof import('portal-vue'))['PortalTarget']
   }
 }


Reviews:
user: login: mzner
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:32:57Z
user: login: mzner
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T10:33:06Z
user: login: LukasHirt
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-18T10:35:49Z

Review comments:
diff_hunk: @@ -18,7 +18,9 @@
     "licenses:save": "license-checker-rseidelsohn --relativeLicensePath --out /dev/null --files ./third-party-licenses/third-party-licenses",
     "vite": "vue-demi-fix && vite",
     "check:types": "pnpm build:tokens && vue-tsc --noEmit",
-    "check:all": "pnpm check:types && pnpm lint --fix && pnpm test:unit"
+    "check:all": "pnpm check:types && pnpm lint --fix && pnpm test:unit",
+    "format:check": "prettier --check \"./**/*.{ts,js,vue}\"",
path: package.json
user: login: mzner
body: Should we rename "format:check" to "check:format" just to stay consistent with other "check" commands?
created_at: 2025-03-18T10:32:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,7 +18,9 @@
     "licenses:save": "license-checker-rseidelsohn --relativeLicensePath --out /dev/null --files ./third-party-licenses/third-party-licenses",
     "vite": "vue-demi-fix && vite",
     "check:types": "pnpm build:tokens && vue-tsc --noEmit",
-    "check:all": "pnpm check:types && pnpm lint --fix && pnpm test:unit"
+    "check:all": "pnpm check:types && pnpm lint --fix && pnpm test:unit",
+    "format:check": "prettier --check \"./**/*.{ts,js,vue}\"",
path: package.json
user: login: LukasHirt
body: Sounds good :+1:
created_at: 2025-03-18T10:35:49Z
author_association: COLLABORATOR

PR comments:
user: login: update-docs[bot]
created_at: 2025-03-18T10:27:55Z
body: Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a [changelog](https://github.com/owncloud/web/blob/master/changelog/README.md) item based on your changes.

author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-03-18T10:50:59Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=owncloud_web&pullRequest=12327) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=owncloud_web&pullRequest=12327&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=owncloud_web&pullRequest=12327&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_web&pullRequest=12327&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=owncloud_web&pullRequest=12327&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=owncloud_web&pullRequest=12327&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=owncloud_web&pullRequest=12327)


author_association: NONE