Open armanbilge opened 2 years ago
Btw, I don't think this should be too hard to support. I think the key change here is adding support for ESModules, which means:
<script type="module" src="..."></script>
After enabling ES modules for (the non-mdoc part of) my project, the only change I had to make was (2).
I did a little investigation on this, as it's something I would like... from the outside, it doesn't look tooooo hard to get ESModules working.
In the first instance the module emitted by the linker, seems fine... as arman pointed out.
Let's assume we ran mdoc, on readme.md
. I think the readme.js
file emitted, should change to say.
<div id="mdoc-html-run1" data-mdoc-js></div>
<script type="module" src="readme.md.js"></script>
<script type="module" src="mdoc.js"></script>
instead of
<div id="mdoc-html-run1" data-mdoc-js></div>
<script type="text/javascript" src="readme.md.js" defer></script>
<script type="text/javascript" src="mdoc.js" defer></script>
So that change seems easy enough (famous last words). To keep the CLI working nicely however, I think it may also be necessary, to alter mdoc.js
. Currently, it looks like this.
import { mdoc_js_run0 } from "./readme.md.js";
(function (global) {
function findDivs() {
return Array.from(global.document.querySelectorAll("div[data-mdoc-js]"));
}
function loadAll(scope) {
findDivs().forEach(function (el) {
const idNum = el.getAttribute("id");
console.log(idNum);
var id = el.getAttribute("id").replace("-html-", "_js_");
// eval(id)(el);
mdoc_js_run0(el);
});s
}
loadAll(global);
})(window);
I would propose, to make it look like this;
(function (global) {
function findDivs() {
return Array.from(global.document.querySelectorAll("div[data-mdoc-js]"));
}
function loadAll(scope) {
findDivs().forEach(function (el) {
var id = el.getAttribute("id").replace("-html-", "_js_");
// https://stackoverflow.com/questions/2033711/how-can-i-attach-meta-data-to-a-dom-node
const moduleName = el.getAttribute("data-mdoc-module-name");
import(moduleName).then(function (module) {
//import("./readme.md.js").then(function (module) {
module[id](el);
});
});
}
loadAll(global);
})(window);
This would dynamically load the module, and then run the function it exports. i.e. preserve the existing live reload CLI functionality.
As things stand, it would require emitting an extra attribute on each of the div
s that mdoc adds.
<div id="mdoc-html-run0" data-mdoc-js></div>
would need to become
<div id="mdoc-html-run0" data-mdoc-js data-mdoc-module-name="readme.md.js" ></div>
I believe this would solve the ESModule problem, which I think is the key first step. It should be relatively simpler to then follow through on the SmallestModuleFor
and EsModuleImportMap pieces later...
Here's my initial experiment in this.
Scala.js 1.10.0 added
ModuleSplitStyle.SmallModulesFor
to enable fast, iterative development of Scala.js apps.https://www.scala-js.org/news/2022/04/04/announcing-scalajs-1.10.0/#new-module-split-style-smallmodulesforpackages
IIUC all mdocs are compiled under the
mdoc
package so I expect that would be the argument to use for this setting. Then,mdoc --watch
can provide a supercharged dev cycle.