117 lines
3.7 KiB
TypeScript
117 lines
3.7 KiB
TypeScript
export type BuildWarningInput = {
|
|
code?: string | null;
|
|
message?: string | null;
|
|
id?: string | null;
|
|
file?: string | null;
|
|
};
|
|
|
|
export type BuildWarningClass =
|
|
| "large-chunk"
|
|
| "empty-chunk"
|
|
| "production-sourcemap"
|
|
| "aws-smithy-circular-chunk"
|
|
| "dynamic-static-import"
|
|
| "sourcemap-resolve-failure"
|
|
| "next-themes-invalid-annotation"
|
|
| "unknown";
|
|
|
|
export type BuildWarningClassification = {
|
|
class: BuildWarningClass;
|
|
suppressed: boolean;
|
|
code?: string;
|
|
message: string;
|
|
id?: string;
|
|
file?: string;
|
|
};
|
|
|
|
const normalize = (value: string | null | undefined) => value?.toLowerCase() ?? "";
|
|
const EMPTY_CHUNK_ALLOWLIST = new Set([
|
|
"___entity.export",
|
|
"api.collab.token",
|
|
"api.embed.forms._formKey.submit",
|
|
"api.leads.capture",
|
|
"api.metrics",
|
|
"api.password-policy-remind",
|
|
"api.status",
|
|
"api.tenants._tenant.plugins",
|
|
"callback",
|
|
"dry-run",
|
|
"healthcheck",
|
|
"healthz",
|
|
"ip-address-log-labels",
|
|
"logout",
|
|
"null",
|
|
"onboarding._id",
|
|
"postman_collection_._json",
|
|
"preferences",
|
|
"readyz",
|
|
"start",
|
|
"stream",
|
|
"submit",
|
|
"swagger",
|
|
"track-click._deliveryId",
|
|
"track-open._deliveryId_.gif_",
|
|
"workflows._id.run.stream._executionId",
|
|
]);
|
|
|
|
function getEmptyChunkName(message: string): string | null {
|
|
const match = /generated an empty chunk:\s*["']?([^"'.]+(?:\.[^"'.]+)*)["']?/i.exec(message);
|
|
return match?.[1] ?? null;
|
|
}
|
|
|
|
export function classifyBuildWarning(warning: BuildWarningInput): BuildWarningClassification {
|
|
const code = warning.code ?? undefined;
|
|
const message = warning.message ?? "";
|
|
const id = warning.id ?? undefined;
|
|
const file = warning.file ?? undefined;
|
|
const normalizedCode = normalize(code);
|
|
const normalizedMessage = normalize(message);
|
|
const normalizedId = normalize(id);
|
|
|
|
let warningClass: BuildWarningClass = "unknown";
|
|
|
|
if (
|
|
normalizedMessage.includes("some chunks are larger than") ||
|
|
normalizedMessage.includes("chunk size limit") ||
|
|
normalizedMessage.includes("chunk size warning")
|
|
) {
|
|
warningClass = "large-chunk";
|
|
} else if (normalizedMessage.includes("generated an empty chunk") || normalizedMessage.includes("empty chunk")) {
|
|
warningClass = "empty-chunk";
|
|
} else if (normalizedMessage.includes("source maps are enabled in production")) {
|
|
warningClass = "production-sourcemap";
|
|
} else if (
|
|
normalizedMessage.includes("will end up in different chunks") &&
|
|
normalizedMessage.includes("circular dependency between chunks") &&
|
|
(normalizedMessage.includes("@aws-sdk") || normalizedMessage.includes("@smithy"))
|
|
) {
|
|
warningClass = "aws-smithy-circular-chunk";
|
|
} else if (
|
|
normalizedMessage.includes("is dynamically imported by") &&
|
|
normalizedMessage.includes("but also statically imported by") &&
|
|
normalizedMessage.includes("dynamic import will not move module into another chunk")
|
|
) {
|
|
warningClass = "dynamic-static-import";
|
|
} else if (normalizedCode === "sourcemap_error" && normalizedMessage.includes("can't resolve original location")) {
|
|
warningClass = "sourcemap-resolve-failure";
|
|
} else if (normalizedCode === "invalid_annotation" && normalizedId.includes("next-themes")) {
|
|
warningClass = "next-themes-invalid-annotation";
|
|
}
|
|
|
|
const emptyChunkName = warningClass === "empty-chunk" ? getEmptyChunkName(message) : null;
|
|
const suppressEmptyChunk = emptyChunkName !== null && EMPTY_CHUNK_ALLOWLIST.has(emptyChunkName);
|
|
|
|
return {
|
|
class: warningClass,
|
|
suppressed: suppressEmptyChunk || warningClass === "sourcemap-resolve-failure" || warningClass === "next-themes-invalid-annotation",
|
|
code,
|
|
message,
|
|
id,
|
|
file,
|
|
};
|
|
}
|
|
|
|
export function shouldSuppressBuildWarning(warning: BuildWarningInput): boolean {
|
|
return classifyBuildWarning(warning).suppressed;
|
|
}
|