fix(web): resolve Payload CMS build error with Node.js ESM loader
Payload CMS imports .css/.scss/.svg files that Node.js ESM can't handle during page data collection. Added a custom ESM loader that stubs these asset imports, fixing the build that has been broken since the upgrade. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,33 +1,10 @@
|
||||
/**
|
||||
* Node.js ESM custom loader — stubs static asset imports as empty modules.
|
||||
*
|
||||
* Next.js 16 does route collection in raw Node ESM (not webpack/turbopack).
|
||||
* Payload CMS deps import .css, .scss, .svg, and other assets that Node
|
||||
* can't handle. This loader intercepts those and returns empty modules.
|
||||
*
|
||||
* Usage: NODE_OPTIONS="--import ./apps/web/css-stub-loader.mjs"
|
||||
*/
|
||||
|
||||
import { register } from "node:module";
|
||||
|
||||
register(
|
||||
"data:text/javascript," +
|
||||
encodeURIComponent(`
|
||||
const STYLE_RE = /\\.(css|scss|sass|less|svg|png|jpg|jpeg|gif|webp|ico|woff|woff2|ttf|eot|otf)$/;
|
||||
// Node.js ESM loader that stubs non-JS asset imports during Next.js page data collection.
|
||||
// Payload CMS and its deps import .css/.scss/.svg files that Node.js can't handle.
|
||||
const STUB_EXTENSIONS = ['.css', '.scss', '.sass', '.svg', '.png', '.jpg', '.jpeg', '.gif', '.ico', '.woff', '.woff2', '.ttf', '.eot'];
|
||||
|
||||
export function resolve(specifier, context, nextResolve) {
|
||||
if (STYLE_RE.test(specifier)) {
|
||||
return { url: 'data:text/javascript,export default {};', shortCircuit: true };
|
||||
if (STUB_EXTENSIONS.some(ext => specifier.endsWith(ext))) {
|
||||
return { url: 'data:text/javascript,export default ""', shortCircuit: true };
|
||||
}
|
||||
return nextResolve(specifier, context);
|
||||
}
|
||||
|
||||
export function load(url, context, nextLoad) {
|
||||
if (STYLE_RE.test(url)) {
|
||||
return { format: 'module', source: 'export default {};', shortCircuit: true };
|
||||
}
|
||||
return nextLoad(url, context);
|
||||
}
|
||||
`),
|
||||
import.meta.url,
|
||||
);
|
||||
|
||||
@@ -90,7 +90,6 @@ const config: NextConfig = {
|
||||
"@payloadcms/richtext-lexical",
|
||||
"@payloadcms/next",
|
||||
"@payloadcms/ui",
|
||||
"react-image-crop",
|
||||
"sharp",
|
||||
"libsodium-wrappers",
|
||||
],
|
||||
@@ -130,7 +129,7 @@ const config: NextConfig = {
|
||||
},
|
||||
|
||||
/** Enables hot reloading for local packages without a build step */
|
||||
transpilePackages: INTERNAL_PACKAGES,
|
||||
transpilePackages: [...INTERNAL_PACKAGES, "react-image-crop"],
|
||||
experimental: {
|
||||
optimizePackageImports: INTERNAL_PACKAGES,
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "next build --webpack",
|
||||
"build": "NODE_OPTIONS='--experimental-loader ./css-stub-loader.mjs' next build --webpack",
|
||||
"clean": "git clean -xdf .cache .next .turbo node_modules",
|
||||
"dev": "next dev",
|
||||
"format": "prettier --check . --ignore-path ../../.gitignore",
|
||||
|
||||
Reference in New Issue
Block a user