Repository: microsoft/vscode-edge-devtools
Pull request #346 (2021-04-09 18:20:38)

Manual ESLint fixes
This PR depends on #339 which contains all of the auto-fixes. It's a lot of changes, but I checked that all the tests pass and there are no build errors. This resolves all of the current linting errors and warnings, with a few exceptions where I disabled some rules for a single line:
- Replacing occurrences of tslint-disabled rules
- Errors/warnings relating to `InspectorFrontendHostInstance.sendToVscodeOutput()` since it's usage is unconventional
- To enable ts-ignore where it's used
- A few instances that might require larger refactoring (in cdpTargetsProvider.ts, toolsHost.ts, and inspectorContentPolicy.ts)

Hopefully we can re-enable linting soon!


Patch:
diff --git a/.eslintrc.js b/.eslintrc.js
index b30ce61..8c44d3d 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,147 +1,148 @@
-// Generated using recommended approach
-// https://code.visualstudio.com/api/advanced-topics/tslint-eslint-migration
-module.exports = {
-    "env": {
-        "browser": true,
-        "es6": true,
-        "node": true
-    },
-    "extends": [
-        "plugin:@typescript-eslint/recommended",
-        "plugin:@typescript-eslint/recommended-requiring-type-checking"
-    ],
-    "parser": "@typescript-eslint/parser",
-    "parserOptions": {
-        "project": "tsconfig.json",
-        "sourceType": "module"
-    },
-    "plugins": [
-        "eslint-plugin-jsdoc",
-        "eslint-plugin-prefer-arrow",
-        "@typescript-eslint",
-        "import",
-    ],
-    /**
-     * ESLint rules
-     *
-     * All available rules: http://eslint.org/docs/rules/
-     *
-     * Rules take the following form:
-     *   'rule-name', [severity, { opts }]
-     * Severity: 2 == error, 1 == warning, 0 == off.
-     */
-    'rules': {
-        /**
-         * Enforced rules
-         */
-    
-    
-        // syntax preferences
-        'quotes': [2, 'single', {'avoidEscape': true, 'allowTemplateLiterals': true}],
-        'semi': 2,
-        'no-extra-semi': 2,
-        'comma-style': [2, 'last'],
-        'wrap-iife': [2, 'inside'],
-        'spaced-comment': [2, 'always', {'markers': ['*']}],
-        'eqeqeq': [2],
-        'accessor-pairs': [2, {'getWithoutSet': false, 'setWithoutGet': false}],
-        'curly': 2,
-        'new-parens': 2,
-        'func-call-spacing': 2,
-        'arrow-parens': [2, 'as-needed'],
-        'eol-last': 2,
-    
-        // anti-patterns
-        'no-caller': 2,
-        // MSFT: Not supported by esprima which is used by localization scripts.
-        //no-case-declarations': 2,
-        'no-cond-assign': 2,
-        'no-console': [2, {'allow': ['assert', 'context', 'error', 'timeStamp', 'time', 'timeEnd', 'warn']}],
-        'no-debugger': 2,
-        'no-dupe-keys': 2,
-        'no-duplicate-case': 2,
-        'no-else-return': [2, {'allowElseIf': false}],
-        'no-empty-character-class': 2,
-        'no-global-assign': 2,
-        'no-implied-eval': 2,
-        'no-labels': 2,
-        'no-multi-str': 2,
-        'no-new-object': 2,
-        'no-octal-escape': 2,
-        'no-self-compare': 2,
-        'no-shadow-restricted-names': 2,
-        'no-unreachable': 2,
-        'no-unsafe-negation': 2,
-        'no-unused-vars': [2, {'args': 'none', 'vars': 'local'}],
-        'no-var': 2,
-        'no-with': 2,
-        'prefer-const': 2,
-        'radix': 2,
-        'valid-typeof': 2,
-        'no-return-assign': [2, 'always'],
-    
-        // es2015 features
-        'require-yield': 2,
-        'template-curly-spacing': [2, 'never'],
-    
-        // spacing details
-        'space-infix-ops': 2,
-        'space-in-parens': [2, 'never'],
-        'space-before-function-paren': [2, {'anonymous': 'never', 'named': 'never', 'asyncArrow': 'always'}],
-        'no-whitespace-before-property': 2,
-        'keyword-spacing': [
-          2, {
-            'overrides': {
-              'if': {'after': true},
-              'else': {'after': true},
-              'for': {'after': true},
-              'while': {'after': true},
-              'do': {'after': true},
-              'switch': {'after': true},
-              'return': {'after': true}
-            }
-          }
-        ],
-        'arrow-spacing': [2, {'after': true, 'before': true}],
-    
-        // file whitespace
-        'no-multiple-empty-lines': [2, {'max': 2}],
-        'no-mixed-spaces-and-tabs': 2,
-        'no-trailing-spaces': 2,
-        'linebreak-style': [2, 'unix'],
-    
-        /**
-         * Disabled, aspirational rules
-         */
-    
-        
-        'indent': [0, 2, {'SwitchCase': 1, 'CallExpression': {'arguments': 2}, 'MemberExpression': 2}],
-    
-        // brace-style is disabled, as eslint cannot enforce 1tbs as default, but allman for functions
-        'brace-style': [0, 'allman', {'allowSingleLine': true}],
-    
-        // key-spacing is disabled, as some objects use value-aligned spacing, some not.
-        'key-spacing': [0, {'beforeColon': false, 'afterColon': true, 'align': 'value'}],
-        // quote-props is diabled, as property quoting styles are too varied to enforce.
-        'quote-props': [0, 'as-needed'],
-    
-        // no-implicit-globals will prevent accidental globals
-        'no-implicit-globals': [0],
-    
-        '@typescript-eslint/explicit-member-accessibility': [0],
-        '@typescript-eslint/no-explicit-any': 2,
-    
-        // Closure does not properly typecheck default exports
-        'import/no-default-export': 2,
-      },
-      'overrides': [{
-        'files': ['*.ts'],
-        'rules': {
-          '@typescript-eslint/explicit-member-accessibility': [2, {'accessibility': 'no-public'}],
-          'comma-dangle': [2, 'always-multiline'],
-          // run just the TypeScript unused-vars rule, else we get duplicate errors
-          'no-unused-vars': 0,
-          '@typescript-eslint/no-unused-vars': [2, {'argsIgnorePattern': '^_'}],
-        }
-      }]
-};
+// Generated using recommended approach
+// https://code.visualstudio.com/api/advanced-topics/tslint-eslint-migration
+module.exports = {
+    "env": {
+        "browser": true,
+        "es6": true,
+        "node": true
+    },
+    "extends": [
+        "plugin:@typescript-eslint/recommended",
+        "plugin:@typescript-eslint/recommended-requiring-type-checking"
+    ],
+    "parser": "@typescript-eslint/parser",
+    "parserOptions": {
+        "project": "tsconfig.json",
+        "sourceType": "module"
+    },
+    "plugins": [
+        "eslint-plugin-jsdoc",
+        "eslint-plugin-prefer-arrow",
+        "@typescript-eslint",
+        "import",
+    ],
+    /**
+     * ESLint rules
+     *
+     * All available rules: http://eslint.org/docs/rules/
+     *
+     * Rules take the following form:
+     *   'rule-name', [severity, { opts }]
+     * Severity: 2 == error, 1 == warning, 0 == off.
+     */
+    'rules': {
+        /**
+         * Enforced rules
+         */
+    
+    
+        // syntax preferences
+        'quotes': [2, 'single', {'avoidEscape': true, 'allowTemplateLiterals': true}],
+        'semi': 2,
+        'no-extra-semi': 2,
+        'comma-style': [2, 'last'],
+        'wrap-iife': [2, 'inside'],
+        'spaced-comment': [2, 'always', {'markers': ['*']}],
+        'eqeqeq': [2],
+        'accessor-pairs': [2, {'getWithoutSet': false, 'setWithoutGet': false}],
+        'curly': 2,
+        'new-parens': 2,
+        'func-call-spacing': 2,
+        'arrow-parens': [2, 'as-needed'],
+        'eol-last': 2,
+    
+        // anti-patterns
+        'no-caller': 2,
+        // MSFT: Not supported by esprima which is used by localization scripts.
+        //no-case-declarations': 2,
+        'no-cond-assign': 2,
+        'no-console': [2, {'allow': ['assert', 'context', 'error', 'timeStamp', 'time', 'timeEnd', 'warn']}],
+        'no-debugger': 2,
+        'no-dupe-keys': 2,
+        'no-duplicate-case': 2,
+        'no-else-return': [2, {'allowElseIf': false}],
+        'no-empty-character-class': 2,
+        'no-global-assign': 2,
+        'no-implied-eval': 2,
+        'no-labels': 2,
+        'no-multi-str': 2,
+        'no-new-object': 2,
+        'no-octal-escape': 2,
+        'no-self-compare': 2,
+        'no-shadow-restricted-names': 2,
+        'no-unreachable': 2,
+        'no-unsafe-negation': 2,
+        'no-unused-vars': [2, {'args': 'none', 'vars': 'local'}],
+        'no-var': 2,
+        'no-with': 2,
+        'prefer-const': 2,
+        'radix': 2,
+        'valid-typeof': 2,
+        'no-return-assign': [2, 'always'],
+    
+        // es2015 features
+        'require-yield': 2,
+        'template-curly-spacing': [2, 'never'],
+    
+        // spacing details
+        'space-infix-ops': 2,
+        'space-in-parens': [2, 'never'],
+        'space-before-function-paren': [2, {'anonymous': 'never', 'named': 'never', 'asyncArrow': 'always'}],
+        'no-whitespace-before-property': 2,
+        'keyword-spacing': [
+          2, {
+            'overrides': {
+              'if': {'after': true},
+              'else': {'after': true},
+              'for': {'after': true},
+              'while': {'after': true},
+              'do': {'after': true},
+              'switch': {'after': true},
+              'return': {'after': true}
+            }
+          }
+        ],
+        'arrow-spacing': [2, {'after': true, 'before': true}],
+    
+        // file whitespace
+        'no-multiple-empty-lines': [2, {'max': 2}],
+        'no-mixed-spaces-and-tabs': 2,
+        'no-trailing-spaces': 2,
+        //'linebreak-style': [2, 'unix'],
+    
+        /**
+         * Disabled, aspirational rules
+         */
+    
+        
+        'indent': [0, 2, {'SwitchCase': 1, 'CallExpression': {'arguments': 2}, 'MemberExpression': 2}],
+    
+        // brace-style is disabled, as eslint cannot enforce 1tbs as default, but allman for functions
+        'brace-style': [0, 'allman', {'allowSingleLine': true}],
+    
+        // key-spacing is disabled, as some objects use value-aligned spacing, some not.
+        'key-spacing': [0, {'beforeColon': false, 'afterColon': true, 'align': 'value'}],
+        // quote-props is diabled, as property quoting styles are too varied to enforce.
+        'quote-props': [0, 'as-needed'],
+    
+        // no-implicit-globals will prevent accidental globals
+        'no-implicit-globals': [0],
+    
+        '@typescript-eslint/explicit-member-accessibility': [0],
+        '@typescript-eslint/no-explicit-any': 2,
+        '@typescript-eslint/restrict-template-expressions': 0,
+    
+        // Closure does not properly typecheck default exports
+        'import/no-default-export': 2,
+      },
+      'overrides': [{
+        'files': ['*.ts'],
+        'rules': {
+          '@typescript-eslint/explicit-member-accessibility': [2, {'accessibility': 'no-public'}],
+          'comma-dangle': [2, 'always-multiline'],
+          // run just the TypeScript unused-vars rule, else we get duplicate errors
+          'no-unused-vars': 0,
+          '@typescript-eslint/no-unused-vars': [2, {'argsIgnorePattern': '^_'}],
+        }
+      }]
+};
diff --git a/package.json b/package.json
index 98db734..4da4ed5 100644
--- a/package.json
+++ b/package.json
@@ -543,7 +543,7 @@
         "build-and-lint": "npm run build && npm run lint",
         "watch": "npm run watch-wp",
         "watch-wp": "webpack --watch",
-        "lint": "eslint -c .eslintrc.js",
+        "lint": "eslint -c .eslintrc.js */*.ts",
         "test": "npm run lint && jest --config package.json --runInBand",
         "download-edge": "node scripts/downloadAndExtractEdge.js"
     },
diff --git a/postBuildStep.ts b/postBuildStep.ts
index 879992f..0bea555 100644
--- a/postBuildStep.ts
+++ b/postBuildStep.ts
@@ -3,9 +3,9 @@
 import * as fse from 'fs-extra';
 import path from 'path';
 
-import applyPaddingInlineCssPatch from './src/host/polyfills/cssPaddingInline';
+import { applyPaddingInlineCssPatch } from './src/host/polyfills/cssPaddingInline';
 import { applyContentSecurityPolicyPatch } from './src/host/polyfills/inspectorContentPolicy';
-import applyRuntimeImportScriptPathPrefixPatch from './src/host/polyfills/runtime';
+import { applyRuntimeImportScriptPathPrefixPatch } from './src/host/polyfills/runtime';
 import {applyAnnouncementNamePatch, applyGithubLinksPatch, applyReleaseNotePatch} from './src/host/polyfills/releaseNote';
 import {
     applyAppendTabOverridePatch,
@@ -43,8 +43,8 @@ import {
     applyStylesToggleFocusPatch,
     applyThemePatch,
 } from './src/host/polyfills/simpleView';
-import applySetupTextSelectionPatch from './src/host/polyfills/textSelection';
-import applyThirdPartyI18nLocalesPatch from './src/host/polyfills/thirdPartyI18n';
+import { applySetupTextSelectionPatch } from './src/host/polyfills/textSelection';
+import { applyThirdPartyI18nLocalesPatch } from './src/host/polyfills/thirdPartyI18n';
 
 async function copyFile(srcDir: string, outDir: string, name: string) {
     await fse.copy(
@@ -101,7 +101,7 @@ async function copyStaticFiles() {
 }
 
 async function patchFilesForWebView(toolsOutDir: string) {
-    // tslint:disable-next-line:no-console
+    // eslint-disable-next-line no-console
     console.log('Patching files.');
     await patchFileForWebViewWrapper('shell.js', toolsOutDir, [
         applyInspectorCommonContextMenuPatch,
diff --git a/src/cdpTarget.ts b/src/cdpTarget.ts
index a1e1048..4f84bdc 100644
--- a/src/cdpTarget.ts
+++ b/src/cdpTarget.ts
@@ -5,7 +5,7 @@ import * as path from 'path';
 import * as vscode from 'vscode';
 import { IRemoteTargetJson } from './utils';
 
-export default class CDPTarget extends vscode.TreeItem {
+export class CDPTarget extends vscode.TreeItem {
     readonly targetJson: IRemoteTargetJson;
     readonly propertyName: string | null = null;
     readonly iconPath: { dark: string, light: string } | undefined;
@@ -42,11 +42,13 @@ export default class CDPTarget extends vscode.TreeItem {
     /**
      * Issue: https://github.com/microsoft/vscode-edge-devtools/issues/199
      */
+    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
     // @ts-ignore
     get description(): string {
         return (this.propertyName ? this.targetJson[this.propertyName] : this.targetJson.url);
     }
 
+    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
     // @ts-ignore
     get tooltip(): string {
         return `${this.label} - ${this.description}`;
@@ -56,7 +58,7 @@ export default class CDPTarget extends vscode.TreeItem {
         return this.targetJson.webSocketDebuggerUrl;
     }
 
-    getChildren() {
+    getChildren(): CDPTarget[] {
         // Populate the child nodes if we don't have any yet
         if (!this.propertyName && this.children.length === 0) {
             this.children = [];
diff --git a/src/cdpTargetsProvider.ts b/src/cdpTargetsProvider.ts
index 4a7b0d3..7ef7841 100644
--- a/src/cdpTargetsProvider.ts
+++ b/src/cdpTargetsProvider.ts
@@ -5,10 +5,12 @@ import * as vscode from 'vscode';
 import TelemetryReporter from 'vscode-extension-telemetry';
 import * as path from 'path';
 import * as fs from 'fs';
-import CDPTarget from './cdpTarget';
+import { CDPTarget } from './cdpTarget';
 import { fixRemoteWebSocket, getListOfTargets, getRemoteEndpointSettings, IRemoteTargetJson, SETTINGS_STORE_NAME } from './utils';
+import { IncomingMessage } from 'http';
+import https = require('https');
 
-export default class CDPTargetsProvider implements vscode.TreeDataProvider<CDPTarget> {
+export class CDPTargetsProvider implements vscode.TreeDataProvider<CDPTarget> {
     readonly onDidChangeTreeData: vscode.Event<CDPTarget | null>;
     readonly changeDataEvent: vscode.EventEmitter<CDPTarget | null>;
     private extensionPath: string;
@@ -43,6 +45,7 @@ export default class CDPTargetsProvider implements vscode.TreeDataProvider<CDPTa
                 if (responseArray.length) {
                     await new Promise<void>(resolve => {
                         let targetsProcessed = 0;
+                        // eslint-disable-next-line @typescript-eslint/no-misused-promises
                         responseArray.forEach(async (target: IRemoteTargetJson) => {
                             const actualTarget = fixRemoteWebSocket(hostname, port, target);
                             if (actualTarget.type === 'page' || actualTarget.type === 'iframe') {
@@ -89,7 +92,7 @@ export default class CDPTargetsProvider implements vscode.TreeDataProvider<CDPTa
     refresh(): void {
         this.telemetryReporter.sendTelemetryEvent('view/refresh');
         this.changeDataEvent.fire(null);
-        this.clearFaviconResourceDirectory();
+        void this.clearFaviconResourceDirectory();
     }
 
     async clearFaviconResourceDirectory(): Promise<void> {
@@ -125,14 +128,13 @@ export default class CDPTargetsProvider implements vscode.TreeDataProvider<CDPTa
         if (!url || !url.startsWith('https')) {
             return null;
         }
-        const https = require('https');
         const faviconRegex = /((?:\/\/|\.)([^\.]*)\.[^\.^\/]+\/).*/;
 
         // Example regex match: https://docs.microsoft.com/en-us/microsoft-edge/
         // urlMatch[0] = .microsoft.com/en-us/microsoft-edge/
         // urlMatch[1] = .microsoft.com/
         // urlMatch[2] = microsoft
-        const urlMatch = url.match(faviconRegex);
+        const urlMatch = faviconRegex.exec(url);
         let filename;
         if (urlMatch) {
             filename = `${urlMatch[2]}Favicon.ico`;
@@ -147,8 +149,8 @@ export default class CDPTargetsProvider implements vscode.TreeDataProvider<CDPTa
 
         const file = fs.createWriteStream(filePath);
         const promise = new Promise<string | null>(resolve => {
-            https.get(faviconUrl, (response: any) => {
-                if (response.headers['content-type'].includes('icon')) {
+            https.get(faviconUrl, (response: IncomingMessage) => {
+                if (response.headers['content-type'] && response.headers['content-type'].includes('icon')) {
                   response.pipe(file);
                   file.on('error', () => {
                       resolve(null);
diff --git a/src/common/settingsProvider.ts b/src/common/settingsProvider.ts
index 19cf57a..e1bf841 100644
--- a/src/common/settingsProvider.ts
+++ b/src/common/settingsProvider.ts
@@ -26,7 +26,7 @@ export class SettingsProvider {
     return whatsNewEnabled;
   }
 
-  static get instance() {
+  static get instance(): SettingsProvider {
     if (!SettingsProvider.singletonInstance) {
       SettingsProvider.singletonInstance = new SettingsProvider();
     }
diff --git a/src/common/webviewEvents.ts b/src/common/webviewEvents.ts
index 31f7440..afdf3f9 100644
--- a/src/common/webviewEvents.ts
+++ b/src/common/webviewEvents.ts
@@ -42,7 +42,7 @@ export interface ITelemetryDataNumber {
 export interface ITelemetryDataObject {
     event: 'error';
     name: string;
-    data: object;
+    data: Record<string, unknown>;
 }
 export type TelemetryData = ITelemetryDataNumber | ITelemetryDataObject;
 
@@ -85,7 +85,7 @@ export function parseMessageFromChannel(
 export function encodeMessageForChannel(
     postMessageCallback: (message: string) => void,
     eventType: WebviewEvent,
-    args?: object) {
+    args?: unknown): void {
     const message = `${eventType}:${JSON.stringify(args)}`;
     postMessageCallback(message);
 }
diff --git a/src/debugTelemetryReporter.ts b/src/debugTelemetryReporter.ts
index c652d70..49db8d5 100644
--- a/src/debugTelemetryReporter.ts
+++ b/src/debugTelemetryReporter.ts
@@ -3,7 +3,7 @@
 
 import TelemetryReporter from 'vscode-extension-telemetry';
 
-export default class DebugTelemetryReporter extends TelemetryReporter {
+export class DebugTelemetryReporter extends TelemetryReporter {
     constructor() {
         super('extensionId', 'extensionVersion', 'key');
     }
@@ -11,13 +11,13 @@ export default class DebugTelemetryReporter extends TelemetryReporter {
     sendTelemetryEvent(
         eventName: string,
         properties?: { [key: string]: string; },
-        measurements?: { [key: string]: number; }) {
-        // tslint:disable-next-line: no-console
+        measurements?: { [key: string]: number; }): void {
+        // eslint-disable-next-line no-console
         console.log(
             `${eventName}: ${JSON.stringify(properties)}, ${JSON.stringify(measurements)}`);
     }
 
-    dispose(): Promise<any> {
+    dispose(): Promise<void> {
         return Promise.resolve();
     }
 }
diff --git a/src/devtoolsPanel.ts b/src/devtoolsPanel.ts
index f1daa39..b85c9f5 100644
--- a/src/devtoolsPanel.ts
+++ b/src/devtoolsPanel.ts
@@ -62,9 +62,9 @@ export class DevToolsPanel {
         this.panelSocket.on('getState', msg => this.onSocketGetState(msg));
         this.panelSocket.on('getVscodeSettings', msg => this.onSocketGetVscodeSettings(msg));
         this.panelSocket.on('setState', msg => this.onSocketSetState(msg));
-        this.panelSocket.on('getUrl', msg => this.onSocketGetUrl(msg));
-        this.panelSocket.on('openUrl', msg => this.onSocketOpenUrl(msg));
-        this.panelSocket.on('openInEditor', msg => this.onSocketOpenInEditor(msg));
+        this.panelSocket.on('getUrl', msg => this.onSocketGetUrl(msg) as unknown as void);
+        this.panelSocket.on('openUrl', msg => this.onSocketOpenUrl(msg) as unknown as void);
+        this.panelSocket.on('openInEditor', msg => this.onSocketOpenInEditor(msg) as unknown as void);
         this.panelSocket.on('close', () => this.onSocketClose());
         this.panelSocket.on('copyText', msg => this.onSocketCopyText(msg));
         this.panelSocket.on('focusEditor', msg => this.onSocketFocusEditor(msg));
@@ -77,7 +77,7 @@ export class DevToolsPanel {
         }, this, this.disposables);
 
         // Handle view change
-        this.panel.onDidChangeViewState(e => {
+        this.panel.onDidChangeViewState(_e => {
             if (this.panel.visible) {
                 this.update();
             }
@@ -89,7 +89,7 @@ export class DevToolsPanel {
         }, this, this.disposables);
     }
 
-    dispose() {
+    dispose(): void {
         DevToolsPanel.instance = undefined;
 
         this.panel.dispose();
@@ -114,7 +114,7 @@ export class DevToolsPanel {
                 this.telemetryReporter.sendTelemetryEvent(`websocket/${e}`);
                 break;
         }
-        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg), 'websocket', { event: e, message });
+        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg) as unknown as void, 'websocket', { event: e, message });
     }
 
     private onSocketReady() {
@@ -133,24 +133,24 @@ export class DevToolsPanel {
 
     private onSocketCopyText(message: string) {
         const { clipboardData } = JSON.parse(message) as { clipboardData: string };
-        vscode.env.clipboard.writeText(clipboardData);
+        void vscode.env.clipboard.writeText(clipboardData);
     }
 
     private onSocketFocusEditor(message: string) {
         const { next } = JSON.parse(message) as { next: boolean };
         if (next) {
-            vscode.commands.executeCommand('workbench.action.nextEditor');
+            void vscode.commands.executeCommand('workbench.action.nextEditor');
         } else {
-            vscode.commands.executeCommand('workbench.action.previousEditor');
+            void vscode.commands.executeCommand('workbench.action.previousEditor');
         }
     }
 
     private onSocketFocusEditorGroup(message: string) {
         const { next } = JSON.parse(message) as { next: boolean };
         if (next) {
-            vscode.commands.executeCommand('workbench.action.focusNextGroup');
+            void vscode.commands.executeCommand('workbench.action.focusNextGroup');
         } else {
-            vscode.commands.executeCommand('workbench.action.focusPreviousGroup');
+            void vscode.commands.executeCommand('workbench.action.focusPreviousGroup');
         }
     }
 
@@ -160,7 +160,7 @@ export class DevToolsPanel {
     }
 
     private onSocketTelemetry(message: string) {
-        const telemetry: TelemetryData = JSON.parse(message);
+        const telemetry: TelemetryData = JSON.parse(message) as TelemetryData;
 
         // Fire telemetry
         switch (telemetry.event) {
@@ -196,13 +196,13 @@ export class DevToolsPanel {
 
     private onSocketGetState(message: string) {
         const { id } = JSON.parse(message) as { id: number };
-        const preferences: any = this.context.workspaceState.get(SETTINGS_PREF_NAME) || SETTINGS_PREF_DEFAULTS;
-        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg), 'getState', { id, preferences });
+        const preferences: Record<string, unknown> = this.context.workspaceState.get(SETTINGS_PREF_NAME) || SETTINGS_PREF_DEFAULTS;
+        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg) as unknown as void, 'getState', { id, preferences });
     }
 
     private onSocketGetVscodeSettings(message: string) {
         const { id } = JSON.parse(message) as { id: number };
-        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg), 'getVscodeSettings', {
+        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg) as unknown as void, 'getVscodeSettings', {
             enableNetwork: SettingsProvider.instance.isNetworkEnabled(),
             themeString: SettingsProvider.instance.getThemeSettings(),
             whatsNew: SettingsProvider.instance.getWhatsNewSettings(),
@@ -212,9 +212,9 @@ export class DevToolsPanel {
     private onSocketSetState(message: string) {
         // Parse the preference from the message and store it
         const { name, value } = JSON.parse(message) as { name: string, value: string };
-        const allPref: any = this.context.workspaceState.get(SETTINGS_PREF_NAME) || {};
+        const allPref: Record<string, unknown> = this.context.workspaceState.get(SETTINGS_PREF_NAME) || {};
         allPref[name] = value;
-        this.context.workspaceState.update(SETTINGS_PREF_NAME, allPref);
+        void this.context.workspaceState.update(SETTINGS_PREF_NAME, allPref);
     }
 
     private async onSocketGetUrl(message: string) {
@@ -228,12 +228,12 @@ export class DevToolsPanel {
             // Response will not have content
         }
 
-        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg), 'getUrl', { id: request.id, content });
+        encodeMessageForChannel(msg => this.panel.webview.postMessage(msg) as unknown as void, 'getUrl', { id: request.id, content });
     }
 
-    private async onSocketOpenUrl(message: string) {
+    private onSocketOpenUrl(message: string) {
       const { url } = JSON.parse(message) as { url: string };
-      vscode.env.openExternal(vscode.Uri.parse(url));
+      void vscode.env.openExternal(vscode.Uri.parse(url));
     }
 
     private async onSocketOpenInEditor(message: string) {
@@ -260,7 +260,7 @@ export class DevToolsPanel {
 
         // Convert the local url to a workspace path
         const transformer = new debugCore.UrlPathTransformer();
-        transformer.launch({ pathMapping: this.config.pathMapping });
+        void transformer.launch({ pathMapping: this.config.pathMapping });
         const localSource = { path: sourcePath };
         await transformer.fixSource(localSource);
 
@@ -281,7 +281,7 @@ export class DevToolsPanel {
         // Finally open the document if it exists
         if (uri) {
             const doc = await vscode.workspace.openTextDocument(uri);
-            vscode.window.showTextDocument(
+            void vscode.window.showTextDocument(
                 doc,
                 {
                     preserveFocus: true,
@@ -289,7 +289,7 @@ export class DevToolsPanel {
                     viewColumn: vscode.ViewColumn.One,
                 });
         } else {
-            vscode.window.showErrorMessage(`Could not open document. No workspace mapping was found for '${url}'.`);
+            void vscode.window.showErrorMessage(`Could not open document. No workspace mapping was found for '${url}'.`);
         }
     }
 
@@ -332,7 +332,7 @@ export class DevToolsPanel {
         context: vscode.ExtensionContext,
         telemetryReporter: Readonly<TelemetryReporter>,
         targetUrl: string,
-        config: IRuntimeConfig) {
+        config: IRuntimeConfig): void {
         const column = vscode.ViewColumn.Beside;
 
         if (DevToolsPanel.instance) {
diff --git a/src/extension.ts b/src/extension.ts
index 4d3d502..8e4c7a7 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -5,10 +5,10 @@ import { Browser } from 'puppeteer-core';
 import * as vscode from 'vscode';
 import * as debugCore from 'vscode-chrome-debug-core';
 import TelemetryReporter from 'vscode-extension-telemetry';
-import CDPTarget from './cdpTarget';
-import CDPTargetsProvider from './cdpTargetsProvider';
+import { CDPTarget } from './cdpTarget';
+import { CDPTargetsProvider } from './cdpTargetsProvider';
 import { DevToolsPanel } from './devtoolsPanel';
-import LaunchDebugProvider from './launchDebugProvider';
+import { LaunchDebugProvider } from './launchDebugProvider';
 import {
     createTelemetryReporter,
     fixRemoteWebSocket,
@@ -28,17 +28,17 @@ import {
 let telemetryReporter: Readonly<TelemetryReporter>;
 let browserInstance: Browser;
 
-export function activate(context: vscode.ExtensionContext) {
+export function activate(context: vscode.ExtensionContext): void {
     if (!telemetryReporter) {
         telemetryReporter = createTelemetryReporter(context);
     }
 
-    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_STORE_NAME}.attach`, async () => {
-        attach(context);
+    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_STORE_NAME}.attach`, (): void => {
+        void attach(context);
     }));
 
-    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_STORE_NAME}.launch`, async () => {
-        launch(context);
+    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_STORE_NAME}.launch`, (): void => {
+        void launch(context);
     }));
 
     // Register the launch provider
@@ -74,11 +74,11 @@ export function activate(context: vscode.ExtensionContext) {
             const runtimeConfig = getRuntimeConfig();
             DevToolsPanel.createOrShow(context, telemetryReporter, target.websocketUrl, runtimeConfig);
         }));
-    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_VIEW_NAME}.openSettings`, async () => {
-        vscode.commands.executeCommand('workbench.action.openSettings', `${SETTINGS_STORE_NAME}`);
+    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_VIEW_NAME}.openSettings`, () => {
+        void vscode.commands.executeCommand('workbench.action.openSettings', `${SETTINGS_STORE_NAME}`);
     }));
-    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_VIEW_NAME}.viewChangelog`, async () => {
-        vscode.env.openExternal(vscode.Uri.parse('https://github.com/microsoft/vscode-edge-devtools/blob/master/CHANGELOG.md'));
+    context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_VIEW_NAME}.viewChangelog`, () => {
+        void vscode.env.openExternal(vscode.Uri.parse('https://github.com/microsoft/vscode-edge-devtools/blob/master/CHANGELOG.md'));
     }));
     context.subscriptions.push(vscode.commands.registerCommand(
         `${SETTINGS_VIEW_NAME}.close-instance`,
@@ -100,7 +100,7 @@ export function activate(context: vscode.ExtensionContext) {
                     // e.g redirecting to chrome-error: protocol
                     if (!page.isClosed() && (normalizedPath === page.target().url())) {
                         // fire and forget
-                        page.close();
+                        void page.close();
                         break;
                     }
                 }
@@ -112,11 +112,11 @@ export function activate(context: vscode.ExtensionContext) {
     context.subscriptions.push(vscode.commands.registerCommand(
         `${SETTINGS_VIEW_NAME}.copyItem`,
         (target: CDPTarget) => vscode.env.clipboard.writeText(target.tooltip)));
-    vscode.commands.executeCommand('setContext', 'titleCommandsRegistered', true);
+    void vscode.commands.executeCommand('setContext', 'titleCommandsRegistered', true);
 }
 
 export async function attach(
-    context: vscode.ExtensionContext, attachUrl?: string, config?: Partial<IUserConfig>, useRetry?: boolean) {
+    context: vscode.ExtensionContext, attachUrl?: string, config?: Partial<IUserConfig>, useRetry?: boolean): Promise<void> {
     if (!telemetryReporter) {
         telemetryReporter = createTelemetryReporter(context);
     }
@@ -129,13 +129,13 @@ export async function attach(
     // Get the attach target and keep trying until reaching timeout
     const startTime = Date.now();
     do {
-        let responseArray: any[] | undefined;
+        let responseArray: IRemoteTargetJson[] | undefined;
         try {
             // Keep trying to attach to the list endpoint until timeout
             responseArray = await debugCore.utils.retryAsync(
                 () => getListOfTargets(hostname, port, useHttps),
                 timeout,
-                /* intervalDelay=*/ SETTINGS_DEFAULT_ATTACH_INTERVAL);
+                /* intervalDelay=*/ SETTINGS_DEFAULT_ATTACH_INTERVAL) as IRemoteTargetJson[];
         } catch {
             // Timeout so make sure we error out with no json result
             responseArray = undefined;
@@ -154,16 +154,16 @@ export async function attach(
                 // Match the targets using the edge debug adapter logic
                 let matchedTargets: debugCore.chromeConnection.ITarget[] | undefined;
                 try {
-                    matchedTargets = debugCore.chromeUtils.getMatchingTargets(responseArray, attachUrl);
+                    matchedTargets = debugCore.chromeUtils.getMatchingTargets(responseArray as unknown as debugCore.chromeConnection.ITarget[], attachUrl);
                 } catch {
                     matchedTargets = undefined;
                 }
 
                 if (matchedTargets && matchedTargets.length > 0 && matchedTargets[0].webSocketDebuggerUrl) {
-                    const actualTarget = fixRemoteWebSocket(hostname, port, matchedTargets[0] as any);
+                    const actualTarget = fixRemoteWebSocket(hostname, port, matchedTargets[0] as unknown as IRemoteTargetJson);
                     targetWebsocketUrl = actualTarget.webSocketDebuggerUrl;
                 } else if (!useRetry) {
-                    vscode.window.showErrorMessage(`Couldn't attach to ${attachUrl}.`);
+                    void vscode.window.showErrorMessage(`Couldn't attach to ${attachUrl}.`);
                 }
             }
 
@@ -205,7 +205,7 @@ export async function attach(
     } while (useRetry && Date.now() - startTime < timeout);
 }
 
-export async function launch(context: vscode.ExtensionContext, launchUrl?: string, config?: Partial<IUserConfig>) {
+export async function launch(context: vscode.ExtensionContext, launchUrl?: string, config?: Partial<IUserConfig>): Promise<void> {
     if (!telemetryReporter) {
         telemetryReporter = createTelemetryReporter(context);
     }
@@ -226,7 +226,7 @@ export async function launch(context: vscode.ExtensionContext, launchUrl?: strin
         const browserPath = await getBrowserPath(config);
         if (!browserPath) {
             telemetryReporter.sendTelemetryEvent('command/launch/error/browser_not_found', telemetryProps);
-            vscode.window.showErrorMessage(
+            void vscode.window.showErrorMessage(
                 'Microsoft Edge could not be found. ' +
                 'Ensure you have installed Microsoft Edge ' +
                 "and that you have selected 'default' or the appropriate version of Microsoft Edge " +
@@ -238,17 +238,18 @@ export async function launch(context: vscode.ExtensionContext, launchUrl?: strin
             // If it is one of those names we use that, otherwise we default it to "other".
             // Then we upload just one of those 3 names to telemetry.
             const exeName = browserPath.split(/\\|\//).pop();
-            const match = exeName!.match(/(chrome|edge)/gi) || [];
+            if (!exeName) { return; }
+            const match = exeName.match(/(chrome|edge)/gi) || [];
             const knownBrowser = match.length > 0 ? match[0] : 'other';
             const browserProps = { exe: `${knownBrowser.toLowerCase()}` };
             telemetryReporter.sendTelemetryEvent('command/launch/browser', browserProps);
 
         browserInstance = await launchBrowser(browserPath, port, url, userDataDir);
         browserInstance.addListener('targetcreated', () => {
-            vscode.commands.executeCommand(`${SETTINGS_VIEW_NAME}.refresh`);
+            void vscode.commands.executeCommand(`${SETTINGS_VIEW_NAME}.refresh`);
         });
         browserInstance.addListener('targetdestroyed', () => {
-            vscode.commands.executeCommand(`${SETTINGS_VIEW_NAME}.refresh`);
+            void vscode.commands.executeCommand(`${SETTINGS_VIEW_NAME}.refresh`);
         });
         await attach(context, url, config);
     }
diff --git a/src/host/host.ts b/src/host/host.ts
index a1f8d02..9d836f1 100644
--- a/src/host/host.ts
+++ b/src/host/host.ts
@@ -2,9 +2,9 @@
 // Licensed under the MIT License.
 
 import { parseMessageFromChannel } from '../common/webviewEvents';
-import ToolsHost from './toolsHost';
-import ToolsResourceLoader, { IRuntimeResourceLoader } from './toolsResourceLoader';
-import ToolsWebSocket from './toolsWebSocket';
+import { ToolsHost } from './toolsHost';
+import { ToolsResourceLoader, IRuntimeResourceLoader } from './toolsResourceLoader';
+import { ToolsWebSocket } from './toolsWebSocket';
 
 let listenForSecondKeyChord = false;
 
@@ -19,7 +19,7 @@ export interface IRoot {
     Runtime: IRuntimeResourceLoader;
 }
 
-export function initialize(dtWindow: IDevToolsWindow) {
+export function initialize(dtWindow: IDevToolsWindow): void {
     if (!dtWindow) {
         return;
     }
diff --git a/src/host/mainHost.ts b/src/host/mainHost.ts
index 2c6b7d9..8d71d42 100644
--- a/src/host/mainHost.ts
+++ b/src/host/mainHost.ts
@@ -3,4 +3,4 @@
 
 import { IDevToolsWindow, initialize } from './host';
 
-initialize(window as any as IDevToolsWindow);
+initialize(window as unknown as IDevToolsWindow);
diff --git a/src/host/messaging.ts b/src/host/messaging.ts
index 2f6f675..1241a10 100644
--- a/src/host/messaging.ts
+++ b/src/host/messaging.ts
@@ -1,9 +1,9 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 
-declare const acquireVsCodeApi: () => any;
+declare const acquireVsCodeApi: () => {postMessage(message: unknown): void};
 
-export function initializeMessaging() {
+export function initializeMessaging(): void {
     const vscode = acquireVsCodeApi();
 
     let toolsWindow: Window | null;
diff --git a/src/host/polyfills/cssPaddingInline.ts b/src/host/polyfills/cssPaddingInline.ts
index e64f7e6..bdbfa26 100644
--- a/src/host/polyfills/cssPaddingInline.ts
+++ b/src/host/polyfills/cssPaddingInline.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 
-export default function applyPaddingInlineCssPatch(content: string) {
+export function applyPaddingInlineCssPatch(content: string): string | null {
     const separator = '\\n';
     const cssHeaderContents =
     `.elements-disclosure .gutter-container {
diff --git a/src/host/polyfills/inspectorContentPolicy.ts b/src/host/polyfills/inspectorContentPolicy.ts
index db2703c..5b26697 100644
--- a/src/host/polyfills/inspectorContentPolicy.ts
+++ b/src/host/polyfills/inspectorContentPolicy.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 
-export function applyContentSecurityPolicyPatch(content: string) {
+export function applyContentSecurityPolicyPatch(content: string): string | null {
     const scriptPattern = /script-src\s*'self'/g;
     let result;
     if (content.match(scriptPattern)) {
@@ -11,6 +11,7 @@ export function applyContentSecurityPolicyPatch(content: string) {
     }
 
     const metaString = `<meta name="referrer" content="no-referrer">`;
+    // eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
     if (result.match(metaString)) {
         return result.replace(metaString, `<script src="../../host/host.bundle.js"></script>`);
     }
diff --git a/src/host/polyfills/releaseNote.ts b/src/host/polyfills/releaseNote.ts
index 1dd98a8..a7ab894 100644
--- a/src/host/polyfills/releaseNote.ts
+++ b/src/host/polyfills/releaseNote.ts
@@ -3,7 +3,7 @@
 
 import {devtoolsHighlights, extensionHighlights} from './releaseNoteContent';
 
-export function applyReleaseNotePatch(content: string) {
+export function applyReleaseNotePatch(content: string): string | null {
     const releaseNoteTextPattern = /const releaseNoteText\s*=\s*\[[\s\S]+var ReleaseNoteText_edge\s*=/;
     const replacementNotes = `
         export const releaseNoteText = [
@@ -20,14 +20,14 @@ export function applyReleaseNotePatch(content: string) {
         var ReleaseNoteText_edge =
     `;
 
-    if (content.match(releaseNoteTextPattern)) {
+    if (releaseNoteTextPattern.exec(content)) {
         return content.replace(releaseNoteTextPattern, replacementNotes);
     }
         return null;
 
 }
 
-export function applyGithubLinksPatch(content: string) {
+export function applyGithubLinksPatch(content: string): string | null {
     const linkPattern = /const learnMore\s*=[\s\S]+learnMore\);/g;
     const linkReplacementText = `
         const githubLink = XLink.XLink.create(releaseNote.githubLink, ls \`Visit our Github Page\`, 'release-note-link-learn-more');
@@ -36,17 +36,17 @@ export function applyGithubLinksPatch(content: string) {
         const issuesLink = XLink.XLink.create(releaseNote.issuesLink, ls \`Send us feedback\`, 'release-note-link-learn-more');
         issuesContainer.appendChild(issuesLink);
     `;
-    if (content.match(linkPattern)) {
+    if (linkPattern.exec(content)) {
         return content.replace(linkPattern, linkReplacementText);
     }
         return null;
 
 }
 
-export function applyAnnouncementNamePatch(content: string) {
+export function applyAnnouncementNamePatch(content: string): string | null {
     const microsoftAnnouncement = /Announcements from the Microsoft Edge DevTools team/;
     const chromiumAnnouncement = /Announcements from the Chromium project/;
-    if (content.match(microsoftAnnouncement) && content.match(chromiumAnnouncement)) {
+    if (microsoftAnnouncement.exec(content) && chromiumAnnouncement.exec(content)) {
         content = content.replace(microsoftAnnouncement, 'New extension features');
         return content.replace(chromiumAnnouncement, 'New in Developer Tools');
     }
diff --git a/src/host/polyfills/runtime.ts b/src/host/polyfills/runtime.ts
index 5d1cfe1..f2ff13a 100644
--- a/src/host/polyfills/runtime.ts
+++ b/src/host/polyfills/runtime.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 
-export default function applyRuntimeImportScriptPathPrefixPatch(content: string) {
+export function applyRuntimeImportScriptPathPrefixPatch(content: string): string | null {
 
     // ImportScript is exposed as a module variable, this patch:
     // Exposes it again as a global and remove the local declaration.
diff --git a/src/host/polyfills/simpleView.ts b/src/host/polyfills/simpleView.ts
index 7604616..cd11bdf 100644
--- a/src/host/polyfills/simpleView.ts
+++ b/src/host/polyfills/simpleView.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 import { IDevToolsWindow } from '../host';
-import ToolsHost from '../toolsHost';
+import { ToolsHost } from '../toolsHost';
 
 declare let InspectorFrontendHost: ToolsHost;
 
@@ -20,8 +20,8 @@ const enum KeepMatchedText {
 
 const isDrawerEnabled = '(Root.Runtime.vscodeSettings.enableNetwork || Root.Runtime.vscodeSettings.whatsNew)';
 
-function replaceInSourceCode(content: string, pattern: RegExp, replacementText: string, keepMatchedText?: KeepMatchedText) {
-    const match = content.match(pattern);
+function replaceInSourceCode(content: string, pattern: RegExp, replacementText: string, keepMatchedText?: KeepMatchedText): string | null {
+    const match = pattern.exec(content);
     if (match) {
         if (keepMatchedText) {
             const matchedText = match[0];
@@ -37,10 +37,10 @@ function replaceInSourceCode(content: string, pattern: RegExp, replacementText:
 
 }
 
-export function revealInVSCode(revealable: IRevealable | undefined, omitFocus: boolean) {
+export function revealInVSCode(revealable: IRevealable | undefined, omitFocus: boolean): Promise<void> {
     if (revealable && revealable.uiSourceCode && revealable.uiSourceCode._url) {
         // using Devtools legacy mode.
-        (self as any as IDevToolsWindow).InspectorFrontendHost.openInEditor(
+        (self as unknown as IDevToolsWindow).InspectorFrontendHost.openInEditor(
             revealable.uiSourceCode._url,
             revealable.lineNumber,
             revealable.columnNumber,
@@ -51,58 +51,59 @@ export function revealInVSCode(revealable: IRevealable | undefined, omitFocus: b
     return Promise.resolve();
 }
 
-export function getVscodeSettings(callback: (arg0: object) => void) {
+export function getVscodeSettings(callback: (arg0: Record<string, unknown>) => void): void {
     InspectorFrontendHost.getVscodeSettings(callback);
 }
 
-export function sendToVscodeOutput(message: string) {
+export function sendToVscodeOutput(message: string): void {
     // Since we are calling InspectorFrontendHost outside of root.js, we need to use InspectorFrontendHost.InspectorFrontendHostInstance
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
     InspectorFrontendHost.InspectorFrontendHostInstance.sendToVscodeOutput(message);
 }
 
-export function applyExtensionSettingsInstantiatePatch(content: string) {
+export function applyExtensionSettingsInstantiatePatch(content: string): string | null {
     const pattern = /const experiments\s*=\s*new ExperimentsSupport\(\);/;
     const replacementText = `const vscodeSettings={};`;
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.AtEnd);
 }
 
-export function applyExtensionSettingsRuntimeObjectPatch(content: string){
+export function applyExtensionSettingsRuntimeObjectPatch(content: string): string | null {
     const pattern = /experiments:\s*experiments/;
     const replacementText = ', vscodeSettings:vscodeSettings';
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.InFront);
 }
 
-export function applyCreateExtensionSettingsLegacyPatch(content: string) {
+export function applyCreateExtensionSettingsLegacyPatch(content: string): string | null {
     const pattern = /Root\.Runtime\.experiments/g;
     const replacementText = 'Root.Runtime.vscodeSettings = Runtime.vscodeSettings;';
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.AtEnd);
 }
 
-export function applyPortSettingsFunctionCreationPatch(content: string) {
+export function applyPortSettingsFunctionCreationPatch(content: string): string | null {
     const pattern = /static instance/g;
     const replacementText = getVscodeSettings.toString().slice(9);
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.AtEnd);
 }
 
-export function applyPortSettingsFunctionCallPatch(content: string) {
+export function applyPortSettingsFunctionCallPatch(content: string): string | null {
     const pattern = /this._descriptorsMap\s*=\s*{};/g;
     const replacementText = 'this.getVscodeSettings((vscodeSettingsObject) => {Object.assign(vscodeSettings, vscodeSettingsObject);});';
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.InFront);
 }
 
-export function applyCommonRevealerPatch(content: string) {
+export function applyCommonRevealerPatch(content: string): string | null {
     const pattern = /let reveal\s*=\s*function\s*\(revealable,\s*omitFocus\)\s*{/g;
     const replacementText = `let reveal = ${revealInVSCode.toString().slice(0, -1)}`;
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyStylesRevealerPatch(content: string) {
+export function applyStylesRevealerPatch(content: string): string | null {
     const pattern = /this\._navigateToSource\(selectElement,\s*true\);/g;
     const replacementText = '';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyStylesToggleFocusPatch(content: string) {
+export function applyStylesToggleFocusPatch(content: string): string | null {
     // Patch to fix accessibility focus issue when toggling a property with context menu option.
     const pattern = /contextMenu\.defaultSection\(\)\.appendCheckboxItem\(ls\s*`Toggle property[\s\S]+.const sectionIndex = this\._parentPane\.focusedSectionIndex\(\);/g;
     const replacementText = `
@@ -112,14 +113,14 @@ export function applyStylesToggleFocusPatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyQuickOpenPatch(content: string) {
+export function applyQuickOpenPatch(content: string): string | null {
     // This patch removes the ability to use the quick open menu (CTRL + P)
     const pattern = /handleAction\(context,\s*actionId\)\s*{\s*switch\s*\(actionId\)/;
     const replacementText = 'handleAction(context, actionId) { actionId = null; switch(actionId)';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyCommandMenuPatch(content: string) {
+export function applyCommandMenuPatch(content: string): string | null {
     // pattern intended to match logic of CommandMenu.attach()
     const pattern = /for\s*\(const action of actions\)\s*{\s*const category\s*=\s*action[\s\S]+this\._commands\.sort\(commandComparator\);/;
     const replacementText =
@@ -153,61 +154,61 @@ export function applyCommandMenuPatch(content: string) {
 
 // This function is needed for Elements-only version, but we need the drawer
 // for the Request Blocking tool when enabling the Network Panel.
-export function applyInspectorViewShowDrawerPatch(content: string) {
+export function applyInspectorViewShowDrawerPatch(content: string): string | null {
     // This patch hides the drawer.
     const pattern = /_showDrawer\(focus\)\s*{/g;
     const replacementText = `_showDrawer(focus) { if (!${isDrawerEnabled}) {return false;}`;
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyInspectorViewCloseDrawerPatch(content: string) {
+export function applyInspectorViewCloseDrawerPatch(content: string): string | null {
     // this patch closes the drawer if the network tool is disabled
     const pattern = /InspectorView\.InspectorView\.instance\(\)\.createToolbars\(\);/g;
     const replacementText = `if (!${isDrawerEnabled}) {InspectorView.InspectorView.instance()._closeDrawer();}`;
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.InFront);
 }
 
-export function applyMainViewPatch(content: string) {
+export function applyMainViewPatch(content: string): string | null {
     const pattern = /const moreTools\s*=\s*[^;]+;/g;
     const replacementText = 'const moreTools = { defaultSection: () => ({ appendItem: () => {} }) };';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyScreencastAppPatch(content: string) {
+export function applyScreencastAppPatch(content: string): string | null {
     // This patch fixes screencasting functionality in version 88
     const pattern = /this\._getAppProviderInstance\('Main.SimpleAppProvider'\);/g;
     const replacementText = 'Runtime.Runtime.instance().extension(AppProvider.AppProvider).instance();';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyScreencastRepaintPatch(content: string) {
+export function applyScreencastRepaintPatch(content: string): string | null {
     // This patch removes a condition that calls repaint to restore scroll functionality
     const pattern = /\(this._highlightNode\)/g;
     const replacementText = '(true)';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyRemoveBreakOnContextMenuItem(content: string) {
+export function applyRemoveBreakOnContextMenuItem(content: string): string | null {
     const pattern = /const breakpointsMenu\s+=[\s\S]+hasDOMBreakpoint\(.*\);\s+}\s+}/;
     const replacementText = '';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyShowDrawerTabs(content: string) {
+export function applyShowDrawerTabs(content: string): string | null {
     // Appends the Request Blocking tab or Whats New tab in the drawer even if it is not open.
     const pattern = /if\s*\(!view\.isCloseable\(\)\)/;
     const replacementText = "if(!view.isCloseable()||id==='network.blocked-urls'||id==='release-note')";
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyPersistDrawerTabs(content: string) {
+export function applyPersistDrawerTabs(content: string): string | null {
     // Removes the close button from the Request blocking and Whats New tab tab by making the tab non-closeable.
     const pattern = /this\._closeable\s*=\s*closeable;/;
     const replacementText = "this._closeable= (id==='network.blocked-urls' | id === 'release-note')?false:closeable;";
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applySetTabIconPatch(content: string) {
+export function applySetTabIconPatch(content: string): string | null {
     // Adding undefined check in SetTabIcon so it doesn't throw an error trying to access disabled tabs.
     // This is needed due to applyAppendTabPatch which removes unused tabs from the tablist.
     const pattern = /setTabIcon\(id,\s*icon\)\s*{\s*const tab\s*=\s*this\._tabsById\.get\(id\);/;
@@ -215,7 +216,7 @@ export function applySetTabIconPatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyAppendTabOverridePatch(content: string) {
+export function applyAppendTabOverridePatch(content: string): string | null {
     // The appendTab function chooses which tabs to put in the tabbed pane header section
     // showTabElement and selectTab are only called by tabs that have already been appended via appendTab.
     // Injecting our verifications by redirecting appendTab to appendTabOverride
@@ -225,7 +226,7 @@ export function applyAppendTabOverridePatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyAppendTabConditionsPatch(content: string) {
+export function applyAppendTabConditionsPatch(content: string): string | null {
     const elementsTabs = [
         'elements',
         'Styles',
@@ -287,21 +288,21 @@ export function applyEnableNetworkPatch(): string {
     }`;
 }
 
-export function applyDefaultTabPatch(content: string) {
+export function applyDefaultTabPatch(content: string): string | null {
     // This patches removes the _defaultTab property
     const pattern = /this\._defaultTab\s*=\s*[^;]+;/g;
     const replacementText = 'this._defaultTab=undefined;';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyDrawerTabLocationPatch(content: string) {
+export function applyDrawerTabLocationPatch(content: string): string | null {
     // This shows the drawer with the network.blocked-urls tab open.
     const pattern = /this._showDrawer.bind\s*\(this,\s*false\),\s*'drawer-view',\s*true,\s*true/g;
     const replacementText = "this._showDrawer.bind\(this, false\), 'drawer-view', true, true, 'network.blocked-urls'";
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyInspectorCommonCssPatch(content: string) {
+export function applyInspectorCommonCssPatch(content: string): string | null {
     // Hides the more tools button in the drawer and reveals the screen cast button.
     const separator = '\\n';
 
@@ -324,7 +325,7 @@ export function applyInspectorCommonCssPatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyInspectorCommonNetworkPatch(content: string) {
+export function applyInspectorCommonNetworkPatch(content: string): string | null {
     // Hides export HAR button and pretty print button and reveals the Network search close button in the Network Panel.
     const separator = '\\n';
 
@@ -354,7 +355,7 @@ export function applyInspectorCommonNetworkPatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyInspectorCommonContextMenuPatch(content: string) {
+export function applyInspectorCommonContextMenuPatch(content: string): string | null {
     // Hides certain context menu items from elements in the Network Panel.
     const separator = '\\n';
 
@@ -374,7 +375,7 @@ export function applyInspectorCommonContextMenuPatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyInspectorCommonCssRightToolbarPatch(content: string) {
+export function applyInspectorCommonCssRightToolbarPatch(content: string): string | null {
     const pattern = /(\.tabbed-pane-right-toolbar\s*\{([^\}]*)?\})/g;
     const replacementText =
         `.tabbed-pane-right-toolbar {
@@ -383,7 +384,7 @@ export function applyInspectorCommonCssRightToolbarPatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyInspectorCommonCssTabSliderPatch(content: string) {
+export function applyInspectorCommonCssTabSliderPatch(content: string): string | null {
     const pattern = /(\.tabbed-pane-tab-slider\s*\{([^\}]*)?\})/g;
     const replacementText =
         `.tabbed-pane-tab-slider {
@@ -392,7 +393,7 @@ export function applyInspectorCommonCssTabSliderPatch(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyContextMenuRevealOption(content: string) {
+export function applyContextMenuRevealOption(content: string): string | null {
     const pattern = /const destination\s*=\s*Revealer\.revealDestination\(revealable\);/;
     const replacementText = `
         let destination = Revealer.revealDestination(revealable);
@@ -402,33 +403,33 @@ export function applyContextMenuRevealOption(content: string) {
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyMoveToContextMenuPatch(content: string) {
+export function applyMoveToContextMenuPatch(content: string): string | null {
     const pattern = /const locationName\s*=\s*ViewManager\.instance\(\)\.locationNameForViewId\(tabId\);/;
     const replacementText = `return;`;
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.InFront);
 }
 
-export function applyThemePatch(content: string) {
+export function applyThemePatch(content: string): string | null {
     // Sets the theme of the DevTools
     const pattern = /const settingDescriptor/;
     const replacementText = 'const theme = Root.Runtime.vscodeSettings.theme;if(theme){themeSetting.set(theme);} const settingDescriptor';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyRemovePreferencePatch(content: string) {
+export function applyRemovePreferencePatch(content: string): string | null {
     // This patch returns early whe trying to remove localStorage which we already set as undefined
     const pattern = /removePreference\(name\)\s*{\s*delete window\.localStorage\[name\];\s*}/;
     const replacementText = 'removePreference(name){return;}';
     return replaceInSourceCode(content, pattern, replacementText);
 }
 
-export function applyRerouteConsoleMessagePatch(content: string) {
+export function applyRerouteConsoleMessagePatch(content: string): string | null {
     const pattern = /this\.dispatchEventToListeners\(Events\$h\.MessageAdded,\s*msg\);/g;
     const replacementText = `sendToVscodeOutput(msg.level + ': ' + msg.messageText); ${sendToVscodeOutput.toString()}`;
     return replaceInSourceCode(content, pattern, replacementText, KeepMatchedText.InFront);
 }
 
-export function applyScreencastCursorPatch(content: string) {
+export function applyScreencastCursorPatch(content: string): string | null {
     // This patch removes the touch cursor from the screencast view
     const pattern = /\('div',\s*'screencast-canvas-container'\)\);/g;
     const replacementText = "this._canvasContainerElement.style.cursor = 'unset';";
diff --git a/src/host/polyfills/textSelection.ts b/src/host/polyfills/textSelection.ts
index 7ff86c8..d5d5a6a 100644
--- a/src/host/polyfills/textSelection.ts
+++ b/src/host/polyfills/textSelection.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 
-export default function applySetupTextSelectionPatch(content: string) {
+export function applySetupTextSelectionPatch(content: string): string | null {
     const pattern = /_setupTextSelectionHack\(stylePaneWrapperElement\)\s*{/g;
     if (content.match(pattern)) {
         return content.replace(pattern, '_setupTextSelectionHack() { return;');
diff --git a/src/host/polyfills/thirdPartyI18n.ts b/src/host/polyfills/thirdPartyI18n.ts
index 1f32d4c..5c3c581 100644
--- a/src/host/polyfills/thirdPartyI18n.ts
+++ b/src/host/polyfills/thirdPartyI18n.ts
@@ -3,7 +3,7 @@
 
 // Needs to change when the following bug is fixed:
 // #341: Devtools should be localized as in the browser.
-export default function applyThirdPartyI18nLocalesPatch(content: string) {
+export function applyThirdPartyI18nLocalesPatch(content: string): string | null {
     const pattern = /const\s*locales\s*=\s*\{[^]+?};/g;
     if (content.match(pattern)) {
         return content.replace(pattern, "const locales = {'en-US': {'title': 'value'},};");
diff --git a/src/host/toolsHost.ts b/src/host/toolsHost.ts
index f7893f5..ea2dd1e 100644
--- a/src/host/toolsHost.ts
+++ b/src/host/toolsHost.ts
@@ -9,39 +9,40 @@ import {
     WebSocketEvent,
     WebviewEvent,
 } from '../common/webviewEvents';
-import ToolsResourceLoader from './toolsResourceLoader';
-import ToolsWebSocket from './toolsWebSocket';
+import { ToolsResourceLoader } from './toolsResourceLoader';
+import { ToolsWebSocket } from './toolsWebSocket';
 
-export default class ToolsHost {
+export class ToolsHost {
     // We need to add a dummy property to get around build errors for sendToVscodeOutput.
-    // tslint:disable-next-line:variable-name
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     InspectorFrontendHostInstance: any;
     private resourceLoader: Readonly<ToolsResourceLoader> | undefined;
     private getHostCallbacksNextId = 0;
-    private getHostCallbacks: Map<number, (preferences: object) => void> = new Map();
+    private getHostCallbacks: Map<number, (preferences: Record<string, unknown>) => void> =
+        new Map<number,(preferences: Record<string, unknown>) => void>();
 
-    setResourceLoader(resourceLoader: Readonly<ToolsResourceLoader>) {
+    setResourceLoader(resourceLoader: Readonly<ToolsResourceLoader>): void {
         this.resourceLoader = resourceLoader;
     }
 
-    isHostedMode() {
+    isHostedMode(): boolean {
         // DevTools will always be inside a webview
         return true;
     }
 
-    getPreferences(callback: (preferences: any) => void) {
+    getPreferences(callback: (preferences: Record<string, unknown>) => void): void {
         // Load the preference via the extension workspaceState
         const id = this.getHostCallbacksNextId++;
         this.getHostCallbacks.set(id, callback);
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'getState', { id });
     }
 
-    setPreference(name: string, value: string) {
+    setPreference(name: string, value: string): void {
         // Save the preference via the extension workspaceState
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'setState', { name, value });
     }
 
-    recordEnumeratedHistogram(actionName: string, actionCode: number, bucketSize: number) {
+    recordEnumeratedHistogram(actionName: string, actionCode: number, _bucketSize: number): void {
         // Inform the extension of the DevTools telemetry event
         this.sendTelemetry({
             data: actionCode,
@@ -50,7 +51,7 @@ export default class ToolsHost {
         });
     }
 
-    recordPerformanceHistogram(histogramName: string, duration: number) {
+    recordPerformanceHistogram(histogramName: string, duration: number): void {
         // Inform the extension of the DevTools telemetry event
         this.sendTelemetry({
             data: duration,
@@ -66,7 +67,7 @@ export default class ToolsHost {
         filename: string,
         sourceUrl: string,
         lineno: number,
-        colno: number) {
+        colno: number): void {
         // Package up the error info to send to the extension
         const data = { message, stack, filename, sourceUrl, lineno, colno };
 
@@ -78,69 +79,69 @@ export default class ToolsHost {
         });
     }
 
-    openInEditor(url: string, line: number, column: number, ignoreTabChanges: boolean) {
+    openInEditor(url: string, line: number, column: number, ignoreTabChanges: boolean): void {
         // Forward the data to the extension
         const request: IOpenEditorData = { column, line, url, ignoreTabChanges };
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'openInEditor', request);
     }
 
-    getVscodeSettings(callback: (arg0: object) => void) {
+    getVscodeSettings(callback: (arg0: Record<string, unknown>) => void): void {
         const id = this.getHostCallbacksNextId++;
         this.getHostCallbacks.set(id, callback);
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'getVscodeSettings', {id});
     }
 
-    sendToVscodeOutput(consoleMessage: string) {
+    sendToVscodeOutput(consoleMessage: string): void {
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'consoleOutput', {consoleMessage});
     }
 
-    copyText(clipboardData: string) {
+    copyText(clipboardData: string): void {
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'copyText', {clipboardData});
     }
 
-    openInNewTab(url: string) {
+    openInNewTab(url: string): void {
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'openUrl', {url});
     }
 
-    focusEditor(next: boolean) {
+    focusEditor(next: boolean): void {
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'focusEditor', {next});
     }
 
-    focusEditorGroup(next: boolean) {
+    focusEditorGroup(next: boolean): void {
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'focusEditorGroup', {next});
     }
 
     onMessageFromChannel(e: WebviewEvent, args: string): boolean {
         switch (e) {
             case 'getState': {
-                const { id, preferences } = JSON.parse(args);
+                const { id, preferences } = JSON.parse(args) as {id: number, preferences: Record<string, unknown>};
                 this.fireGetHostCallback(id, preferences);
                 break;
             }
 
             case 'getUrl': {
-                const { id, content } = JSON.parse(args);
+                const { id, content } = JSON.parse(args) as {id: number, content: string};
                 this.fireGetUrlCallback(id, content);
                 break;
             }
 
             case 'websocket': {
-                const { event, message } = JSON.parse(args);
+                const { event, message } = JSON.parse(args) as {event: WebSocketEvent, message: string};
                 this.fireWebSocketCallback(event, message);
                 break;
             }
 
             case 'getVscodeSettings': {
-                const parsedArgs = JSON.parse(args);
+                const parsedArgs = JSON.parse(args) as {parsedArgs: Record<string, unknown>};
                 this.parseVscodeSettingsObject(parsedArgs);
             }
         }
         return true;
     }
 
-    private parseVscodeSettingsObject(vscodeObject: any) {
-        const id: number = vscodeObject.id;
-        const themeString: ThemeString = vscodeObject.themeString;
+    private parseVscodeSettingsObject(vscodeObject: Record<string, unknown>) {
+        const id: number = vscodeObject.id as number;
+        const themeString: ThemeString = vscodeObject.themeString as ThemeString;
         let theme;
         switch (themeString) {
             case 'System preference':
@@ -167,8 +168,9 @@ export default class ToolsHost {
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'telemetry', telemetry);
     }
 
-    private fireGetHostCallback(id: number, args: object) {
+    private fireGetHostCallback(id: number, args: Record<string, unknown>) {
         if (this.getHostCallbacks.has(id)) {
+            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
             this.getHostCallbacks.get(id)!(args);
             this.getHostCallbacks.delete(id);
         }
diff --git a/src/host/toolsResourceLoader.ts b/src/host/toolsResourceLoader.ts
index 628ef9c..dafb391 100644
--- a/src/host/toolsResourceLoader.ts
+++ b/src/host/toolsResourceLoader.ts
@@ -7,16 +7,16 @@ export interface IRuntimeResourceLoader {
     loadResourcePromise: (url: string) => Promise<string>;
 }
 
-export default class ToolsResourceLoader {
+export class ToolsResourceLoader {
     private originalLoadResource: (url: string) => Promise<string>;
     private urlLoadNextId = 0;
-    private urlLoadResolvers: Map<number, (url: string) => void> = new Map();
+    private urlLoadResolvers: Map<number, (url: string) => void> = new Map<number,(url: string) => void>();
 
     private constructor(originalLoadResource: (url: string) => Promise<string>) {
         this.originalLoadResource = originalLoadResource;
     }
 
-    onResolvedUrlFromChannel(id: number, content: string) {
+    onResolvedUrlFromChannel(id: number, content: string): void {
         if (this.urlLoadResolvers.has(id)) {
             const resolve = this.urlLoadResolvers.get(id);
             if (resolve) {
@@ -39,7 +39,7 @@ export default class ToolsResourceLoader {
         return this.originalLoadResource(url);
     }
 
-    static overrideResourceLoading(loaderObject: IRuntimeResourceLoader) {
+    static overrideResourceLoading(loaderObject: IRuntimeResourceLoader): ToolsResourceLoader {
         const originalLoadResource = loaderObject.loadResourcePromise;
 
         // Replace the loader promise with our override version so we can control cross domain requests
diff --git a/src/host/toolsWebSocket.ts b/src/host/toolsWebSocket.ts
index ec1f5e7..be4ab3b 100644
--- a/src/host/toolsWebSocket.ts
+++ b/src/host/toolsWebSocket.ts
@@ -13,7 +13,7 @@ interface IMessageEvent {
  * so instead we replace it and forward all messages to/from the extension
  * which is able to create the real websocket connection to the target page.
  */
-export default class ToolsWebSocket {
+export class ToolsWebSocket {
     private static devtoolsWebSocket: ToolsWebSocket;
 
     onopen: (() => void) | undefined;
@@ -21,18 +21,18 @@ export default class ToolsWebSocket {
     onerror: (() => void) | undefined;
     onmessage: ((e: IMessageEvent) => void) | undefined;
 
-    constructor(url: string) {
+    constructor(_url: string) {
         ToolsWebSocket.devtoolsWebSocket = this;
         // Inform the extension that we are ready to receive messages
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'ready');
     }
 
-    send(message: string) {
+    send(message: string): void {
         // Forward the message to the extension
         encodeMessageForChannel(msg => window.parent.postMessage(msg, '*'), 'websocket', { message });
     }
 
-    onMessageFromChannel(e: WebSocketEvent, message?: string) {
+    onMessageFromChannel(e: WebSocketEvent, message?: string): void {
         switch (e) {
             case 'open':
                 if (this.onopen) {
@@ -61,7 +61,7 @@ export default class ToolsWebSocket {
         }
     }
 
-    static get instance() {
+    static get instance(): ToolsWebSocket {
         return ToolsWebSocket.devtoolsWebSocket;
     }
 }
diff --git a/src/launchDebugProvider.ts b/src/launchDebugProvider.ts
index a3b34a9..bc9fac6 100644
--- a/src/launchDebugProvider.ts
+++ b/src/launchDebugProvider.ts
@@ -14,13 +14,13 @@ type AttachCallback = (
     context: vscode.ExtensionContext,
     targetUrl?: string,
     config?: Partial<IUserConfig>,
-    useRetry?: boolean) => void;
+    useRetry?: boolean) => void | Promise<void>;
 type LaunchCallback = (
     context: vscode.ExtensionContext,
     launchUrl?: string,
-    config?: Partial<IUserConfig>) => void;
+    config?: Partial<IUserConfig>) => void | Promise<void>;
 
-export default class LaunchDebugProvider implements vscode.DebugConfigurationProvider {
+export class LaunchDebugProvider implements vscode.DebugConfigurationProvider {
     private readonly context: vscode.ExtensionContext;
     private readonly telemetryReporter: Readonly<TelemetryReporter>;
     private readonly attach: AttachCallback;
@@ -38,8 +38,8 @@ export default class LaunchDebugProvider implements vscode.DebugConfigurationPro
     }
 
     provideDebugConfigurations(
-        folder: vscode.WorkspaceFolder | undefined,
-        token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration[]> {
+        _folder: vscode.WorkspaceFolder | undefined,
+        _token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration[]> {
         return Promise.resolve([{
             name: 'Launch Microsoft Edge and open the Edge DevTools',
             request: 'launch',
@@ -50,7 +50,7 @@ export default class LaunchDebugProvider implements vscode.DebugConfigurationPro
 
     resolveDebugConfiguration(
         folder: vscode.WorkspaceFolder | undefined,
-        config: vscode.DebugConfiguration, token?: vscode.CancellationToken):
+        config: vscode.DebugConfiguration, _token?: vscode.CancellationToken):
         vscode.ProviderResult<vscode.DebugConfiguration> {
         const userConfig = config as Partial<IUserConfig>;
 
@@ -58,10 +58,10 @@ export default class LaunchDebugProvider implements vscode.DebugConfigurationPro
             const targetUri: string = this.getUrlFromConfig(folder, config);
             if (config.request && config.request === 'attach') {
                 this.telemetryReporter.sendTelemetryEvent('debug/attach');
-                this.attach(this.context, targetUri, userConfig);
+                void this.attach(this.context, targetUri, userConfig);
             } else if (config.request && config.request === 'launch') {
                 this.telemetryReporter.sendTelemetryEvent('debug/launch');
-                this.launch(this.context, targetUri, userConfig);
+                void this.launch(this.context, targetUri, userConfig);
             }
         } else if (config && (config.type === 'edge' || config.type === 'msedge')) {
             const settings = vscode.workspace.getConfiguration(SETTINGS_STORE_NAME);
@@ -75,13 +75,13 @@ export default class LaunchDebugProvider implements vscode.DebugConfigurationPro
 
                 // Allow the debugger to actually launch the browser before attaching
                 setTimeout(() => {
-                    this.attach(this.context, userConfig.url, userConfig, /* useRetry=*/ true);
+                    void this.attach(this.context, userConfig.url, userConfig, /* useRetry=*/ true);
                 }, SETTINGS_DEFAULT_ATTACH_INTERVAL);
             }
             return Promise.resolve(config);
         } else {
             this.telemetryReporter.sendTelemetryEvent('debug/error/config_not_found');
-            vscode.window.showErrorMessage('No supported launch config was found.');
+            vscode.window.showErrorMessage('No supported launch config was found.') as Promise<void>;
         }
 
         return undefined;
@@ -91,15 +91,15 @@ export default class LaunchDebugProvider implements vscode.DebugConfigurationPro
         let outUrlString = '';
 
         if (config.file) {
-            outUrlString = config.file;
+            outUrlString = config.file as string;
             if (folder) {
                 outUrlString = outUrlString.replace('${workspaceFolder}', folder.uri.path);
             }
             outUrlString = (outUrlString.startsWith('/') ? 'file://' : 'file:///') + outUrlString;
         } else if (config.url) {
-            outUrlString = config.url;
+            outUrlString = config.url as string;
         } else if (config.urlFilter) {
-            outUrlString = config.urlFilter;
+            outUrlString = config.urlFilter as string;
         }
 
         return outUrlString;
diff --git a/src/panelSocket.ts b/src/panelSocket.ts
index 9e945a1..5648cbc 100644
--- a/src/panelSocket.ts
+++ b/src/panelSocket.ts
@@ -20,15 +20,15 @@ export class PanelSocket extends EventEmitter {
         this.postMessageToDevTools = postMessageToDevTools;
     }
 
-    get isConnectedToTarget() {
+    get isConnectedToTarget(): boolean {
         return this.isConnected;
     }
 
-    onMessageFromWebview(message: string) {
+    onMessageFromWebview(message: string): void {
         parseMessageFromChannel(message, (eventName, args) => this.onMessageParsed(eventName, args));
     }
 
-    dispose() {
+    dispose(): void {
         if (this.socket) {
             this.isConnected = false;
             this.socket.close();
@@ -50,14 +50,16 @@ export class PanelSocket extends EventEmitter {
                 this.connectToTarget();
             }
 
-            const { message } = JSON.parse(args);
+            const { message } = JSON.parse(args) as {message: string};
             if (message && message[0] === '{') {
                 if (!this.isConnected) {
                     // DevTools are sending a message before the real websocket has finished opening so cache it
                     this.messages.push(message);
                 } else {
                     // Websocket ready so send the message directly
-                    this.socket!.send(message);
+                    if (this.socket) {
+                        this.socket.send(message);
+                    }
                 }
             }
         }
diff --git a/src/utils.ts b/src/utils.ts
index c34d832..3345755 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -11,7 +11,7 @@ import * as vscode from 'vscode';
 import * as debugCore from 'vscode-chrome-debug-core';
 import TelemetryReporter from 'vscode-extension-telemetry';
 import packageJson from '../package.json';
-import DebugTelemetryReporter from './debugTelemetryReporter';
+import { DebugTelemetryReporter } from './debugTelemetryReporter';
 
 import puppeteer from 'puppeteer-core';
 
@@ -91,7 +91,7 @@ export const SETTINGS_DEFAULT_ATTACH_TIMEOUT = 10000;
 export const SETTINGS_DEFAULT_ATTACH_INTERVAL = 200;
 
 const WIN_APP_DATA = process.env.LOCALAPPDATA || '/';
-const msEdgeBrowserMapping: Map<BrowserFlavor, IBrowserPath> = new Map();
+const msEdgeBrowserMapping: Map<BrowserFlavor, IBrowserPath> = new Map<BrowserFlavor, IBrowserPath>();
 
 export interface IRemoteTargetJson {
     [index: string]: string;
@@ -124,7 +124,7 @@ export function fetchUri(uri: string, options: https.RequestOptions = {}): Promi
         get(options, response => {
             let responseData = '';
             response.on('data', chunk => {
-                responseData += chunk.toString();
+                responseData += chunk;
             });
             response.on('end', () => {
                 // Sometimes the 'error' event is not fired. Double check here.
@@ -155,7 +155,8 @@ export function fixRemoteWebSocket(
     remotePort: number,
     target: IRemoteTargetJson): IRemoteTargetJson {
     if (target.webSocketDebuggerUrl) {
-        const addressMatch = target.webSocketDebuggerUrl.match(/ws:\/\/([^/]+)\/?/);
+        const re = /ws:\/\/([^/]+)\/?/;
+        const addressMatch = re.exec(target.webSocketDebuggerUrl);
         if (addressMatch) {
             const replaceAddress = `${remoteAddress}:${remotePort}`;
             target.webSocketDebuggerUrl = target.webSocketDebuggerUrl.replace(addressMatch[1], replaceAddress);
@@ -170,7 +171,7 @@ export function fixRemoteWebSocket(
  * @param hostname The remote hostname
  * @param port The remote port
  */
-export async function getListOfTargets(hostname: string, port: number, useHttps: boolean): Promise<any[]> {
+export async function getListOfTargets(hostname: string, port: number, useHttps: boolean): Promise<IRemoteTargetJson[]> {
     const checkDiscoveryEndpoint = (uri: string) => {
         return fetchUri(uri, { headers: { Host: 'localhost' } });
     };
@@ -191,7 +192,7 @@ export async function getListOfTargets(hostname: string, port: number, useHttps:
 
     let result: IRemoteTargetJson[];
     try {
-        result = JSON.parse(jsonResponse);
+        result = JSON.parse(jsonResponse) as IRemoteTargetJson[];
     } catch {
         result = [];
     }
@@ -242,7 +243,7 @@ export function getRemoteEndpointSettings(config: Partial<IUserConfig> = {}): ID
  *
  * @param context The vscode context
  */
-export function createTelemetryReporter(context: vscode.ExtensionContext): Readonly<TelemetryReporter> {
+export function createTelemetryReporter(_context: vscode.ExtensionContext): Readonly<TelemetryReporter> {
     if (packageJson && vscode.env.machineId !== 'someValue.machineId') {
         // Use the real telemetry reporter
         return new TelemetryReporter(packageJson.name, packageJson.version, packageJson.aiKey);
@@ -292,7 +293,7 @@ export async function getBrowserPath(config: Partial<IUserConfig> = {}): Promise
  * @param targetUrl The url of the page to open
  * @param userDataDir The user data directory for the launched instance
  */
-export async function launchBrowser(browserPath: string, port: number, targetUrl: string, userDataDir?: string) {
+export async function launchBrowser(browserPath: string, port: number, targetUrl: string, userDataDir?: string): Promise<puppeteer.Browser> {
     const args = [
         '--no-first-run',
         '--no-default-browser-check',
@@ -317,10 +318,10 @@ export async function launchBrowser(browserPath: string, port: number, targetUrl
  * @param port The port of the browser
  * @param tabUrl The url to open, if any
  */
-export async function openNewTab(hostname: string, port: number, tabUrl?: string) {
+export async function openNewTab(hostname: string, port: number, tabUrl?: string): Promise<IRemoteTargetJson | undefined> {
     try {
-        const json = await fetchUri(`http://${hostname}:${port}/json/new?${tabUrl}`);
-        const target: IRemoteTargetJson | undefined = JSON.parse(json);
+        const json = await fetchUri(`http://${hostname}:${port}/json/new?${tabUrl ? tabUrl : ''}`);
+        const target: IRemoteTargetJson | undefined = JSON.parse(json) as IRemoteTargetJson | undefined;
         return target;
     } catch {
         return undefined;
@@ -332,7 +333,7 @@ export async function openNewTab(hostname: string, port: number, tabUrl?: string
  *
  * @param uri The string from which to remove the trailing slash (if any)
  */
-export function removeTrailingSlash(uri: string) {
+export function removeTrailingSlash(uri: string): string {
     return (uri.endsWith('/') ? uri.slice(0, -1) : uri);
 }
 
@@ -395,7 +396,7 @@ export function getRuntimeConfig(config: Partial<IUserConfig> = {}): IRuntimeCon
  * @param webRoot The value to use for replacement.
  * @param entry The path containing the '${webRoot}' string that we will replace.
  */
-export function replaceWebRootInSourceMapPathOverridesEntry(webRoot: string, entry: string) {
+export function replaceWebRootInSourceMapPathOverridesEntry(webRoot: string, entry: string): string {
     if (webRoot) {
         const webRootIndex = entry.indexOf('${webRoot}');
         if (webRootIndex === 0) {
@@ -442,7 +443,7 @@ export function applyPathMapping(
             .replace(/\*/g, '(.*)')
             .replace(/\\\\/g, '/');
         const leftRegex = new RegExp(`^${leftRegexSegment}$`, 'i');
-        const overridePatternMatches = forwardSlashSourcePath.match(leftRegex);
+        const overridePatternMatches = leftRegex.exec(forwardSlashSourcePath);
         if (!overridePatternMatches) {
             continue;
         }


Test patch:
diff --git a/src/cdpTarget.test.ts b/src/cdpTarget.test.ts
index ea1f1e9..7b1ccf2 100644
--- a/src/cdpTarget.test.ts
+++ b/src/cdpTarget.test.ts
@@ -22,8 +22,8 @@ describe("CDPTarget", () => {
             url: "url",
         } as IRemoteTargetJson;
 
-        const { default: cdpTarget } = await import("./cdpTarget");
-        const target = new cdpTarget(json, "");
+        const ct = await import("./cdpTarget");
+        const target = new ct.CDPTarget(json, "");
         expect(target).toBeDefined();
     });
 
@@ -34,8 +34,8 @@ describe("CDPTarget", () => {
             url: "url",
         } as IRemoteTargetJson;
 
-        const { default: cdpTarget } = await import("./cdpTarget");
-        const target = new cdpTarget(json, "", "path");
+        const ct = await import("./cdpTarget");
+        const target = new ct.CDPTarget(json, "", "path");
         expect(target.iconPath).toBeDefined();
         expect(target.iconPath!.dark).toEqual(
             expect.stringMatching(/path(\\|\/)resources(\\|\/)dark(\\|\/)extension.svg/g));
@@ -51,14 +51,14 @@ describe("CDPTarget", () => {
             webSocketDebuggerUrl: "webSocketDebuggerUrl",
         } as IRemoteTargetJson;
 
-        const { default: cdpTarget } = await import("./cdpTarget");
-        const target = new cdpTarget(json, "");
+        const ct = await import("./cdpTarget");
+        const target = new ct.CDPTarget(json, "");
         target.label = "label";
         expect(target.websocketUrl).toEqual(json.webSocketDebuggerUrl);
         expect(target.description).toEqual(json.url);
         expect(target.tooltip).toEqual(`label - ${json.url}`);
 
-        const target2 = new cdpTarget(json, "type");
+        const target2 = new ct.CDPTarget(json, "type");
         target2.label = "label";
         expect(target2.description).toEqual(json.type);
         expect(target2.tooltip).toEqual(`label - ${json.type}`);
@@ -72,8 +72,8 @@ describe("CDPTarget", () => {
             webSocketDebuggerUrl: "webSocketDebuggerUrl",
         } as IRemoteTargetJson;
 
-        const { default: cdpTarget } = await import("./cdpTarget");
-        const target = new cdpTarget(json, "");
+        const ct = await import("./cdpTarget");
+        const target = new ct.CDPTarget(json, "");
         expect(target.getChildren().length).toEqual(4);
     });
 });
diff --git a/src/cdpTargetsProvider.test.ts b/src/cdpTargetsProvider.test.ts
index faae5d4..144e760 100644
--- a/src/cdpTargetsProvider.test.ts
+++ b/src/cdpTargetsProvider.test.ts
@@ -6,7 +6,7 @@
 
 import { ExtensionContext } from "vscode";
 import TelemetryReporter from "vscode-extension-telemetry";
-import CDPTarget from "./cdpTarget";
+import { CDPTarget } from "./cdpTarget";
 import { createFakeExtensionContext, createFakeTelemetryReporter, createFakeVSCode, Mocked } from "./test/helpers";
 import { IRemoteTargetJson } from "./utils";
 
@@ -20,20 +20,20 @@ describe("CDPTargetsProvider", () => {
         mockVSCode = createFakeVSCode() as any;
         mockReporter = createFakeTelemetryReporter();
 
-        jest.doMock("./cdpTarget", () => jest.fn());
+        jest.doMock("./cdpTarget", () => ({ CDPTarget: jest.fn() }));
         jest.doMock("vscode", () => mockVSCode, { virtual: true });
         jest.resetModules();
     });
 
     it("gets created successfully", async () => {
-        const { default: cdpTargetsProvider } = await import("./cdpTargetsProvider");
-        const provider = new cdpTargetsProvider(mockContext, mockReporter);
+        const ctp = await import("./cdpTargetsProvider");
+        const provider = new ctp.CDPTargetsProvider(mockContext, mockReporter);
         expect(provider).toBeDefined();
     });
 
     it("returns the element from getTreeItem", async () => {
-        const { default: cdpTargetsProvider } = await import("./cdpTargetsProvider");
-        const provider = new cdpTargetsProvider(mockContext, mockReporter);
+        const ctp = await import("./cdpTargetsProvider");
+        const provider = new ctp.CDPTargetsProvider(mockContext, mockReporter);
         const expectedElement = {} as CDPTarget;
         expect(provider.getTreeItem(expectedElement)).toEqual(expectedElement);
     });
@@ -46,16 +46,16 @@ describe("CDPTargetsProvider", () => {
             };
         } as any;
 
-        const { default: cdpTargetsProvider } = await import("./cdpTargetsProvider");
-        const provider = new cdpTargetsProvider(mockContext, mockReporter);
+        const ctp = await import("./cdpTargetsProvider");
+        const provider = new ctp.CDPTargetsProvider(mockContext, mockReporter);
         provider.refresh();
         expect(mockFire).toHaveBeenCalled();
         expect(mockReporter.sendTelemetryEvent).toHaveBeenCalled();
     });
 
     it("calls getChildren on the element", async () => {
-        const { default: cdpTargetsProvider } = await import("./cdpTargetsProvider");
-        const provider = new cdpTargetsProvider(mockContext, mockReporter);
+        const ctp = await import("./cdpTargetsProvider");
+        const provider = new ctp.CDPTargetsProvider(mockContext, mockReporter);
         const expectedChildren = [1, 2, 3];
         const mockElement = {
             getChildren: jest.fn(() => expectedChildren),
@@ -87,13 +87,13 @@ describe("CDPTargetsProvider", () => {
             }),
         };
         jest.doMock("./utils", () => mockUtils);
-        jest.doMock("./cdpTarget", () => function CDPTargetInstance(json: IRemoteTargetJson) {
-            return { targetJson: json };
-        });
+        jest.doMock("./cdpTarget", () => ({
+            CDPTarget: jest.fn((json: IRemoteTargetJson) => ({ targetJson: json }))
+        }));
         jest.resetModules();
 
-        const { default: cdpTargetsProvider } = await import("./cdpTargetsProvider");
-        const provider = new cdpTargetsProvider(mockContext, mockReporter);
+        const ctp = await import("./cdpTargetsProvider");
+        const provider = new ctp.CDPTargetsProvider(mockContext, mockReporter);
         const result = await provider.getChildren();
         expect(result.length).toEqual(allTargets.length);
 
@@ -105,11 +105,11 @@ describe("CDPTargetsProvider", () => {
     });
 
     it("check if favicons are downloaded and cleared correctly", async () => {
-        const { default: cdpTargetsProvider } = await import("./cdpTargetsProvider");
+        const ctp = await import("./cdpTargetsProvider");
         const fs = require('fs');
         const dir = './resources/favicons/';
 
-        const provider = new cdpTargetsProvider(mockContext, mockReporter);
+        const provider = new ctp.CDPTargetsProvider(mockContext, mockReporter);
         const microsoftIcon = await provider.downloadFaviconFromSitePromise("https://docs.microsoft.com/en-us/microsoft-edge/");
         const bingIcon = await provider.downloadFaviconFromSitePromise("https://www.bing.com/");
         expect(microsoftIcon).not.toEqual(null);
diff --git a/src/debugTelemetryReporter.test.ts b/src/debugTelemetryReporter.test.ts
index 3422cab..4ba80ef 100644
--- a/src/debugTelemetryReporter.test.ts
+++ b/src/debugTelemetryReporter.test.ts
@@ -4,21 +4,21 @@
 import { createFakeVSCode } from "./test/helpers";
 
 // Allow us to mock the console object for testing
-// tslint:disable: no-console
+// eslint-disable no-console
 
 jest.mock("vscode", () => createFakeVSCode(), { virtual: true });
 jest.mock("vscode-extension-telemetry");
 
 describe("debugTelemetryReporter", () => {
     it("gets created successfully", async () => {
-        const { default: telemetryReporter } = await import("./debugTelemetryReporter");
-        const reporter = new telemetryReporter();
+        const dtr = await import("./debugTelemetryReporter");
+        const reporter = new dtr.DebugTelemetryReporter();
         expect(reporter).toBeDefined();
     });
 
     it("sendTelemetryEvent writes to the console", async () => {
-        const { default: telemetryReporter } = await import("./debugTelemetryReporter");
-        const reporter = new telemetryReporter();
+        const dtr = await import("./debugTelemetryReporter");
+        const reporter = new dtr.DebugTelemetryReporter();
 
         global.console.log = jest.fn();
         const expectedName = "event";
@@ -32,8 +32,8 @@ describe("debugTelemetryReporter", () => {
     });
 
     it("dispose completes", async () => {
-        const { default: telemetryReporter } = await import("./debugTelemetryReporter");
-        const reporter = new telemetryReporter();
+        const dtr = await import("./debugTelemetryReporter");
+        const reporter = new dtr.DebugTelemetryReporter();
         await reporter.dispose();
     });
 });
diff --git a/src/extension.test.ts b/src/extension.test.ts
index 9a01a3f..5de1e04 100644
--- a/src/extension.test.ts
+++ b/src/extension.test.ts
@@ -23,6 +23,7 @@ describe("extension", () => {
         let mockUtils: Partial<Mocked<typeof import("./utils")>>;
         let mockRegisterTree: jest.Mock;
         let mockProviderRefresh: jest.Mock;
+        let mockProviderConstructor: jest.Mock;
         let mockClipboard: jest.Mock;
 
         beforeEach(() => {
@@ -43,9 +44,10 @@ describe("extension", () => {
             jest.doMock("./launchDebugProvider");
 
             mockProviderRefresh = jest.fn();
-            jest.doMock("./cdpTargetsProvider", () => function CDPTargetsProvider() {
+            mockProviderConstructor = jest.fn(() => ({refresh: mockProviderRefresh}));
+            jest.doMock("./cdpTargetsProvider", () => {
                 return {
-                    refresh: mockProviderRefresh,
+                    CDPTargetsProvider: mockProviderConstructor,
                 };
             });
 
diff --git a/src/host/host.test.ts b/src/host/host.test.ts
index 881ce64..1bb321a 100644
--- a/src/host/host.test.ts
+++ b/src/host/host.test.ts
@@ -66,7 +66,9 @@ describe("host", () => {
         it("sets resource loader", async () => {
             const mockOverride = jest.fn();
             jest.doMock("./toolsResourceLoader", () => ({
-                overrideResourceLoading: mockOverride,
+                ToolsResourceLoader: {
+                    overrideResourceLoading: mockOverride,
+                },
             }));
             jest.resetModules();
 
@@ -96,11 +98,12 @@ describe("host", () => {
                 parseMessageFromChannel: jest.fn(),
             };
             jest.doMock("../common/webviewEvents", () => mockWebviewEvents);
-            jest.doMock("./toolsHost", () => (function toolsHost() {
-                return {
-                    onMessageFromChannel: jest.fn(),
-                };
-            }));
+            jest.doMock("./toolsHost", () => ({
+                ToolsHost: function toolsHost() {
+                    return {
+                        onMessageFromChannel: jest.fn(),
+                    };
+            }}));
             jest.resetModules();
 
             const host = await import("./host");
diff --git a/src/host/polyfills/cssPaddingInline.test.ts b/src/host/polyfills/cssPaddingInline.test.ts
index 2fba6e4..d129efa 100644
--- a/src/host/polyfills/cssPaddingInline.test.ts
+++ b/src/host/polyfills/cssPaddingInline.test.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 import { testPatch } from "../../test/helpers";
-import applyPaddingInlineCssPatch from "./cssPaddingInline";
+import { applyPaddingInlineCssPatch } from "./cssPaddingInline";
 
 describe("cssPaddingInline", () => {
     it("applyPaddingInlineCssPatch correctly changes elements-disclosure text", async () => {
diff --git a/src/host/polyfills/runtime.test.ts b/src/host/polyfills/runtime.test.ts
index 545916f..a9b1295 100644
--- a/src/host/polyfills/runtime.test.ts
+++ b/src/host/polyfills/runtime.test.ts
@@ -1,19 +1,19 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-import { testPatch } from "../../test/helpers";
-import applyRuntimeImportScriptPathPrefixPatch from "./runtime";
-
-describe("importScriptPathPrefix replacement", () => {
-    it("verifies that importScriptPathPrefix is exposed as a module variable", async () => {
-        const filePath = "root/root.js";
-        const expectedStrings = ["self.importScriptPathPrefix=baseUrl.substring(0,baseUrl.lastIndexOf('/')+1);})();"];
-        const unexpectedStrings = ["let importScriptPathPrefix"]
-
-        testPatch(filePath, applyRuntimeImportScriptPathPrefixPatch, expectedStrings, unexpectedStrings);
-    });
-
-    it("verifies that importScriptPathPrefix correctly reports a wrong replacement", async () => {
-        const result = applyRuntimeImportScriptPathPrefixPatch("");
-        expect(result).toEqual(null);
-    });
-});
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import { testPatch } from "../../test/helpers";
+import { applyRuntimeImportScriptPathPrefixPatch } from "./runtime";
+
+describe("importScriptPathPrefix replacement", () => {
+    it("verifies that importScriptPathPrefix is exposed as a module variable", async () => {
+        const filePath = "root/root.js";
+        const expectedStrings = ["self.importScriptPathPrefix=baseUrl.substring(0,baseUrl.lastIndexOf('/')+1);})();"];
+        const unexpectedStrings = ["let importScriptPathPrefix"]
+
+        testPatch(filePath, applyRuntimeImportScriptPathPrefixPatch, expectedStrings, unexpectedStrings);
+    });
+
+    it("verifies that importScriptPathPrefix correctly reports a wrong replacement", async () => {
+        const result = applyRuntimeImportScriptPathPrefixPatch("");
+        expect(result).toEqual(null);
+    });
+});
diff --git a/src/host/polyfills/textSelection.test.ts b/src/host/polyfills/textSelection.test.ts
index bd4bff8..61487d3 100644
--- a/src/host/polyfills/textSelection.test.ts
+++ b/src/host/polyfills/textSelection.test.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 import { testPatch } from "../../test/helpers";
-import applySetupTextSelectionPatch from "./textSelection";
+import { applySetupTextSelectionPatch } from "./textSelection";
 
 describe("textSelection", () => {
     it("applySetupTextSelectionPatch correctly changes text", async () => {
diff --git a/src/host/polyfills/thirdPartyI18n.test.ts b/src/host/polyfills/thirdPartyI18n.test.ts
index d98ddbd..9db84e0 100644
--- a/src/host/polyfills/thirdPartyI18n.test.ts
+++ b/src/host/polyfills/thirdPartyI18n.test.ts
@@ -1,7 +1,7 @@
 // Copyright (c) Microsoft Corporation. All rights reserved.
 // Licensed under the MIT License.
 import { testPatch } from "../../test/helpers";
-import applyThirdPartyI18nLocalesPatch from "./thirdPartyI18n";
+import { applyThirdPartyI18nLocalesPatch } from "./thirdPartyI18n";
 
 describe("override i18n locales", () => {
     it("applyThirdPartyI18nLocalesPatch correctly changes text", async () => {
diff --git a/src/host/toolsHost.test.ts b/src/host/toolsHost.test.ts
index 72b9033..01bee3e 100644
--- a/src/host/toolsHost.test.ts
+++ b/src/host/toolsHost.test.ts
@@ -2,7 +2,7 @@
 // Licensed under the MIT License.
 
 import { getFirstCallback, Mocked } from "../test/helpers";
-import ToolsResourceLoader from "./toolsResourceLoader";
+import { ToolsResourceLoader } from "./toolsResourceLoader";
 
 describe("toolsHost", () => {
     let mockResourceLoader: Mocked<ToolsResourceLoader>;
@@ -24,8 +24,8 @@ describe("toolsHost", () => {
 
     describe("isHostedMode", () => {
         it("returns true", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             expect(host.isHostedMode()).toEqual(true);
         });
@@ -33,8 +33,8 @@ describe("toolsHost", () => {
 
     describe("getPreferences", () => {
         it("calls across to webview", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const mockCallback = jest.fn();
             host.getPreferences(mockCallback);
@@ -53,8 +53,8 @@ describe("toolsHost", () => {
         });
 
         it("fires callbacks on response from extension", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const mockCallback = jest.fn();
             host.getPreferences(mockCallback);
@@ -76,8 +76,8 @@ describe("toolsHost", () => {
 
     describe("setPreferences", () => {
         it("calls across to webview", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const expectedPref = {
                 name: "myPreference",
@@ -101,8 +101,8 @@ describe("toolsHost", () => {
 
     describe("recordEnumeratedHistogram", () => {
         it("calls across to extension", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const expectedTelemetry = {
                 data: 1000,
@@ -127,8 +127,8 @@ describe("toolsHost", () => {
 
     describe("recordPerformanceHistogram", () => {
         it("calls across to extension", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const expectedTelemetry = {
                 data: 500,
@@ -153,8 +153,8 @@ describe("toolsHost", () => {
 
     describe("reportError", () => {
         it("calls across to extension", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const expectedTelemetry = {
                 data: {
@@ -193,8 +193,8 @@ describe("toolsHost", () => {
 
     describe("openInEditor", () => {
         it("calls across to extension", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const expectedRequest = {
                 column: 500,
@@ -224,8 +224,8 @@ describe("toolsHost", () => {
 
     describe("onMessageFromChannel", () => {
         it("calls onResolvedUrlFromChannel on getUrl message", async () => {
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
             host.setResourceLoader(mockResourceLoader);
 
             const expectedArgs = { id: 0, content: "some content" };
@@ -239,19 +239,21 @@ describe("toolsHost", () => {
 
         it("calls onMessageFromChannel on websocket message", async () => {
             const mockToolsWS = {
-                instance: {
-                    onMessageFromChannel: jest.fn(),
+                ToolsWebSocket: {
+                    instance: {
+                        onMessageFromChannel: jest.fn(),
+                    },
                 },
             };
             jest.doMock("./toolsWebSocket", () => mockToolsWS);
 
-            const { default: toolsHost } = await import("./toolsHost");
-            const host = new toolsHost();
+            const th = await import("./toolsHost");
+            const host = new th.ToolsHost();
 
             const expectedArgs = { event: "message", message: "some websocket message" };
             host.onMessageFromChannel("websocket", JSON.stringify(expectedArgs));
 
-            expect(mockToolsWS.instance.onMessageFromChannel).toHaveBeenCalledWith(
+            expect(mockToolsWS.ToolsWebSocket.instance.onMessageFromChannel).toHaveBeenCalledWith(
                 expectedArgs.event,
                 expectedArgs.message,
             );
diff --git a/src/host/toolsResourceLoader.test.ts b/src/host/toolsResourceLoader.test.ts
index 6343fb0..c0d5dd5 100644
--- a/src/host/toolsResourceLoader.test.ts
+++ b/src/host/toolsResourceLoader.test.ts
@@ -26,8 +26,8 @@ describe("toolsResourceLoader", () => {
         it("overrides load resource promise correctly", async () => {
             const originalLoader = mockLoader.loadResourcePromise;
 
-            const { default: toolsResourceLoader } = await import("./toolsResourceLoader");
-            const resourceLoader = toolsResourceLoader.overrideResourceLoading(mockLoader);
+            const trl = await import("./toolsResourceLoader");
+            const resourceLoader = trl.ToolsResourceLoader.overrideResourceLoading(mockLoader);
 
             expect(resourceLoader).toBeDefined();
             expect(mockLoader.loadResourcePromise).not.toEqual(originalLoader);
@@ -36,8 +36,8 @@ describe("toolsResourceLoader", () => {
 
     describe("loadResource", () => {
         it("uses channel to request http url", async () => {
-            const { default: toolsResourceLoader } = await import("./toolsResourceLoader");
-            const resourceLoader = toolsResourceLoader.overrideResourceLoading(mockLoader);
+            const trl = await import("./toolsResourceLoader");
+            const resourceLoader = trl.ToolsResourceLoader.overrideResourceLoading(mockLoader);
 
             const expectedUrl = "http://file.url";
             const contentPromise = mockLoader.loadResourcePromise(expectedUrl);
@@ -62,8 +62,8 @@ describe("toolsResourceLoader", () => {
         });
 
         it("uses channel to request https url", async () => {
-            const { default: toolsResourceLoader } = await import("./toolsResourceLoader");
-            const resourceLoader = toolsResourceLoader.overrideResourceLoading(mockLoader);
+            const trl = await import("./toolsResourceLoader");
+            const resourceLoader = trl.ToolsResourceLoader.overrideResourceLoading(mockLoader);
 
             const expectedUrl = "https://file.url";
             const contentPromise = mockLoader.loadResourcePromise(expectedUrl);
@@ -90,8 +90,8 @@ describe("toolsResourceLoader", () => {
         it("uses real loader for packaged files", async () => {
             const originalLoader = mockLoader.loadResourcePromise;
 
-            const { default: toolsResourceLoader } = await import("./toolsResourceLoader");
-            const resourceLoader = toolsResourceLoader.overrideResourceLoading(mockLoader);
+            const trl = await import("./toolsResourceLoader");
+            const resourceLoader = trl.ToolsResourceLoader.overrideResourceLoading(mockLoader);
             expect(resourceLoader).toBeDefined();
 
             const expectedUrl = "elements.js";
diff --git a/src/host/toolsWebSocket.test.ts b/src/host/toolsWebSocket.test.ts
index 77bda91..281c508 100644
--- a/src/host/toolsWebSocket.test.ts
+++ b/src/host/toolsWebSocket.test.ts
@@ -18,18 +18,18 @@ describe("toolsWebSocket", () => {
 
     describe("constructor", () => {
         it("updates instance property", async () => {
-            const { default: toolsWebSocket } = await import("./toolsWebSocket");
+            const tws = await import("./toolsWebSocket");
 
-            const websocket = new toolsWebSocket("some url");
-            expect(toolsWebSocket.instance).toEqual(websocket);
+            const websocket = new tws.ToolsWebSocket("some url");
+            expect(tws.ToolsWebSocket.instance).toEqual(websocket);
 
-            const websocket2 = new toolsWebSocket("some other url");
-            expect(toolsWebSocket.instance).toEqual(websocket2);
+            const websocket2 = new tws.ToolsWebSocket("some other url");
+            expect(tws.ToolsWebSocket.instance).toEqual(websocket2);
         });
 
         it("sends ready event", async () => {
-            const { default: toolsWebSocket } = await import("./toolsWebSocket");
-            const websocket = new toolsWebSocket("some url");
+            const tws = await import("./toolsWebSocket");
+            const websocket = new tws.ToolsWebSocket("some url");
             expect(websocket).toBeDefined();
 
             expect(mockWebviewEvents.encodeMessageForChannel).toHaveBeenCalledWith(
@@ -46,8 +46,8 @@ describe("toolsWebSocket", () => {
 
     describe("send", () => {
         it("forwards messages correctly", async () => {
-            const { default: toolsWebSocket } = await import("./toolsWebSocket");
-            const websocket = new toolsWebSocket("some url");
+            const tws = await import("./toolsWebSocket");
+            const websocket = new tws.ToolsWebSocket("some url");
             mockWebviewEvents.encodeMessageForChannel.mockClear();
 
             const expectedMessage = "some message string";
@@ -67,8 +67,8 @@ describe("toolsWebSocket", () => {
 
     describe("onMessageFromChannel", () => {
         it("parses control messages and calls correct handlers", async () => {
-            const { default: toolsWebSocket } = await import("./toolsWebSocket");
-            const websocket = new toolsWebSocket("some url");
+            const tws = await import("./toolsWebSocket");
+            const websocket = new tws.ToolsWebSocket("some url");
 
             websocket.onerror = jest.fn();
             websocket.onMessageFromChannel("error");
@@ -84,8 +84,8 @@ describe("toolsWebSocket", () => {
         });
 
         it("forwards websocket messages to onmessage", async () => {
-            const { default: toolsWebSocket } = await import("./toolsWebSocket");
-            const websocket = new toolsWebSocket("some url");
+            const tws = await import("./toolsWebSocket");
+            const websocket = new tws.ToolsWebSocket("some url");
 
             websocket.onmessage = jest.fn();
 
@@ -99,8 +99,8 @@ describe("toolsWebSocket", () => {
         });
 
         it("ignores websocket messages with no message data", async () => {
-            const { default: toolsWebSocket } = await import("./toolsWebSocket");
-            const websocket = new toolsWebSocket("some url");
+            const tws = await import("./toolsWebSocket");
+            const websocket = new tws.ToolsWebSocket("some url");
 
             websocket.onmessage = jest.fn();
 
diff --git a/src/launchDebugProvider.test.ts b/src/launchDebugProvider.test.ts
index d3d5609..8e45392 100644
--- a/src/launchDebugProvider.test.ts
+++ b/src/launchDebugProvider.test.ts
@@ -2,7 +2,7 @@
 // Licensed under the MIT License.
 
 import TelemetryReporter from "vscode-extension-telemetry";
-import LaunchDebugProvider from "./launchDebugProvider";
+import { LaunchDebugProvider } from "./launchDebugProvider";
 import {
     createFakeExtensionContext,
     createFakeTelemetryReporter,
@@ -27,8 +27,8 @@ describe("launchDebugProvider", () => {
         jest.doMock("vscode", () => createFakeVSCode(), { virtual: true });
         jest.resetModules();
 
-        const { default: launchDebugProvider } = await import("./launchDebugProvider");
-        host = new launchDebugProvider(createFakeExtensionContext(), mockReporter, attach, launch);
+        const ldp = await import("./launchDebugProvider");
+        host = new ldp.LaunchDebugProvider(createFakeExtensionContext(), mockReporter, attach, launch);
     });
 
     describe("provideDebugConfigurations", () => {
diff --git a/src/utils.test.ts b/src/utils.test.ts
index 0da7358..7912ff8 100644
--- a/src/utils.test.ts
+++ b/src/utils.test.ts
@@ -384,7 +384,7 @@ describe("utils", () => {
         const mockReporter = {};
         beforeEach(async () => {
             jest.doMock("../package.json", () => ({}), { virtual: true });
-            jest.doMock("./debugTelemetryReporter", () => function debug() { return mockReporter; });
+            jest.doMock("./debugTelemetryReporter", () => ({DebugTelemetryReporter: jest.fn()}));
             jest.resetModules();
 
             utils = await import("./utils");