Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Create a new Specifier type for JavaScript module specifiers#3818

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
hansl wants to merge1 commit intoboa-dev:main
base:main
Choose a base branch
Loading
fromhansl:specifiers

Conversation

@hansl
Copy link
Contributor

This PR does not change any of the current API. I wanted to see if people preferred doing it as part of this PR (thus larger in scope), or doing a review of this new type, then as a follow up update the related APIs.

My thoughts after playing with modules;

  • There is friction between what is a Path, and what is a module specifier. To remove that friction and simplify the API surface, I suggest that all Path from Source, Module and their relative types be moved to using this new Specifier/OwnedSpecifier type.
  • Paths should only be used when working with the file system. That is, a Path is only necessary in a ModuleLoader's implementation, and should never be part of the interface. That way the API is platform independent, and concerns are separated between resolution/namespacing and actually pointing at files. Same goes for URLs (Path being technically a URL). These are implementation specific and should not be part of the API. Having easy conversions from one to the other would make it trivial anyway.
  • Source should have a Specifier, Scripts should take the specifier and make a copy of it, etc.
  • Traces will show up just fine in a single namespace, but we should avoid storing relative specifiers (relative to what). We should see absolute paths for modules, regardless of how they were imported, soimport './path' resolving to/some/path.js (see below), should show up in traces as/some/path.js. This would be part of the follow up PR.
  • There should be an invariant that two absolute specifiers should ALWAYS resolve to the same module. AFAICT, that is true of all JavaScript module implementation (can't remember if it's in the spec). Relative specifiers should be resolved to become absolute, then follow the same invariant.
  • I would suggest having aRevoledSpecifier or something which is guaranteed at creation to be absolute and resolved. It canDeref<Specifier> orDeref<OwnedSpecifier>. That way the type system will make sure you cannot create a module with a relative path (relative to what?!?). When creating a module, you need to pass a referrer or a resolved specifier.

Some extra curricular suggestions:

  • There should be some interaction between a resolver and a loader, but these two concerns should likely be separated. I'm not going to do that, but having something like aNodeModuleResolver that doesn't have to also be a loader would be good.
  • Loaders likely should have some awareness of what specifiers are available, and allow queries and (ideally) listing where possible. Query requires that the trait default implementation ofModuleLoader::get_module, and that this method be implemented correctly.
  • I didn't want to get into URLs just yet (or at all). This is not a use case I care about right now. But this new type would also help there, as resolving relative to an existing specifier is made trivial.

@codecov
Copy link

codecovbot commentedApr 17, 2024
edited
Loading

Codecov Report

Attention: Patch coverage is76.99531% with49 lines in your changes missing coverage. Please review.

Project coverage is 50.41%. Comparing base(6ddc2b4) to head(bf0eedc).
Report is 448 commits behind head on main.

Files with missing linesPatch %Lines
core/engine/src/module/specifier.rs76.99%49 Missing⚠️
Additional details and impacted files
@@            Coverage Diff             @@##             main    #3818      +/-   ##==========================================+ Coverage   47.24%   50.41%   +3.16%==========================================  Files         476      460      -16       Lines       46892    45179    -1713     ==========================================+ Hits        22154    22776     +622+ Misses      24738    22403    -2335

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report?Share it here.

🚀 New features to boost your workflow:
  • ❄️Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jedel1043
Copy link
Member

jedel1043 commentedApr 17, 2024
edited
Loading

I'm trying to think about the implications of always having absolute paths for modules and scripts. Right now, I can think of:

  • Users who don't want to use absolute paths on traces for security reasons.
  • Users who want to embed Boa in a system that doesn't have a filesystem (not possible now, WIP),
    but that want to expose some relative paths to the host project for debugging purposes.

Committing to absolute paths would be very bad for both use cases.

Maybe we can just change specifiers to store astr, then the loaders would be the ones to decide if they want to parse unix paths/windows paths/urls?

@hansl
Copy link
ContributorAuthor

hansl commentedApr 17, 2024
edited
Loading

Users who don't want to use absolute paths on traces for security reasons.

Absolute to the root of the (very much virtual) namespace, not their filesystems.Path and FileSystem is an implementation detail. The way to go fromSpecifier toPath is by having a base path, like we do inSimpleModuleLoader. Everywhere else in Boa itself we would never deal with those base paths (which is the part that's sensitive).

Users who want to embed Boa in a system that doesn't have a filesystem (not possible now, WIP), but that want to expose some relative paths to the host project for debugging purposes.

This would be done using theModuleLoader. The base would be the host project, joining specifiers with the base path when loading/resolving modules. The root of the namespace becomes the base of the host project. But that's all up to the host itself, Boa has no knowledge of these kind of details. Boa only cares about specifiers and modules.

Basically what I'm saying is:

Boa SHOULD NOT have as a concern WHERE the file is located or HOW to find it, but that there exists a map of uniqueSpecifier =>Module that can be resolved using aModuleLoader, and that each unique absoluteSpecifier resolves to one and only oneModule.

This is a very powerful statement, and would allow optimizations that are host independent, such as having a module cache outside of module loader, for example.

And to avoid further confusion, what I mean by "absoluteSpecifier" is not absolute in terms of filesystem (Boa should not be aware of filesystems or platform), but in an imaginary namespace that contains all modules handled by the host. Specifier can be seen as URIs in this context, and every module/source would have a Specifier that must be complete (not relative), and every such specifier must point to only one module.

@jedel1043
Copy link
Member

jedel1043 commentedApr 17, 2024
edited
Loading

What would be the overall changes toSource if we go with this? Do we need to removeSource::from_filepath and ask users to open the file manually + convert their paths toSpecifier beforehand?
EDIT: Also, can we offer some type of conversion fromPath toSpecifier?

@hansl
Copy link
ContributorAuthor

Source::from_filepath would likely take aSpecifier as an additional argument. There is nothing wrong with utility functions. We could also make it separate (aSourceExt trait for example) to keep engine clean, but I don't think that's necessary.

@hansl
Copy link
ContributorAuthor

Also, can we offer some type of conversion from Path to Specifier?

Could be inSpecifier itself. There's already afrom_path, all you'd need to do isSpecifier::from_path(path::strip_prefix(base))

@jedel1043
Copy link
Member

jedel1043 commentedApr 17, 2024
edited
Loading

This discussion is getting a bit too long for a PR, and I wanted to ask some more questions about the API. I'll open a thread in Matrix.
EDIT: Link to the discussionhttps://matrix.to/#/!hjtiFaaZzLlPqwfAms:matrix.org/$er1XOv9CQIzd2aT2rZfiFAue4zOWBRsDx71XfcOcBtU?via=matrix.org&via=mozilla.org

@jedel1043jedel1043 changed the titleCreate a new Speficier type for JavaScript module specifiersCreate a new Specifier type for JavaScript module specifiersApr 17, 2024
@hanslhansl marked this pull request as draftSeptember 9, 2024 01:09
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@jedel1043jedel1043jedel1043 left review comments

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

@hansl@jedel1043

[8]ページ先頭

©2009-2025 Movatter.jp