tc39 / source-map

Source map specification, RFCs and new proposals.
https://tc39.es/source-map/
Other
119 stars 16 forks source link

Including dependency graph #14

Open connorjclark opened 2 years ago

connorjclark commented 2 years ago

Source programs have a module graph that is lost when compiling down to a bundle. If this information were persisted in the source map, developer tools could utilize it to inform things such as tree shaking (or lack thereof), optimized chunking, editor capabilities (showing in DevTools Sources panel "here are all the files that import this module"?), and possibly more use cases.

This would close a big gap between browser devtools knowledge and local bundler knowledge.

Some tools exist using module graph data. Currently, they consume the raw debug data outputted by various bundlers. Putting this into the source map specification would greatly reduce the complexity of making such tools.


Fleshed out example:

a.js

// two imports
import b from './b.js';
import c from './c.js';

b.js

// no imports
console.log(1);

c.js

// async will be transpiled down to something else, and that process will
// import from another module to use a utility fn `regeneratorRuntime`.
export async function run() {
  console.log(2);
}

regenerator.js

export function regeneratorRuntime() { ... }

output.js

console.log(1);
function regeneratorRuntime() { ... }
function run() {
  console.log(2);
}
regeneratorRuntime.wrap(... run ...);
{
  "files": [
    "./a.js",
    "./b.js",
    "./c.js",
    "regenerator.js"
  ],
  "dependencies": [
    [1, 2],
    [],
    [3]
  ]
}

This should also solve a problem of composing source maps as described here: https://github.com/samccone/bundle-buddy/issues/41

jkup commented 2 months ago

I'm curious what the appetite is on this from the browser side. We could for sure add this information to the source map, but it would likely greatly increase their size. If folks want this information added and would use it in the browser, we'd happily consider adding it!

jkup commented 2 months ago

It would be really cool if you could ctrl+click on import statements and the debugger would follow the mapping to the real source file.

paulirish commented 2 months ago

Bundles are often treated as fairly opaque built artifacts, but even when inspected with the treemap/sunburst/etc size-exploration tools, the user cannot determine the root cause of every individual file's inclusion.

Or, put another way…

The existing mapping data enables insight into what a bundle is composed of. But it can't illuminate why.


Here's a screenshot of how bundlebuddy makes use of dep graph data:

for force directed graph of chrome devtools frontend modules, as shown by BundleBuddy

(If you want to try it out: esbuild-meta.json)

FWIW, this data currently exists in the custom build artifacts of bundlers, mostly because of @samccone's personal engagement with bundler authors.

Beyond bundle analysis, @connorjclark's original list of usecases is worth a reread:

developer tools could utilize it to inform things such as tree shaking (or lack thereof), optimized chunking, editor capabilities (showing in DevTools Sources panel "here are all the files that import this module"?), and possibly more use cases.


it would likely greatly increase their size.

The draft idea from @connorjclark's post above is pretty size-efficient…

  "files": ["./a.js", "./b.js", "./c.js", "regenerator.js"],
  "dependencies": [[1, 2], [], [3]]

...but I wouldn't be surprised if an alternative representation is even smaller.

jkup commented 2 months ago

Hey folks! Sorry, we were going through issues yesterday as a group and I went too quickly over this one. I think this would make a great stage 0 proposal for TG4. Would either of you be interested in championing it, or is it more a feature request but someone else would have to own the proposal?

Thanks and sorry for the quick response above!

samccone commented 2 months ago

Love the idea of formalizing this information inside of the sourcemap - @paulirish is it worth us polling for interest across the ecosystem implementation owners - or should we commit to the stage 0 work and then use that as the communication approach?