Closed sidwebworks closed 2 years ago
Update: I have managed to get Monaco detect external types libs, and created a custom Web worker to fetch types in the background. however I haven't yet tried to integrate it with the Esbuild fetch plugin. I think I will output a json object of all the top level imported modules out of my result and create a dependency file
UPDATE: Esbuild actually gives u an metafile output which I used to create a list of all the top level imports that file has.
const result = await build({
entryPoints: ["index.js"],
bundle: true,
write: false,
metafile: true,
legalComments: "none",
plugins: [unpkgPathPlugin(), fetchPlugin(rawCode, lang)],
define: {
"process.env.NODE_ENV": `"production"`,
global: "window",
},
});
const imports = result.metafile?.inputs["a:index.js"].imports
.map((el) => el.path.replace("a:https://unpkg.com/", ""))
.filter((e) => !e.includes("/"));
Combining it with a types web worker and a setting up a listener makes the intellisense work properly.
const loadTypes = (types) => {
const disposables: any = [];
const monaco = window && window.monaco;
const dependencies = types.map((e) => ({ name: e, version: "@latest" })) || [];
if (!typesWorker) {
typesWorker = new Worker(
new URL("../../workers/fetch-types.worker.js", import.meta.url)
);
}
dependencies.forEach((dep) => {
typesWorker.postMessage({
name: dep.name,
version: dep.version,
});
});
typesWorker.addEventListener("message", (event) => {
// name,
// version,
// typings: result,
const key = `node_modules/${event.data.name}/index.d.ts`;
const source = event.data.typings[key];
// const path = `${MONACO_LIB_PREFIX}${event.data.name}`;
const libUri = `file:///node_modules/@types/${event.data.name}/index.d.ts`;
disposables.push(
monaco.languages.typescript.javascriptDefaults.addExtraLib(source, libUri)
);
disposables.push(
monaco.languages.typescript.typescriptDefaults.addExtraLib(source, libUri)
);
// When resolving definitions and references, the editor will try to use created models.
// Creating a model for the library allows "peek definition/references" commands to work with the library.
});
return {
dispose() {
disposables.forEach((d) => d.dispose());
if (typesWorker) {
typesWorker.terminate();
}
},
};
};
Although there are a lot of spots for improvement, Like this initial implementation doesn't cache the types, so that's a TODO.
Need to figure out a way to integrate the ESBUILD plugins to export some form of dependency chart so that can be used to fetch typing externally and then fed into Monaco's TSC options.