Skip to content

embed-resources needs to work with es6 modules #11860

@cscheid

Description

@cscheid

On main, embed-resources no longer works because of the change I made to start decomposing quarto.js.

With that said: I want a better organization for quarto.js, because it's getting out of hand. We also will need to put in more work on it to fix dark mode for 1.7. Using ES6 modules is the right move. The problem is that when embed-resources is true, quarto.js can't be used as is; we need to process the file.

The good news is that we already have esbuild, and so we should simply use it. Here's two possible avenues:

  • "static": use our quarto build-js step to create embed-resources-enabled versions of our dependencies, and then detect and include them at the time where we resolve our dependencies.
    • problem: this requires us to remember to type quarto build-js every time we change our dependencies, and it's hard to test robustly for.
  • "dynamic": detect embed-resources, and then call esbuild on all top-level javascript dependencies.
    • problem: this requires Quarto to know the difference between quarto.js and tabsets/tabsets.js; the former is a "top-level" dependency, the latter isn't. We want embed-resources to call esbuild on quarto.js, but not on tabsets/tabsets.js.
      • solution: a "top-level" dependency needs to come from a <script> tag; so we can analyze the HTML, find the javascript module imports, and call esbuild in front of it.

We should do the latter solution, because it will fix a number of other embed-resources issues we have. Consider the example below. Ideally, we would detect and embed everything that is statically reachable from main.html, but we currently don't do it. quarto.js just becomes an instance of this same problem now. But, because we're the ones causing it, we really do need to fix the problem.

An example that never worked

In case you try to run the experiment below and are surprised to find that it "runs", notice that it will only run as long as hello.js is in the same directory (which it will be if you have main.html in the same place as you rendered it). The problem is that Quarto should be embedding the import to hello.js, and it is not.

main.qmd

---
format:
  html:
    embed-resources: true
---

```{=html}
<script type="module" src="./main.js"></script>
```

## oh oh

main.js

import { hello } from "./module.js"

module.js

export const hello = 'world';
alert("We got here");

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinghtmlIssues with HTML and related web technology (html/css/scss/js)

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions