WICG / import-maps

How to control the behavior of JavaScript imports
https://html.spec.whatwg.org/multipage/webappapis.html#import-maps
Other
2.7k stars 72 forks source link

Considering the uses of arbitrary scope depth #51

Closed guybedford closed 6 years ago

guybedford commented 6 years ago

I understand nested scopes are there to support nested node_modules, but it is possible to supported nested node_modules fine with a single-level scope with rewriting.

For example:

{
  "path_prefix": "/node_modules",
  "packages": {
    "html-to-text": { "main": "index.js" },
  },
  "scopes": {
    "html-to-text": {
      "path_prefix": "node_modules",
      "packages": {
        "lodash": { "path": "lodash-es", "main": "lodash.js" }
      },
      "scopes": {
        "lodash": {
          "path_prefix": "node_modules",
          "packages": {
            "lodash-dep": { "main": "index.js" }
          }
        }
      }
    }
  }
}

can be rewritten:

{
  "path_prefix": "/node_modules",
  "packages": {
    "html-to-text": { "main": "index.js" },
  },
  "scopes": {
    "html-to-text": {
      "path_prefix": "node_modules",
      "packages": {
        "lodash": { "path": "lodash-es", "main": "lodash.js" }
      },
     "html-to-text/node_modules/lodash": {
       "path_prefix": "node_modules",
       "packages": {
          "lodash-dep": { "main": "index.js" }
        }
     }
  }
}

The main feature that seems to be lost is the ability to "copy and paste" sections of the scope map around arbitrarily, but considering these cases are all machine-generated do we really need to support such a complex feature for only this benefit?

There is some brevity provided, but I find myself I can read a flat JSON data structure much more easily than a nested one as well.

domenic commented 6 years ago

Hmm. I find that the current design is actually more simple than a flat version, not more complex, because it means we have the same reused schema at every level of the tree. Whereas what you propose would be that the top-level map can contain a scopes key, but nothing else can, right?

There might be a way of simplifying while still flattening, if we think flattening is important. E.g.

{
  "": {
    "path_prefix": "/node_modules",
    "packages": {
      "html-to-text": { "main": "index.js" },
    }
  },
  "html-to-text": {
    "path_prefix": "node_modules",
    "packages": {
      "lodash": { "path": "lodash-es", "main": "lodash.js" }
    },
  },
  "html-to-text/node_modules/lodash": {
   "path_prefix": "node_modules",
   "packages": {
      "lodash-dep": { "main": "index.js" }
    }
  }
}

But I am not sure this is actually much simpler than the current recursive definition...

guybedford commented 6 years ago

I was just implementing this in JS recently, and prefer to use a dictionary lookup for the scope matching over array recursion (as mentioned in https://github.com/domenic/package-name-maps/issues/39), so would effectively be flattening in the preprocess step anyway.

Now this certainly doesn't affect anything algorithmic, as the package map can be converted into a suitable data structure when first passed for fast resolution this way.

Perhaps it is worth asking - what is easiest to spec? and what is easiest to explain?

domenic commented 6 years ago

Is there any way to get the simplicity of this idea without making "basic" package name maps bafflingly opauqe? By which I mean something like

{
  "": {
    "lodash": "/node_modules/lodash-es/lodash.js",
    "moment": "/node_modules/moment/src/moment.js"
  }
}

with its bizarre empty string key at top level.

guybedford commented 6 years ago

So I'm not saying scopes should be removed entirely at all, just that they could be flattened -

{
  "packages": {
    "lodash": "/node_modules/lodash-es/lodash.js"
  },
  "scopes": {
    "/node_modules/lodash-es": {
      "moment": "node_modules/moment/src/moment.js"
    }
  }
}
domenic commented 6 years ago

The new format uses basically what @guybedford wrote in his last comment. Yay!