Skip to content
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

specifiers inversion? #270

Closed
devingfx opened this issue Apr 23, 2023 · 6 comments
Closed

specifiers inversion? #270

devingfx opened this issue Apr 23, 2023 · 6 comments

Comments

@devingfx
Copy link

devingfx commented Apr 23, 2023

Hi!

I may be wrong, but it looks like specifier values are inverted between Dependency and Range ?

{
    "kind": "esm",
    "dependencies": [
        {
    ->      "specifier": "./file2.js",
            "code": {
    ->          "specifier": "file:///home/user/dev/project/file2.js",
                "span": {
                    "start": {},
                    "end": {}
                }
            }
        }
    ],
    "mediaType": "JavaScript",
    "specifier": "file:///home/user/dev/project/file.js"
}

I looks more logical to me to have an absolute URL specifier for a dependency as it's the same format as ModuleJson.specifier and the Range being the string extracted from code... Using dependency.specifier to reference it and dependency.code.specifer to parse code...

So this exemple should be :

{
    "kind": "esm",
    "dependencies": [
        {
            "specifier": "file:///home/user/dev/project/file2.js",
            "code": {
                "specifier": "./file2.js",
                "span": {
                    "start": {},
                    "end": {}
                }
            }
        }
    ],
    "mediaType": "JavaScript",
    "specifier": "file:///home/user/dev/project/file.js"
}
@nayeemrmn
Copy link
Collaborator

The current structure is intentional, though with lots of room for improvement. The 'short' specifier is what dependencies are keyed by so it goes at the top level. The value in code is the resolved specifier.

The whole thing would be made a lot more sound by #247, or feedback there would be appreciated.

@devingfx
Copy link
Author

I has seen the #247 but this issue here is not about restructuring the whole output that may be a bit complicated for dependent tools...

The question here is just about one case of value inversion that looks not correct (one issue, not a feature request)...

The 'short' specifier is what dependencies are keyed by so it goes at the top level.

Yes but indeed the "key" here is not the same format as the "key" for root modules (aka Module.specifier.

The value in code is the resolved specifier.

So it sould be the "key" that identifies a Dependency not nested in the parse result, that reprensent what the actual code is...

It looks wrong!

@nayeemrmn
Copy link
Collaborator

Yes but indeed the "key" here is not the same format as the "key" for root modules (aka Module.specifier.

The value in code is the resolved specifier.

So it sould be the "key" that identifies a Dependency not nested in the parse result, that reprensent what the actual code is...

It's not technically impossible to instead key dependencies by the resolved specifier and maybe both approaches are valid, but keying by the relative specifier happens to be much more convenient when validating against resolution errors. It's also more true to the ES modules spec which operates on (referrer, specifierString) pairs for identifying dependencies, whereas absolute specifiers are a host-defined way of identifying module slots.

Anyway #247 would go far to address the wrong look since it puts them both at the top-level with better names. Note that swapping these two fields would also be dangerous for dependents.

@devingfx
Copy link
Author

[...] whereas absolute specifiers are a host-defined way of identifying module slots.

So why ModuleJson.specifier is the resolved one?

It's not technically impossible to instead key dependencies by the resolved specifier

If I want to get the ModuleJson corresponding to a dependency, I should rely on what is already resolved:

graph.modules.find( m=> m.specifier == dependency.specifier )   // wont work
// aka find by id<specifier>

it's way more convenient to write than:

graph.modules.find( m=> m.specifier == resolve( dirname(m.specifier), dependency.specifier ) ) 
// or whatever the resolution mecanism, default or custom, you re-do what's already done once by createGraph ...

To make it work right now with this json output, I sould use dependency.code.specifier :

graph.modules.find( m=> m.specifier == dependency.code.specifier )

... what sounds wrong, I'm not actualy searching by "what's written in code" , but by "what's resolved for me already to be a global identifier"!

@nayeemrmn
Copy link
Collaborator

If I want to get the ModuleJson corresponding to a dependency, I should rely on what is already resolved:

graph.modules.find( m=> m.specifier == dependency.specifier )   // wont work
// aka find by id<specifier>

Great, #247 would make that work. I agree that dependency.code.specifier is confusing and tedious to write compared to dependency.specifier.

@dsherret
Copy link
Member

It's also now possible for the code and types specifier to be different. For example, a specifier like ./file2.js may resolve to ./file2.js for the code result and ./file2.d.ts for the types.

@dsherret dsherret closed this as not planned Won't fix, can't repro, duplicate, stale Oct 22, 2023
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

No branches or pull requests

3 participants