astro
Version:
Astro is a modern site builder with web best practices, performance, and DX front-of-mind.
96 lines (95 loc) • 3.37 kB
JavaScript
import { fileURLToPath } from "node:url";
import { preprocessStyles, transform } from "@astrojs/compiler-rs";
import { AggregateError, CompilerError } from "../errors/errors.js";
import { AstroErrorData } from "../errors/index.js";
import { normalizePath, resolvePath } from "../viteUtils.js";
import { createStylePreprocessor } from "./style.js";
export async function compile({ astroConfig, viteConfig, toolbarEnabled, filename, source, inlineComponentAssets }) {
const cssPartialCompileResults = [];
const cssTransformErrors = [];
let transformResult;
try {
const preprocessedStyles = await preprocessStyles(source, createStylePreprocessor({
filename,
viteConfig,
astroConfig,
cssPartialCompileResults,
cssTransformErrors
}));
const transformOptions = {
compact: astroConfig.compressHTML,
filename,
inlineComponentAssets,
normalizedFilename: normalizeFilename(filename, astroConfig.root),
sourcemap: "both",
internalURL: "astro/compiler-runtime",
// TODO: remove in Astro v8
astroGlobalArgs: JSON.stringify(astroConfig.site),
scopedStyleStrategy: astroConfig.scopedStyleStrategy,
resultScopedSlot: true,
transitionsAnimationURL: "astro/components/viewtransitions.css",
// Source annotations only serve the dev toolbar. Vitest also runs Vite in `serve`,
// so skip them in `test` mode to keep rendered markup (e.g. from the Container API)
// free of machine-specific paths. See https://github.com/withastro/astro/issues/18162
annotateSourceFile: viteConfig.command === "serve" && viteConfig.mode !== "test" && astroConfig.devToolbar && astroConfig.devToolbar.enabled && toolbarEnabled,
preprocessedStyles,
resolvePath(specifier) {
return resolvePath(specifier, filename);
}
};
transformResult = transform(source, transformOptions);
} catch (err) {
// The compiler should be able to handle errors by itself, however
// for the rare cases where it can't let's directly throw here with as much info as possible
throw new CompilerError({
...AstroErrorData.UnknownCompilerError,
message: err.message ?? "Unknown compiler error",
stack: err.stack,
location: { file: filename }
});
}
handleCompileResultErrors(filename, transformResult, cssTransformErrors);
return {
...transformResult,
css: transformResult.css.map((code, i) => ({
...cssPartialCompileResults[i],
code
}))
};
}
function handleCompileResultErrors(filename, result, cssTransformErrors) {
const compilerError = result.diagnostics.find((diag) => diag.severity === "error");
if (compilerError) {
throw new CompilerError({
name: "CompilerError",
message: compilerError.text,
location: {
line: compilerError.labels[0].line,
column: compilerError.labels[0].column,
file: filename
},
hint: compilerError.hint
});
}
switch (cssTransformErrors.length) {
case 0: break;
case 1: {
throw cssTransformErrors[0];
}
default: {
throw new AggregateError({
...cssTransformErrors[0],
errors: cssTransformErrors
});
}
}
}
function normalizeFilename(filename, root) {
const normalizedFilename = normalizePath(filename);
const normalizedRoot = normalizePath(fileURLToPath(root));
if (normalizedFilename.startsWith(normalizedRoot)) {
return normalizedFilename.slice(normalizedRoot.length - 1);
} else {
return normalizedFilename;
}
}