chore: documentation

This commit is contained in:
Miel Truyen 2023-11-25 20:23:13 +01:00
parent 5c1e528304
commit 980d33c48e
4 changed files with 43 additions and 6 deletions

View File

@ -1,4 +1,4 @@
import path, { extname } from "node:path";
import type { import type {
Plugin, Plugin,
@ -19,17 +19,21 @@ import type {
LoadReference, BodyReference, AttributeReference, LoadFunction LoadReference, BodyReference, AttributeReference, LoadFunction
} from '../types/index.d.ts'; } from '../types/index.d.ts';
// createFilter function is a utility that constructs a filter function from include/exclude patterns.
import {createFilter} from '@rollup/pluginutils'; import {createFilter} from '@rollup/pluginutils';
// parse5 package is used for parsing HTML.
import {parse as parseHtml, serialize as serializeHtml, DefaultTreeAdapterMap} from "parse5"; import {parse as parseHtml, serialize as serializeHtml, DefaultTreeAdapterMap} from "parse5";
import {readFile} from "node:fs/promises"
// nodejs imports (io, path)
import path, { extname, dirname } from "node:path";
import {readFile} from "node:fs/promises"
import posix from "node:path/posix";
import crypto from "node:crypto";
// utilities
import {makeLoader, makeInlineId} from "./loader.js"; import {makeLoader, makeInlineId} from "./loader.js";
import {HtmlImport, HtmlModule} from "./html-module.js"; import {HtmlImport, HtmlModule} from "./html-module.js";
import {dirname} from "node:path";
import posix from "node:path/posix";
import crypto from "node:crypto";
const defaults: RollupHtmlOptions = { const defaults: RollupHtmlOptions = {
transform: (source: string)=>source,// NO-OP transform: (source: string)=>source,// NO-OP
@ -44,6 +48,12 @@ const defaults: RollupHtmlOptions = {
const modulePrefix = `// <html-module>`; const modulePrefix = `// <html-module>`;
const moduleSuffix = `// </html-module>`; const moduleSuffix = `// </html-module>`;
/**
* Creates a Rollup plugin that transforms HTML files.
*
* @param {RollupHtmlOptions} opts - The options for the plugin.
* @returns {Plugin} - The Rollup plugin.
*/
export default function html(opts: RollupHtmlOptions = {}): Plugin { export default function html(opts: RollupHtmlOptions = {}): Plugin {
const { const {
publicPath, publicPath,
@ -70,14 +80,35 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
let entryNames = new Map<string,string>(); let entryNames = new Map<string,string>();
const pluginName = 'html2'; const pluginName = 'html2';
/**
* Short summary:
* Intercepts the loading of the html files and parses it with parse5.
* The parsed result is iterated to check for external references that need to be including in the rollup build (via for example @rollup/plugin-url).
* To satisfy rollup a JS version of the html file is returned, optionally including a few imports left for rollup to resolve
* When the result is generated the rollup result for the html file and any of its inlined assets are stripped from the output.
* and replaced with the html file.
*
* Caveats:
* - to get the resulting html content file we're parsing the evaluating the result JS module and take its default export
* [warn] other plugins such as CJS transformer and hot-reload can severely screw this up.
* - sourcemaps won't work yet (to add support we'd need to rewrite using magic-string?)
* - to fix the naming of resulting html files, and behave properly when files are entryPoints or not... we're fighting rollup alot
*
*
* Rework by testing a stripped down version with JS imports?
* - the logic in load should be moved to a transform, properly use rollups ability to specify the plugin should run 'pre' other hooks and see if that allows us to intercept before a commonjs or some other tool horribly transpiles our code
* - we might need to know which output is being used to properly extract the html back from the result? (in case of not being included in a JS file)
*/
return { return {
name: pluginName,// TODO: Need a better name, original plugin was just named `html` and might still make sense to use in conjunction with this one name: pluginName,// TODO: Need a better name, original plugin was just named `html` and might still make sense to use in conjunction with this one
// Track html entrypoints
buildStart(options){ buildStart(options){
entryNames = new Map(Object.entries(typeof(options.input)==='object'?options.input:{[options.input]:[options.input]}) entryNames = new Map(Object.entries(typeof(options.input)==='object'?options.input:{[options.input]:[options.input]})
.map(([k,v])=>[v,k]) .map(([k,v])=>[v,k])
); );
}, },
resolveId: { resolveId: {
async handler(specifier: string, async handler(specifier: string,
importer: string | undefined, importer: string | undefined,

View File

@ -46,6 +46,12 @@ export function makeInlineId(sourceId: string, node: DefaultTreeAdapterMap['chil
return [sourceId, [makeHtmlPath(node), 'js'].join('.')].join('.'); return [sourceId, [makeHtmlPath(node), 'js'].join('.')].join('.');
} }
/**
* Creates a loader function that maps node types and attributes to load operations.
*
* @param mappings - An array of NodeMapping objects specifying how to map and load different nodes.
* @returns A LoadNodeCallback function that can be used to load nodes based on the mappings.
*/
export function makeLoader(mappings: NodeMapping[] = defaultMapping){ export function makeLoader(mappings: NodeMapping[] = defaultMapping){
const fn : LoadNodeCallback = async function ({node, sourceId}, load){ const fn : LoadNodeCallback = async function ({node, sourceId}, load){
for(const mapping of mappings){ for(const mapping of mappings){