Skip to content

Implement maxNodeModuleJsDepth, noResolve #1189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

jakebailey
Copy link
Member

Fixes #931

This was tricky to deal with in a concurrent loader.

The gist of it is that we keep track of the current "JS file depth" as we recurse. If a subtask about to be enqueued is a JS file from node_modules, we skip it if the current depth of JS files is too high. If the depth is okay, we'll load it, then recurse. If we ever revisit the same file again, we check to see if the new depth is lower than the last time the file is checked, and if it is we'll recheck its subtasks at that new depth (potentially loading more files).

While here, I've simplified a few things; namely I remembered the trick to have a self-referencing generic method and implemented noResolve.

Sadly, there's now a mutex per file, but I can't think of a cleaner method. The only place where this would matter is when the same file is referenced multiple times, in which case we need to recheck it serially anyhow.

We don't seem to have any tests for maxNodeModuleJsDepth; I'll think about how to make some. I'm also not setting up maxNodeModuleJsDepth for the the editor. I'm not sure where that goes.

Copy link
Contributor

@Copilot 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 introduces depth-based controls (maxNodeModuleJsDepth) for loading JS files in node_modules and implements the noResolve option to skip adding resolved modules to the program. It refactors task-loading to track whether a file is loaded and if its depth should increase, simplifying concurrent loading logic.

  • Add loaded, shouldIncreaseDepth, and isLoaded methods to parse- and project-reference tasks
  • Introduce a generic fileLoaderWorker that tracks per-file mutexes and depth limits
  • Update fileloader.go to use a resolvedRef type, respect maxNodeModuleJsDepth, and honor noResolve

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
testdata/baselines/reference/.../moduleResolutionNoResolve.js.diff Removes outdated diff for noResolve baseline
testdata/baselines/reference/.../moduleResolutionNoResolve.js Updates the baseline output for noResolve
internal/compiler/projectreferenceparsetask.go Rename startload, add depth/no-resolve stubs
internal/compiler/program.go Remove unused depth-tracking fields in Program
internal/compiler/parsetask.go Refactor subtasks to use resolvedRef, track JS depth
internal/compiler/fileloadertask.go Generic worker with mutex per file, depth-first logic
internal/compiler/fileloader.go Wire up maxNodeModuleJsDepth, implement noResolve logic
Comments suppressed due to low confidence (2)

internal/compiler/fileloader.go:67

  • There are no tests covering the new maxNodeModuleJsDepth behavior; consider adding cases where the loader skips JS files beyond the depth limit.
var maxNodeModuleJsDepth int

internal/compiler/fileloader.go:386

  • The new noResolve flag path isn't exercised by existing tests; add tests to verify that setting noResolve prevents modules from being added.
shouldAddFile := resolvedModule.IsResolved() && optionsForFile.NoResolve.IsFalseOrUnknown()

@jakebailey jakebailey marked this pull request as draft June 15, 2025 04:12
Comment on lines +5 to +6
+index.js(10,12): error TS2749: 'Thing' refers to a value, but is being used as a type here. Did you mean 'typeof Thing'?
+index.js(17,16): error TS2749: 'Thing' refers to a value, but is being used as a type here. Did you mean 'typeof Thing'?
Copy link
Member Author

Choose a reason for hiding this comment

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

Expected, since @enum doesn't do anything anymore and so no type is declared.

-
-
-==== validator.ts (10 errors) ====
+index.js(4,11): error TS2580: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
Copy link
Member Author

Choose a reason for hiding this comment

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

mod1 looks like:

Object.defineProperty(exports, "thing", { value: 42, writable: true });
Object.defineProperty(exports, "readonlyProp", { value: "Smith", writable: false });
Object.defineProperty(exports, "rwAccessors", { get() { return 98122 }, set(_) { /*ignore*/ } });
Object.defineProperty(exports, "readonlyAccessor", { get() { return 21.75 } });
Object.defineProperty(exports, "setonlyAccessor", {
    /** @param {string} str */
    set(str) {
        this.rwAccessors = Number(str) 
    }
});

This is not being treated as a module for some reason? I don't think I did anything to affect this, probably another bug.

@jakebailey jakebailey marked this pull request as ready for review June 15, 2025 05:33
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.

Some dependency JS files appear to be erroneously typechecked
1 participant