Improve error handling
This commit is contained in:
90
src/esbuild-postcss.ts
Normal file
90
src/esbuild-postcss.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import { dirname, join } from "node:path";
|
||||
import type * as esbuild from "esbuild";
|
||||
import { CssSyntaxError } from "postcss";
|
||||
import { type Compile, type StyleMap, pkgName, toCSSText } from "./shared";
|
||||
|
||||
const PLUGIN_NAME = "tailwind";
|
||||
const ESBUILD_NAMESPACE = "babel-tailwind";
|
||||
|
||||
export const esbuildPlugin = (styleMap: StyleMap, compile: Compile): esbuild.Plugin => ({
|
||||
name: PLUGIN_NAME,
|
||||
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /^tailwind:.+\.css$/ }, ({ path, importer }) => {
|
||||
const resolved = join(dirname(importer), path.replace(/^tailwind:/, ""));
|
||||
if (styleMap.has(resolved)) {
|
||||
return {
|
||||
path: resolved,
|
||||
namespace: ESBUILD_NAMESPACE,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
build.onResolve({ filter: RegExp(`^${pkgName}/base$`) }, () => ({
|
||||
path: "directive:base",
|
||||
namespace: ESBUILD_NAMESPACE,
|
||||
}));
|
||||
|
||||
build.onLoad({ filter: /.*/, namespace: ESBUILD_NAMESPACE }, async ({ path }) => {
|
||||
if (path === "directive:base") {
|
||||
return {
|
||||
contents: (await compile("@tailwind base")).css,
|
||||
loader: "css",
|
||||
};
|
||||
}
|
||||
|
||||
if (!styleMap.has(path)) return;
|
||||
|
||||
const styles = styleMap.get(path)!;
|
||||
|
||||
try {
|
||||
const result = await compile(toCSSText(styles));
|
||||
return {
|
||||
contents: result.css,
|
||||
loader: "css",
|
||||
};
|
||||
} catch (e) {
|
||||
if (e instanceof CssSyntaxError) {
|
||||
const lines = e.source!.split("\n");
|
||||
const cls = lines
|
||||
.at(e.line! - 2)!
|
||||
.slice(1, -1)
|
||||
.trim();
|
||||
|
||||
const entry = styles.find(s => s.key === cls)!;
|
||||
if (!entry) {
|
||||
throw new Error("Could not find entry for CSS");
|
||||
}
|
||||
|
||||
const { location: loc } = entry;
|
||||
const errLoc: Partial<esbuild.Location> = {
|
||||
file: loc.filename,
|
||||
line: loc.start.line,
|
||||
column: loc.start.column,
|
||||
length: loc.end.column - loc.start.column,
|
||||
lineText: loc.text,
|
||||
};
|
||||
|
||||
const doesNotExist = e.reason.match(/The `(.+)` class does not exist/)?.[1];
|
||||
if (doesNotExist) {
|
||||
const index = loc.text.indexOf(doesNotExist, loc.start.column);
|
||||
if (index !== -1) {
|
||||
errLoc.column = index;
|
||||
errLoc.length = doesNotExist.length;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
errors: [
|
||||
{
|
||||
text: e.reason,
|
||||
location: errLoc,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
Reference in New Issue
Block a user