GithubHelp home page GithubHelp logo

Comments (4)

hiroshige-g avatar hiroshige-g commented on August 18, 2024 1

IIUC, "to which package the module script belongs" can be ambiguous (and thus resolution is done based on response URL scopes instead of package scopes). For example,

{
  "path_prefix": "/node_modules",
  "packages": {
    "a": {"path": "a", "main": "index.js", "packages": { "c": {"path": "dep-a", "main": "index.js" }},
    "b": {"path": "a", "main": "index.js", "packages": { "c": {"path": "dep-b", "main": "index.js" }}
  }
}

In this case, scripts imported as

  • import "a";
  • import "b";
  • import "/node_modules/a/index.js";

all point to a single entry in the module map with key = https://example.com/node_modules/a/index.js, and if it contains import "c";, we can't tell whether it should be resolved with dep-a, dep-b, or otherwise.

from import-maps.

domenic avatar domenic commented on August 18, 2024

The second one seems to contain redundant information compared to the first; perhaps I am missing something?

from import-maps.

justinfagnani avatar justinfagnani commented on August 18, 2024

I suspect that @zkat meant to remove the separate "scopes" stanza at the end of the second example which would remove the redundancy.

One reason to separate packages and scopes is that scopes can apply to more than one package.

If you're in a purely npm-driven local installation, there might be a strong correlation between a package and a scope, but consider a CDN use case where a subset of packages are served from the CDN, and you want their dependencies to come from the CDN, even if they use some package names that are installed locally as well:

{
  "packages": {
    "a": { "path": "https://js.cdn/a", "main": "index.js" },
    "b": { "path": "https://js.cdn/b", "main": "index.js" },
    "c": { "path": "node_modules/c", "main": "index.js" },
  },
  "scopes": {
    "https://js.cdn/": {
      "c": { "path": "https://js.cdn/c", "main": "index.js" },
    }
  }
}

c will resolve to the CDN when imported from a package on the CDN, or from node_modules otherwise.

Then, I think there are likely some optimization opportunities available by separating packages and scopes. In some cases with npm you can get a lot of duplication if you depend on incompatible versions of a library and the versions needed aren't correlated nicely with the package tree. ie, you get one version at the top-level, and another version at several other places in the tree. By separating packages and scopes, you can move around the packages so that the many packages dependant on the duplicated version fall under the same scope. I don't think this will work in all cases, especially with multiple version conflicts, but I don't think it can be easily done if packages are the scopes.

Another potential reason is the ease of lookup with this structure, though this claim needs implementor verification, and I can image several ways do do this...

To resolve a name we need to first recurse down the scope tree to find the applicable scope, then recurse back up to find the nearest package name mapping. By having the scope tree keyed by the scope paths, it's very easy to recurse downward without reading any of the package declarations - they can be read lazily only when needed for an resolution.

If scope paths are associated with packages, but packages are keyed by name, then you need to iterate over every package to get it's path in order to recurse down the scope tree.

Of course the whole file can be pre-processed to build up fast lookup tables, but I suspect there's a balance where you don't want to do too much preprocessing before you can start resolving package names. Maybe @hiroshige-g or @nyaxt can speak to that.

And finally, we wanted to try to use generic JSON validation to enforce some of the constraints on the mapping. In this format I tried to make things that need to be unique keys in JSON object to force them to be unique. A referrer URL needs to unambiguously map to a scope, so scope paths as keys helps.

Admittedly it's not quite enough with nesting, because you can generate ambiguous scope paths when concatenating parent and child paths, ie: a + b/c and a/b + c both have a path of a/b/c. So maybe this isn't a strong justification.

from import-maps.

zkat avatar zkat commented on August 18, 2024

Thanks! This does clarify it a lot! I have no further questions. :)

from import-maps.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.