feat: added initial sourcemapping attempt and use transform hook to parse and transform instead of load

This commit is contained in:
2023-11-25 22:44:31 +01:00
parent 980d33c48e
commit afd4a3c9ae
2 changed files with 39 additions and 16 deletions

View File

@@ -23,6 +23,9 @@ import type {
import {createFilter} from '@rollup/pluginutils';
// parse5 package is used for parsing HTML.
import {parse as parseHtml, serialize as serializeHtml, DefaultTreeAdapterMap} from "parse5";
// magic-string to transform code and keeping a sourcemap aligned
import MagicString from "magic-string";
// nodejs imports (io, path)
import path, { extname, dirname } from "node:path";
@@ -147,13 +150,19 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
}
}
},
load: { // TODO, not in the mood to fix this. Load-result is getting cached and that gives us issues. Seperate load/transform behavior and adapt to use magic string for transformations?
load: {
// Something to figure out: its counter intuitive that rollup expects the load-callback to already return JS. It implies we already do transformations and can't really use rollup to further transform any of it. (i.e handlebars > intermediate-html > html would not be possible?)
async handler(id: string) {
if(virtualSources.has(id)) return virtualSources.get(id);
if(!filter(id)) return;
if (virtualSources.has(id)) return virtualSources.get(id);
if (!filter(id)) return;
}
},
transform: {
async handler(...args){
const [code, id] = args;
if (!filter(id)) return;
// Load
// parse
const htmlModule = htmlModules.get(id);
if(htmlModule) {
const contents = await readFile(id, {encoding: "utf-8"});
@@ -162,7 +171,7 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
id,
}) : contents;
// Parse document and store it (TODO: check for watch mode, we should check if it needs reparsing or not)
// Parse document and store it
const document = htmlModule.document = parseHtml(htmlSrc);
// Figure out which references to load from this HTML by iterating all nodes (looking for src or href attributes)
@@ -244,13 +253,14 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
} while (nodeQueue.length > 0);
}
let html = serializeHtml(htmlModule.document).replaceAll(/`/g,'\\\`').replaceAll(/\$\{/g,'\\${');
let htmlJS = new MagicString(serializeHtml(htmlModule.document));// TODO this is still a leak of AST, we're taking parse5 edited result and then transforming sourcemaps, this will only work when no edits were made
htmlJS.replaceAll(/`/g,'\\\`').replaceAll(/\$\{/g,'\\${');
const moduleImports = [];
for(const htmlImport of htmlImports){
if(htmlImport.type === 'default') {
const assetId: string = `asset${moduleImports.length}`;
moduleImports.push(`import ${assetId} from "${htmlImport.id}";`);// TODO: This is just the easy & safe solution. Would prefer to have recognizable names, and reeuse when something is the exact same resource..
html = html.replace(htmlImport.placeholder, `\${${assetId}}`);// TODO: Should we be worried about windows absolute URLs here?
htmlJS = htmlJS.replace(htmlImport.placeholder, `\${${assetId}}`);// TODO: Should we be worried about windows absolute URLs here?
// }else if(htmlImport.type === 'entryChunk' && htmlImport.referenceId){
// html = html.replace(htmlImport.placeholder, `\${import.meta.ROLLUP_FILE_URL_${htmlImport.referenceId}\}`);
}else{
@@ -260,14 +270,24 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
}
// TODO when importing html from .js this will not do. (
const htmlJSModule = [
htmlJS.prepend([
...moduleImports,
``,
`export const html = \`${html}\`;`,
`export const html = \``
].join('\n')).append([
`\`;`,
`export default html;`,
].join('\n');
].join('\n'));
const map = htmlJS.generateMap({
source: id,
file: `${id}.map`,
includeContent: true,
hires: 'boundary'
});
return {
code: htmlJSModule,
code: htmlJS.toString(),
map: map.toString(),
};
}
}