Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ export class ComponentWriterMain {
import: false,
writeConfigFiles: !skipWriteConfigFiles,
dependenciesGraph: await this.workspace.scope.getDependenciesGraphByComponentIds(componentIds),
// Enable addMissingDeps to handle cases where env detectors aren't available on first install
// (e.g., when importing a component that uses a custom env with custom file extension
// detectors like .vue files). The env gets installed during the first pass, and then
// addMissingDeps will re-detect dependencies with the env now available.
addMissingDeps: true,
};
await this.installer.install(undefined, installOpts);
this.logger.debug('installPackagesGracefully, completed installing packages successfully');
Expand Down
34 changes: 34 additions & 0 deletions scopes/workspace/install/install.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ export class InstallMain {
linkNestedDepsInNM: !this.workspace.isLegacy && !hasRootComponents,
};
const { linkedRootDeps } = await this.calculateLinks(linkOpts);
// Capture envs that failed to load before install - they may become available after install
// and we'll need to re-detect dependencies for components using custom file extensions (e.g., .vue)
const envsFailedToLoadBeforeInstall = this.envs.getFailedToLoadEnvs();
// eslint-disable-next-line prefer-const
let { mergedRootPolicy, componentsAndManifests: current } = await this._getComponentsManifestsAndRootPolicy(
installer,
Expand Down Expand Up @@ -484,6 +487,37 @@ export class InstallMain {
// After pruning we need reload moved envs, as during the pruning the old location might be deleted
await this.reloadMovedEnvs();
}

// If addMissingDeps was requested and there were envs that failed to load before install,
// we need to re-check for missing dependencies now that envs may be available.
// This handles the case where a component uses a custom file extension (e.g., .vue) that requires
// an env detector that wasn't available during the first dependency detection pass.
if (options?.addMissingDeps && envsFailedToLoadBeforeInstall.length > 0) {
await this.workspace.clearCache();
const missingPackages = await this._getAllMissingPackages();
Copy link
Member

Choose a reason for hiding this comment

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

so it will install all missing dependencies, not only those that were not detected due to the lack of env in node_modules. Is that fine? Maybe we should just pick the missing deps of the imported components?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure. Honestly, I'm not even sure that this fix is in the right direction. It might be better to forget about this PR and fix the original issue regardless of this.

if (missingPackages.length > 0) {
this.logger.debug(
`found ${missingPackages.length} missing packages after envs became available: ${missingPackages.join(', ')}`
);
await this._addPackages(missingPackages, { skipUnavailable: options?.skipUnavailable });
// Run another install to install the newly discovered missing packages
const newManifests = await this._getComponentsManifests(installer, mergedRootPolicy, calcManifestsOpts);
await installer.installComponents(
this.workspace.path,
newManifests.manifests,
mergedRootPolicy,
newManifests.componentDirectoryMap,
{
linkedDependencies,
installTeambitBit: false,
forcedHarmonyVersion,
},
pmInstallOptions
);
current = newManifests;
}
}

// this is now commented out because we assume we don't need it anymore.
// even when the env was not loaded before and it is loaded now, it should be fine because the dependencies-data
// is only about the auto-detect-deps. there are two more steps: version-resolution and apply-overrides that
Expand Down