From 19b017f3986655468d72b383141256f11d58c186 Mon Sep 17 00:00:00 2001
From: silverwind <me@silverwind.io>
Date: Fri, 28 Jan 2022 13:00:11 -0800
Subject: [PATCH] Use explicit jQuery import, remove unused eslint globals
 (#18435)

- Don't rely on globals (window.$) for jQuery import
- Remove eslint globals no longer in use
---
 .eslintrc                                        | 4 ----
 web_src/js/components/ContextPopup.vue           | 1 +
 web_src/js/components/DashboardRepoList.js       | 1 +
 web_src/js/components/RepoBranchTagDropdown.js   | 1 +
 web_src/js/features/admin-common.js              | 2 ++
 web_src/js/features/admin-emails.js              | 2 ++
 web_src/js/features/admin-users.js               | 2 ++
 web_src/js/features/clipboard.js                 | 2 ++
 web_src/js/features/common-global.js             | 4 ++--
 web_src/js/features/common-issue.js              | 1 +
 web_src/js/features/common-organization.js       | 1 +
 web_src/js/features/comp/ColorPicker.js          | 1 +
 web_src/js/features/comp/EasyMDE.js              | 5 +++--
 web_src/js/features/comp/ImagePaste.js           | 1 +
 web_src/js/features/comp/LabelEdit.js            | 1 +
 web_src/js/features/comp/MarkupContentPreview.js | 1 +
 web_src/js/features/comp/ReactionSelector.js     | 1 +
 web_src/js/features/comp/SearchUserBox.js        | 1 +
 web_src/js/features/comp/WebHookEditor.js        | 1 +
 web_src/js/features/contextpopup.js              | 2 +-
 web_src/js/features/heatmap.js                   | 1 -
 web_src/js/features/imagediff.js                 | 2 ++
 web_src/js/features/install.js                   | 2 ++
 web_src/js/features/notification.js              | 3 ++-
 web_src/js/features/org-team.js                  | 2 ++
 web_src/js/features/repo-branch.js               | 2 ++
 web_src/js/features/repo-code.js                 | 1 +
 web_src/js/features/repo-commit.js               | 2 ++
 web_src/js/features/repo-common.js               | 2 ++
 web_src/js/features/repo-diff.js                 | 2 ++
 web_src/js/features/repo-editor.js               | 2 +-
 web_src/js/features/repo-graph.js                | 2 ++
 web_src/js/features/repo-home.js                 | 1 +
 web_src/js/features/repo-issue-content.js        | 2 +-
 web_src/js/features/repo-issue.js                | 1 +
 web_src/js/features/repo-legacy.js               | 1 +
 web_src/js/features/repo-migrate.js              | 2 ++
 web_src/js/features/repo-migration.js            | 2 ++
 web_src/js/features/repo-projects.js             | 2 ++
 web_src/js/features/repo-release.js              | 1 +
 web_src/js/features/repo-settings.js             | 1 +
 web_src/js/features/repo-template.js             | 1 +
 web_src/js/features/repo-unicode-escape.js       | 2 ++
 web_src/js/features/repo-wiki.js                 | 1 +
 web_src/js/features/sshkey-helper.js             | 2 ++
 web_src/js/features/stopwatch.js                 | 3 ++-
 web_src/js/features/user-auth-webauthn.js        | 2 +-
 web_src/js/features/user-auth.js                 | 2 ++
 web_src/js/features/user-settings.js             | 2 ++
 web_src/js/index.js                              | 1 +
 web_src/js/markup/tasklist.js                    | 7 ++++---
 51 files changed, 76 insertions(+), 18 deletions(-)

diff --git a/.eslintrc b/.eslintrc
index b65d3528a8..646e66836a 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -23,9 +23,6 @@ env:
 
 globals:
   __webpack_public_path__: true
-  CodeMirror: false
-  Dropzone: false
-  SimpleMDE: false
 
 settings:
   html/html-extensions: [".tmpl"]
@@ -34,7 +31,6 @@ overrides:
   - files: ["web_src/**/*.js", "web_src/**/*.vue", "templates/**/*.tmpl"]
     env:
       browser: true
-      jquery: true
       node: false
   - files: ["templates/**/*.tmpl"]
     rules:
diff --git a/web_src/js/components/ContextPopup.vue b/web_src/js/components/ContextPopup.vue
index c002a3d066..0ff141476a 100644
--- a/web_src/js/components/ContextPopup.vue
+++ b/web_src/js/components/ContextPopup.vue
@@ -24,6 +24,7 @@
 </template>
 
 <script>
+import $ from 'jquery';
 import {SvgIcon} from '../svg.js';
 
 const {appSubUrl, i18n} = window.config;
diff --git a/web_src/js/components/DashboardRepoList.js b/web_src/js/components/DashboardRepoList.js
index 52d9f879ea..8d8f186cc6 100644
--- a/web_src/js/components/DashboardRepoList.js
+++ b/web_src/js/components/DashboardRepoList.js
@@ -1,4 +1,5 @@
 import Vue from 'vue';
+import $ from 'jquery';
 import {initVueSvg, vueDelimiters} from './VueComponentLoader.js';
 
 const {appSubUrl, assetUrlPrefix, pageData} = window.config;
diff --git a/web_src/js/components/RepoBranchTagDropdown.js b/web_src/js/components/RepoBranchTagDropdown.js
index 50c71d5bac..e72563ff29 100644
--- a/web_src/js/components/RepoBranchTagDropdown.js
+++ b/web_src/js/components/RepoBranchTagDropdown.js
@@ -1,4 +1,5 @@
 import Vue from 'vue';
+import $ from 'jquery';
 import {vueDelimiters} from './VueComponentLoader.js';
 
 export function initRepoBranchTagDropdown(selector) {
diff --git a/web_src/js/features/admin-common.js b/web_src/js/features/admin-common.js
index 1a3f800080..d2021c45aa 100644
--- a/web_src/js/features/admin-common.js
+++ b/web_src/js/features/admin-common.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const {csrfToken} = window.config;
 
 export function initAdminCommon() {
diff --git a/web_src/js/features/admin-emails.js b/web_src/js/features/admin-emails.js
index f69629d42b..46fafa7eff 100644
--- a/web_src/js/features/admin-emails.js
+++ b/web_src/js/features/admin-emails.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initAdminEmails() {
   function linkEmailAction(e) {
     const $this = $(this);
diff --git a/web_src/js/features/admin-users.js b/web_src/js/features/admin-users.js
index 5863c5480f..2221fc4929 100644
--- a/web_src/js/features/admin-users.js
+++ b/web_src/js/features/admin-users.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initAdminUserListSearchForm() {
   const searchForm = window.config.pageData.adminUserListSearchForm;
   if (!searchForm) return;
diff --git a/web_src/js/features/clipboard.js b/web_src/js/features/clipboard.js
index 83626b614e..e4a5c4f448 100644
--- a/web_src/js/features/clipboard.js
+++ b/web_src/js/features/clipboard.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const {copy_success, copy_error} = window.config.i18n;
 
 function onSuccess(btn) {
diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js
index bf9d21ac49..84b67a68e1 100644
--- a/web_src/js/features/common-global.js
+++ b/web_src/js/features/common-global.js
@@ -1,9 +1,9 @@
+import $ from 'jquery';
+import 'jquery.are-you-sure';
 import {mqBinarySearch} from '../utils.js';
 import createDropzone from './dropzone.js';
 import {initCompColorPicker} from './comp/ColorPicker.js';
 
-import 'jquery.are-you-sure';
-
 const {csrfToken} = window.config;
 
 export function initGlobalFormDirtyLeaveConfirm() {
diff --git a/web_src/js/features/common-issue.js b/web_src/js/features/common-issue.js
index 577abc1870..d7095a54a3 100644
--- a/web_src/js/features/common-issue.js
+++ b/web_src/js/features/common-issue.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {updateIssuesMeta} from './repo-issue.js';
 
 export function initCommonIssue() {
diff --git a/web_src/js/features/common-organization.js b/web_src/js/features/common-organization.js
index 9496f8ff22..218c039041 100644
--- a/web_src/js/features/common-organization.js
+++ b/web_src/js/features/common-organization.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {initCompLabelEdit} from './comp/LabelEdit.js';
 
 export function initCommonOrganization() {
diff --git a/web_src/js/features/comp/ColorPicker.js b/web_src/js/features/comp/ColorPicker.js
index 669e1d1f18..053fc6c059 100644
--- a/web_src/js/features/comp/ColorPicker.js
+++ b/web_src/js/features/comp/ColorPicker.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import createColorPicker from '../colorpicker.js';
 
 export function initCompColorPicker() {
diff --git a/web_src/js/features/comp/EasyMDE.js b/web_src/js/features/comp/EasyMDE.js
index 3a2f935dc2..9d711088d8 100644
--- a/web_src/js/features/comp/EasyMDE.js
+++ b/web_src/js/features/comp/EasyMDE.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import attachTribute from '../tribute.js';
 
 const {appSubUrl} = window.config;
@@ -54,7 +55,7 @@ export async function importEasyMDE() {
  * @returns {null|EasyMDE}
  */
 export async function createCommentEasyMDE(textarea, easyMDEOptions = {}) {
-  if (textarea instanceof jQuery) {
+  if (textarea instanceof $) {
     textarea = textarea[0];
   }
   if (!textarea) {
@@ -151,7 +152,7 @@ export function attachEasyMDEToElements(easyMDE) {
  * @returns {null|EasyMDE}
  */
 export function getAttachedEasyMDE(el) {
-  if (el instanceof jQuery) {
+  if (el instanceof $) {
     el = el[0];
   }
   if (!el) {
diff --git a/web_src/js/features/comp/ImagePaste.js b/web_src/js/features/comp/ImagePaste.js
index 8c8a4186c7..13c1a17c25 100644
--- a/web_src/js/features/comp/ImagePaste.js
+++ b/web_src/js/features/comp/ImagePaste.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 const {csrfToken} = window.config;
 
 async function uploadFile(file, uploadUrl) {
diff --git a/web_src/js/features/comp/LabelEdit.js b/web_src/js/features/comp/LabelEdit.js
index 7d71e6effa..df294078fa 100644
--- a/web_src/js/features/comp/LabelEdit.js
+++ b/web_src/js/features/comp/LabelEdit.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {initCompColorPicker} from './ColorPicker.js';
 
 export function initCompLabelEdit(selector) {
diff --git a/web_src/js/features/comp/MarkupContentPreview.js b/web_src/js/features/comp/MarkupContentPreview.js
index ed0995296b..61fd699b29 100644
--- a/web_src/js/features/comp/MarkupContentPreview.js
+++ b/web_src/js/features/comp/MarkupContentPreview.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {initMarkupContent} from '../../markup/content.js';
 
 const {csrfToken} = window.config;
diff --git a/web_src/js/features/comp/ReactionSelector.js b/web_src/js/features/comp/ReactionSelector.js
index d77b8d3d4e..f3b7a7668e 100644
--- a/web_src/js/features/comp/ReactionSelector.js
+++ b/web_src/js/features/comp/ReactionSelector.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 const {csrfToken} = window.config;
 
 export function initCompReactionSelector(parent) {
diff --git a/web_src/js/features/comp/SearchUserBox.js b/web_src/js/features/comp/SearchUserBox.js
index 1382c7060d..18b67919b5 100644
--- a/web_src/js/features/comp/SearchUserBox.js
+++ b/web_src/js/features/comp/SearchUserBox.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {htmlEscape} from 'escape-goat';
 
 const {appSubUrl} = window.config;
diff --git a/web_src/js/features/comp/WebHookEditor.js b/web_src/js/features/comp/WebHookEditor.js
index efef10ad64..85a4f92809 100644
--- a/web_src/js/features/comp/WebHookEditor.js
+++ b/web_src/js/features/comp/WebHookEditor.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 const {csrfToken} = window.config;
 
 export function initCompWebHookEditor() {
diff --git a/web_src/js/features/contextpopup.js b/web_src/js/features/contextpopup.js
index aa73aad241..0cd47bf2bc 100644
--- a/web_src/js/features/contextpopup.js
+++ b/web_src/js/features/contextpopup.js
@@ -1,5 +1,5 @@
+import $ from 'jquery';
 import Vue from 'vue';
-
 import ContextPopup from '../components/ContextPopup.vue';
 import {parseIssueHref} from '../utils.js';
 
diff --git a/web_src/js/features/heatmap.js b/web_src/js/features/heatmap.js
index e652f4ed98..363be5ca75 100644
--- a/web_src/js/features/heatmap.js
+++ b/web_src/js/features/heatmap.js
@@ -1,5 +1,4 @@
 import Vue from 'vue';
-
 import ActivityHeatmap from '../components/ActivityHeatmap.vue';
 
 export default function initHeatmap() {
diff --git a/web_src/js/features/imagediff.js b/web_src/js/features/imagediff.js
index d3f90b6260..6fd2ba6c36 100644
--- a/web_src/js/features/imagediff.js
+++ b/web_src/js/features/imagediff.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 function getDefaultSvgBoundsIfUndefined(svgXml, src) {
   const DefaultSize = 300;
   const MaxSize = 99999;
diff --git a/web_src/js/features/install.js b/web_src/js/features/install.js
index 05e0f9f463..9468ba9c42 100644
--- a/web_src/js/features/install.js
+++ b/web_src/js/features/install.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initInstall() {
   if ($('.page-content.install').length === 0) {
     return;
diff --git a/web_src/js/features/notification.js b/web_src/js/features/notification.js
index 1e483b16c8..68b23ef162 100644
--- a/web_src/js/features/notification.js
+++ b/web_src/js/features/notification.js
@@ -1,5 +1,6 @@
-const {appSubUrl, csrfToken, notificationSettings} = window.config;
+import $ from 'jquery';
 
+const {appSubUrl, csrfToken, notificationSettings} = window.config;
 let notificationSequenceNumber = 0;
 
 export function initNotificationsTable() {
diff --git a/web_src/js/features/org-team.js b/web_src/js/features/org-team.js
index ea0ea5fe74..1a045022d2 100644
--- a/web_src/js/features/org-team.js
+++ b/web_src/js/features/org-team.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const {appSubUrl} = window.config;
 
 export function initOrgTeamSettings() {
diff --git a/web_src/js/features/repo-branch.js b/web_src/js/features/repo-branch.js
index 4402411bfd..bc713a7397 100644
--- a/web_src/js/features/repo-branch.js
+++ b/web_src/js/features/repo-branch.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initRepoBranchButton() {
   $('.show-create-branch-modal.button').on('click', function () {
     $('#create-branch-form')[0].action = $('#create-branch-form').data('base-action') + $(this).data('branch-from-urlcomponent');
diff --git a/web_src/js/features/repo-code.js b/web_src/js/features/repo-code.js
index 1855f86b41..cc3019c236 100644
--- a/web_src/js/features/repo-code.js
+++ b/web_src/js/features/repo-code.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {svg} from '../svg.js';
 
 function changeHash(hash) {
diff --git a/web_src/js/features/repo-commit.js b/web_src/js/features/repo-commit.js
index 5e8f132f4b..9a8f1a1595 100644
--- a/web_src/js/features/repo-commit.js
+++ b/web_src/js/features/repo-commit.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const {csrfToken} = window.config;
 
 export function initRepoEllipsisButton() {
diff --git a/web_src/js/features/repo-common.js b/web_src/js/features/repo-common.js
index 3ddabe10f1..9479fa78e4 100644
--- a/web_src/js/features/repo-common.js
+++ b/web_src/js/features/repo-common.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const {csrfToken} = window.config;
 
 function getArchive($target, url, first) {
diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js
index f877af7211..45dad52fb1 100644
--- a/web_src/js/features/repo-diff.js
+++ b/web_src/js/features/repo-diff.js
@@ -1,6 +1,8 @@
+import $ from 'jquery';
 import {initCompReactionSelector} from './comp/ReactionSelector.js';
 import {initRepoIssueContentHistory} from './repo-issue-content.js';
 import {validateTextareaNonEmpty} from './comp/EasyMDE.js';
+
 const {csrfToken} = window.config;
 
 export function initRepoDiffReviewButton() {
diff --git a/web_src/js/features/repo-editor.js b/web_src/js/features/repo-editor.js
index 571fed9d27..f32bdbb8c3 100644
--- a/web_src/js/features/repo-editor.js
+++ b/web_src/js/features/repo-editor.js
@@ -1,9 +1,9 @@
+import $ from 'jquery';
 import {htmlEscape} from 'escape-goat';
 import {initMarkupContent} from '../markup/content.js';
 import {createCodeEditor} from './codeeditor.js';
 
 const {csrfToken} = window.config;
-
 let previewFileModes;
 
 function initEditPreviewTab($form) {
diff --git a/web_src/js/features/repo-graph.js b/web_src/js/features/repo-graph.js
index 73bde5facd..f27a986621 100644
--- a/web_src/js/features/repo-graph.js
+++ b/web_src/js/features/repo-graph.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export default function initRepoGraphGit() {
   const graphContainer = document.getElementById('git-graph-container');
   if (!graphContainer) return;
diff --git a/web_src/js/features/repo-home.js b/web_src/js/features/repo-home.js
index 29b4470619..c718bd75d8 100644
--- a/web_src/js/features/repo-home.js
+++ b/web_src/js/features/repo-home.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {stripTags} from '../utils.js';
 
 const {appSubUrl, csrfToken} = window.config;
diff --git a/web_src/js/features/repo-issue-content.js b/web_src/js/features/repo-issue-content.js
index 40e88fb1f3..a671200d88 100644
--- a/web_src/js/features/repo-issue-content.js
+++ b/web_src/js/features/repo-issue-content.js
@@ -1,7 +1,7 @@
+import $ from 'jquery';
 import {svg} from '../svg.js';
 
 const {appSubUrl, csrfToken} = window.config;
-
 let i18nTextEdited;
 let i18nTextOptions;
 let i18nTextDeleteFromHistory;
diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js
index 0523c3fb01..7a62cf2701 100644
--- a/web_src/js/features/repo-issue.js
+++ b/web_src/js/features/repo-issue.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {htmlEscape} from 'escape-goat';
 import attachTribute from './tribute.js';
 import {createCommentEasyMDE, getAttachedEasyMDE} from './comp/EasyMDE.js';
diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js
index f30345bfee..d92a0539d0 100644
--- a/web_src/js/features/repo-legacy.js
+++ b/web_src/js/features/repo-legacy.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {createCommentEasyMDE, getAttachedEasyMDE} from './comp/EasyMDE.js';
 import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js';
 import {initCompImagePaste, initEasyMDEImagePaste} from './comp/ImagePaste.js';
diff --git a/web_src/js/features/repo-migrate.js b/web_src/js/features/repo-migrate.js
index 2779fcd24c..5d61eb410e 100644
--- a/web_src/js/features/repo-migrate.js
+++ b/web_src/js/features/repo-migrate.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const {appSubUrl, csrfToken} = window.config;
 
 export function initRepoMigrationStatusChecker() {
diff --git a/web_src/js/features/repo-migration.js b/web_src/js/features/repo-migration.js
index 6e59d65f32..ece01e53bd 100644
--- a/web_src/js/features/repo-migration.js
+++ b/web_src/js/features/repo-migration.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const $service = $('#service_type');
 const $user = $('#auth_username');
 const $pass = $('#auth_password');
diff --git a/web_src/js/features/repo-projects.js b/web_src/js/features/repo-projects.js
index 5b3f54f8a6..21cb567456 100644
--- a/web_src/js/features/repo-projects.js
+++ b/web_src/js/features/repo-projects.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 const {csrfToken} = window.config;
 
 function moveIssue({item, from, to, oldIndex}) {
diff --git a/web_src/js/features/repo-release.js b/web_src/js/features/repo-release.js
index 915e722546..a44b91f35b 100644
--- a/web_src/js/features/repo-release.js
+++ b/web_src/js/features/repo-release.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import attachTribute from './tribute.js';
 import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js';
 import {initEasyMDEImagePaste} from './comp/ImagePaste.js';
diff --git a/web_src/js/features/repo-settings.js b/web_src/js/features/repo-settings.js
index b0d43bd487..dcb0788350 100644
--- a/web_src/js/features/repo-settings.js
+++ b/web_src/js/features/repo-settings.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {createMonaco} from './codeeditor.js';
 import {initRepoCommonFilterSearchDropdown} from './repo-common.js';
 
diff --git a/web_src/js/features/repo-template.js b/web_src/js/features/repo-template.js
index 5c100a89c5..e387678909 100644
--- a/web_src/js/features/repo-template.js
+++ b/web_src/js/features/repo-template.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {htmlEscape} from 'escape-goat';
 
 const {appSubUrl} = window.config;
diff --git a/web_src/js/features/repo-unicode-escape.js b/web_src/js/features/repo-unicode-escape.js
index 5791c23155..f97bcc7ee7 100644
--- a/web_src/js/features/repo-unicode-escape.js
+++ b/web_src/js/features/repo-unicode-escape.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initUnicodeEscapeButton() {
   $(document).on('click', 'a.escape-button', (e) => {
     e.preventDefault();
diff --git a/web_src/js/features/repo-wiki.js b/web_src/js/features/repo-wiki.js
index c0dc8d1b41..0ac88e3f5a 100644
--- a/web_src/js/features/repo-wiki.js
+++ b/web_src/js/features/repo-wiki.js
@@ -1,3 +1,4 @@
+import $ from 'jquery';
 import {initMarkupContent} from '../markup/content.js';
 import {attachEasyMDEToElements, importEasyMDE, validateTextareaNonEmpty} from './comp/EasyMDE.js';
 import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js';
diff --git a/web_src/js/features/sshkey-helper.js b/web_src/js/features/sshkey-helper.js
index bb3c8accf4..099b54d3a6 100644
--- a/web_src/js/features/sshkey-helper.js
+++ b/web_src/js/features/sshkey-helper.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initSshKeyFormParser() {
 // Parse SSH Key
   $('#ssh-key-content').on('change paste keyup', function () {
diff --git a/web_src/js/features/stopwatch.js b/web_src/js/features/stopwatch.js
index f6185f7ff7..1748c5119c 100644
--- a/web_src/js/features/stopwatch.js
+++ b/web_src/js/features/stopwatch.js
@@ -1,6 +1,7 @@
+import $ from 'jquery';
 import prettyMilliseconds from 'pretty-ms';
-const {appSubUrl, csrfToken, notificationSettings, enableTimeTracking} = window.config;
 
+const {appSubUrl, csrfToken, notificationSettings, enableTimeTracking} = window.config;
 let updateTimeInterval = null; // holds setInterval id when active
 
 export function initStopwatch() {
diff --git a/web_src/js/features/user-auth-webauthn.js b/web_src/js/features/user-auth-webauthn.js
index cf60535d40..4cb8c18219 100644
--- a/web_src/js/features/user-auth-webauthn.js
+++ b/web_src/js/features/user-auth-webauthn.js
@@ -1,8 +1,8 @@
+import $ from 'jquery';
 import {encode, decode} from 'uint8-to-base64';
 
 const {appSubUrl, csrfToken} = window.config;
 
-
 export function initUserAuthWebAuthn() {
   if ($('.user.signin.webauthn-prompt').length === 0) {
     return;
diff --git a/web_src/js/features/user-auth.js b/web_src/js/features/user-auth.js
index bc294803bf..55aace3bcd 100644
--- a/web_src/js/features/user-auth.js
+++ b/web_src/js/features/user-auth.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initUserAuthOauth2() {
   const $oauth2LoginNav = $('#oauth2-login-navigator');
   if ($oauth2LoginNav.length === 0) return;
diff --git a/web_src/js/features/user-settings.js b/web_src/js/features/user-settings.js
index c2f00dc362..3ed29f39b1 100644
--- a/web_src/js/features/user-settings.js
+++ b/web_src/js/features/user-settings.js
@@ -1,3 +1,5 @@
+import $ from 'jquery';
+
 export function initUserSettings() {
   if ($('.user.settings.profile').length > 0) {
     $('#username').on('keyup', function () {
diff --git a/web_src/js/index.js b/web_src/js/index.js
index 8ea30f1fca..c9a7949d5a 100644
--- a/web_src/js/index.js
+++ b/web_src/js/index.js
@@ -1,5 +1,6 @@
 import './publicpath.js';
 
+import $ from 'jquery';
 import {initVueEnv} from './components/VueComponentLoader.js';
 import {initRepoActivityTopAuthorsChart} from './components/RepoActivityTopAuthors.vue';
 import {initDashboardRepoList} from './components/DashboardRepoList.js';
diff --git a/web_src/js/markup/tasklist.js b/web_src/js/markup/tasklist.js
index 149027d428..0f03837baa 100644
--- a/web_src/js/markup/tasklist.js
+++ b/web_src/js/markup/tasklist.js
@@ -1,3 +1,7 @@
+import $ from 'jquery';
+
+const preventListener = (e) => e.preventDefault();
+
 /**
  * Attaches `input` handlers to markdown rendered tasklist checkboxes in comments.
  *
@@ -5,9 +9,6 @@
  * is set accordingly and sent to the server. On success it updates the raw-content on
  * error it resets the checkbox to its original value.
  */
-
-const preventListener = (e) => e.preventDefault();
-
 export function initMarkupTasklist() {
   for (const el of document.querySelectorAll(`.markup[data-can-edit=true]`) || []) {
     const container = el.parentNode;