Skip to content

appservice: Enforce lazy loading of @azure dependencies (and more)#2188

Draft
bwateratmsft wants to merge 11 commits intomainfrom
bmw/appservice/lazy
Draft

appservice: Enforce lazy loading of @azure dependencies (and more)#2188
bwateratmsft wants to merge 11 commits intomainfrom
bmw/appservice/lazy

Conversation

@bwateratmsft
Copy link
Contributor

@bwateratmsft bwateratmsft commented Feb 10, 2026

Also updates dependencies, clears some unnecessary type imports (which will help if we do the @azure-rest package), and so on.

TODO:

  • Verify GitHub package still works with lazy-loaded Octokit client
  • Verify WS import
  • Verify simple-git import

All three have ESM variants so I don't think there will be a problem, but worth verifying.

@bwateratmsft bwateratmsft requested a review from a team as a code owner February 10, 2026 19:45
@bwateratmsft bwateratmsft marked this pull request as draft February 10, 2026 20:13
@bwateratmsft

This comment was marked as resolved.

@bwateratmsft bwateratmsft changed the title appservice: Enforce lazy loading of @azure dependencies appservice: Enforce lazy loading of @azure dependencies (and more) Feb 10, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR focuses on reducing startup cost by enforcing lazy-loading of heavy dependencies (notably @azure/*) across the appservice package, alongside dependency upgrades and type-import cleanup.

Changes:

  • Convert many @azure/* and related imports to import type and/or switch to dynamic imports to avoid eager module loading.
  • Update appservice dependencies/devDependencies (Azure SDKs, p-retry, simple-git, ws, etc.) and adjust code for API/type changes.
  • Add an ESLint flat-config rule (lazyImportRuleConfig) to enforce lazy-loading patterns moving forward.

Reviewed changes

Copilot reviewed 41 out of 42 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
appservice/src/verifyNoRunFromPackageSetting.ts Removes eager type import; relies on inferred return type from client call.
appservice/src/utils/azureUtils.ts Changes AzExtPipelineResponse to a type-only import.
appservice/src/utils/azureClients.ts Adds stricter typing helpers for lazy-loaded Azure clients (incl. subscription client type).
appservice/src/tree/DeploymentsTreeItem.ts Removes eager ARM type imports; relies on inferred types.
appservice/src/tree/DeploymentTreeItem.ts Removes eager ARM type import; relies on inferred type.
appservice/src/swapSlot.ts Removes eager ARM client type import; relies on inferred type.
appservice/src/startStreamingLogs.ts Drops @azure/abort-controller import and uses global AbortController.
appservice/src/siteFiles.ts Updates to p-retry v7 APIs (AbortError import).
appservice/src/remoteDebug/startRemoteDebug.ts Converts Azure utils import to type-only.
appservice/src/github/connectToGitHub.ts Uses inline type import for GitHubContext.
appservice/src/extensionVariables.ts Removes GitHub extension variable registration; aligns extension vars interface with current UIExtensionVariables.
appservice/src/editScmType.ts Removes eager ARM type imports; relies on inferred types.
appservice/src/disconnectRepo.ts Removes eager ARM type import; relies on inferred type.
appservice/src/deploy/wizard/deployZip/DeployZipPushExecuteStep.ts Converts AzExtPipelineResponse to type-only import.
appservice/src/deploy/wizard/deployZip/DeployZipBaseExecuteStep.ts Converts AzExtPipelineResponse to type-only import.
appservice/src/deploy/wizard/deployZip/DeployFlexExecuteStep.ts Converts ARM Site import to type-only.
appservice/src/deploy/wizard/deployZip/DelayFirstWebAppDeployStep.ts Removes eager ARM plan type import; relies on inferred types.
appservice/src/deploy/wizard/createDeployWizard.ts Removes eager ARM type import; relies on inferred types.
appservice/src/deploy/wizard/PostDeployTaskExecuteStep.ts Converts ARM SiteConfig import to type-only.
appservice/src/deploy/wizard/DeployExecuteStepBase.ts Converts ARM imports to type-only; relies more on inference.
appservice/src/deploy/runWithZipStream.ts Converts AzExtPipelineResponse import to type-only.
appservice/src/deploy/localGitDeploy.ts Switches simple-git to dynamic import to support lazy-loading.
appservice/src/deploy/deployToStorageAccount.ts Switches @azure/storage-blob to dynamic import and removes eager SDK imports.
appservice/src/deploy/deploy.ts Removes eager ARM type import; relies on inferred promise type.
appservice/src/deploy/IDeployContext.ts Converts ARM AppServicePlan import to type-only.
appservice/src/createSlot.ts Removes eager ARM client/type imports; relies on inferred types and shared helpers.
appservice/src/createAppService/setLocationsTask.ts Removes explicit type in map callback; relies on inference.
appservice/src/createAppService/getAppInsightsSupportedLocation.ts Removes eager ARM/core-client type imports; relies on inference.
appservice/src/createAppService/SiteNameStep.ts Removes some explicit ARM types; relies on inference for ARM responses.
appservice/src/createAppService/IAppServiceWizardContext.ts Converts azureutils wizard context imports to type-only.
appservice/src/createAppService/AppServicePlanSkuStep.ts Removes unused ARM type import; relies on inference.
appservice/src/createAppService/AppServicePlanRedundancyStep.ts Converts imports to type-only.
appservice/src/createAppService/AppServicePlanListStep.ts Removes explicit ARM client type usage; relies on inference.
appservice/src/createAppService/AppServicePlanCreateStep.ts Removes explicit ARM client typing; relies on inference.
appservice/src/createAppService/AppInsightsNameStep.ts Removes explicit ARM type annotation; relies on inference.
appservice/src/createAppService/AppInsightsListStep.ts Removes explicit AI client type annotation; relies on inference.
appservice/src/createAppService/AppInsightsCreateStep.ts Removes explicit AI/RG type annotations; relies on inference.
appservice/src/TunnelProxy.ts Lazily imports ws at runtime; keeps only type import at top-level.
appservice/src/SiteClient.ts Removes explicit ServiceClient typing; relies on inference from createGenericClient.
appservice/package.json Bumps version and updates runtime/dev dependencies to newer releases.
appservice/eslint.config.mjs Adds lazy-import enforcement via lazyImportRuleConfig in flat ESLint config.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

};

export async function localGitDeploy(site: ParsedSite, options: LocalGitOptions, context: IActionContext): Promise<void> {
const { simpleGit } = await import('simple-git');
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simple-git was previously consumed via a default import, but this change destructures simpleGit from the dynamic import. For CommonJS/default-export interop, await import('simple-git') typically exposes the function on the module’s default export, so simpleGit may be undefined at runtime (especially in the CJS build). Update the lazy import to read the default export (or otherwise handle both default/named export shapes) before calling it.

Suggested change
const { simpleGit } = await import('simple-git');
const simpleGitModule = await import('simple-git');
const simpleGit = (simpleGitModule as any).default ?? (simpleGitModule as any).simpleGit ?? simpleGitModule;

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good look.

};

export async function localGitDeploy(site: ParsedSite, options: LocalGitOptions, context: IActionContext): Promise<void> {
const { simpleGit } = await import('simple-git');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good look.

}

private async setupTunnelServer(bearerToken: string, token: CancellationToken): Promise<void> {
const ws = await import('ws');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check this import too.

import { AzExtPipelineResponse, createGenericClient } from '@microsoft/vscode-azext-azureutils';
import { IActionContext, IParsedError, parseError } from '@microsoft/vscode-azext-utils';
import retry from 'p-retry';
import { AbortError, default as retry } from 'p-retry';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be OK since this isn't an await import but verify.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant