htmelt
Version:
Bundle your HTML assets with Esbuild and LightningCSS. Custom plugins, HMR platform, and more.
127 lines (125 loc) • 3.89 kB
JavaScript
import {
buildCSSFile
} from "./chunk-Q2H5B2YZ.mjs";
import "./chunk-SGZXFKQT.mjs";
// src/plugins/cssReload.mts
import {
fileToId,
idToFile,
idToUri,
md5Hex,
parseNamespace
} from "@htmelt/plugin";
import fs from "fs";
import svgToDataUri from "mini-svg-data-uri";
import path from "path";
var cssReloadPlugin = (config, flags) => {
const cssEntries = /* @__PURE__ */ new Map();
config.registerCssEntry = (id, code, loader = "css") => {
if (!cssEntries.has(id)) {
cssEntries.set(id, {
hash: code != null ? md5Hex(code) : "",
loader
});
}
};
return {
cssPlugins: [inlineSvgUrls(config)],
document({ styles }) {
const buildPrefix = "/" + config.build + "/";
styles.forEach((style) => {
const srcAttr = style.srcAttr.value;
if (srcAttr.startsWith(buildPrefix)) {
const devUrl = config.resolveDevUrl(srcAttr);
style.srcAttr.value = devUrl.href;
cssEntries.set(fileToId(style.srcPath), {
hash: "",
loader: "css"
});
}
});
},
hmr(clients) {
return {
accept: (file) => file.endsWith(".css"),
async update(files) {
const dirtyFiles = files.some((file) => !cssEntries.has(file)) ? Array.from(cssEntries.keys()) : files;
const updates = [];
await Promise.all(
Array.from(dirtyFiles, async (id, i) => {
let uri;
let outFile;
const file = idToFile(id);
const namespace = parseNamespace(id);
let alias;
if (namespace && /^@?[a-z0-9]/i.test(file)) {
alias = config.alias[file];
if (alias && typeof alias !== "string") {
outFile = alias;
}
} else if (path.isAbsolute(file)) {
console.log("[cssReload] reading virtual file", file);
outFile = config.virtualFiles[file];
}
if (outFile) {
uri = alias ? idToUri(id) : fileToId(config.getBuildPath(file));
} else if (path.isAbsolute(file) && fs.existsSync(file)) {
const result = await buildCSSFile(file, config, flags);
const cssText = Buffer.from(result.code).toString("utf8");
const entry = cssEntries.get(id);
const hash = md5Hex(cssText);
if (entry.hash !== hash) {
entry.hash = hash;
uri = fileToId(config.getBuildPath(file));
outFile = {
loader: "css",
current: { data: cssText }
};
}
} else {
cssEntries.delete(id);
}
if (uri && outFile && outFile.loader === "css") {
updates[i] = [uri];
console.log("[cssReload] updating virtual file", uri);
config.setVirtualFile(uri, outFile);
}
})
);
for (const update of updates) {
if (!update)
continue;
await Promise.all(
Array.from(
clients,
(client) => client.evaluateModule("./client/cssReload.mjs", update)
)
);
}
}
};
}
};
};
function inlineSvgUrls(config) {
return {
visitor: (importer) => ({
Url(node) {
if (!/^[./]/.test(node.url)) {
return;
}
if (node.url.endsWith(".svg")) {
const svgFile = config.resolve(node.url, importer);
const svgText = fs.readFileSync(svgFile, "utf8");
return {
url: svgToDataUri(svgText),
loc: node.loc
};
}
}
})
};
}
export {
cssReloadPlugin
};