htmelt
Version:
Bundle your HTML assets with Esbuild and LightningCSS. Custom plugins, HMR platform, and more.
111 lines (108 loc) • 3.04 kB
JavaScript
import {
createDir
} from "./chunk-SGZXFKQT.mjs";
// src/css.mts
import {
fileToId,
findElements,
getAttribute,
isRelativePath
} from "@htmelt/plugin";
import * as fs from "fs";
import { gray, red, yellow } from "kleur/colors";
import * as lightningCss from "lightningcss";
import path from "path";
async function buildCSSFile(file, config, flags = {}) {
const importer = new URL("file://" + path.resolve(file));
const visitors = config.plugins.map(({ cssPlugins }) => {
const visitors2 = [];
cssPlugins?.forEach((cssPlugin) => {
const visitor = cssPlugin.visitor(importer);
if (visitor) {
visitors2.push(visitor);
}
});
return visitors2;
}).flat();
if (!config.virtualFiles[file]) {
console.log(yellow("\u2301"), fileToId(file));
}
const bundle = await lightningCss.bundleAsync({
minify: flags.minify,
sourceMap: config.mode == "development",
errorRecovery: true,
visitor: visitors.length ? lightningCss.composeVisitors(visitors) : void 0,
resolver: {
resolve(specifier, originatingFile) {
if (/^\.\.?(\/|$)/.test(specifier)) {
return path.resolve(path.dirname(originatingFile), specifier);
}
return path.resolve("node_modules", specifier);
}
},
...config.lightningCss,
filename: file
});
if (bundle.warnings.length) {
console.warn("");
bundle.warnings.forEach((w) => {
console.warn(red(w.type), w.message);
console.warn(
" ",
gray(
fileToId(w.loc.filename).slice(1) + ":" + w.loc.line + ":" + w.loc.column
)
);
});
console.warn("");
}
return {
...bundle,
outFile: config.getBuildPath(file, {
content: flags.watch ? void 0 : Buffer.from(bundle.code)
})
};
}
function findRelativeStyles(document, file, config) {
const results = [];
for (const styleNode of findStyleSheets(document)) {
const srcAttr = styleNode.attrs.find((a) => a.name === "href");
if (srcAttr && isRelativePath(srcAttr.value)) {
const srcPath = path.join(path.dirname(file), srcAttr.value);
results.push({
node: styleNode,
srcAttr,
srcPath,
outPath: config.getBuildPath(srcPath)
});
}
}
return results;
}
async function buildRelativeStyles(styles, config, flags) {
await Promise.all(
styles.map(
(style) => buildCSSFile(style.srcPath, config, flags).then((result) => {
style.outPath = result.outFile;
createDir(result.outFile);
fs.writeFileSync(result.outFile, result.code);
if (result.map) {
fs.writeFileSync(result.outFile + ".map", result.map);
}
}).catch((e) => {
console.error('Failed to compile "%s":', fileToId(style.srcPath), e);
})
)
);
}
function findStyleSheets(rootNode) {
return findElements(
rootNode,
(e) => e.tagName == "link" && getAttribute(e, "rel") == "stylesheet"
);
}
export {
buildCSSFile,
findRelativeStyles,
buildRelativeStyles
};