-
-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to import Node builtins #239
Comments
Thanks for the report. I'll check this out. Ideally, if something is imported and not used in the css directly, wyw-in-js should tree-shake it before evalutating the code for css. |
@joshwcomeau Could you share a relevant code snippet that shows how you are using the |
Hey, One package (@jitl/notion-api) would always cause the dev server to hang forever (stuck at "Compiling..." without trace, which might or might not be related to this issue). Therefore I started to extract the few functionalities I needed from the library and recreate the helpers locally. One function (ensureImageDownloaded) relied on Recreating a simpler version of it would cause the same error reported
So to answer the question, an example of real-life use case here is using RSC to download remote images. export async function ensureImageDownloaded(args: {
url: string;
filenamePrefix: string;
directory: string;
}): Promise<string> {
const { url, filenamePrefix, directory } = args;
// Check if file already exists with prefix
const files = await readdir(directory);
const existingFile = files.find((name) => name.startsWith(filenamePrefix));
if (existingFile) {
return existingFile;
}
// Download image
const response = await fetch(url);
const contentType = response.headers.get("content-type") || "image/png";
const ext = contentType.split("/")[1];
const filename = `${filenamePrefix}.${ext}`;
const destPath = path.join(directory, filename);
// Convert response to buffer and save
const arrayBuffer = await response.arrayBuffer();
const buffer = Buffer.from(arrayBuffer);
await writeFile(destPath, buffer);
return filename;
} The repo linked by @joshwcomeau (https://github.com/joshwcomeau/pigmentcss-fs-issue) already provides a great minimal reproducible example as a starting point. You can swap |
Not sure if you have tried this with the latest versions of Next.js and Pigment CSS. I tried with @joshwcomeau's repo and I was getting a different error (after updating Nextjs to which meant that this one was not about sandbox. It wasn't able to find the file relative to itself. So as a workaround, I passed the root directory with // next.config.js
import * as path from "path";
import { withPigment } from "@pigment-css/nextjs-plugin";
const nextConfig = {
env: {
DATA_DIR: path.join(process.cwd(), "src"),
},
};
export default withPigment(nextConfig); and in the file where you want to read it's contents, I did - import * as path from "path";
import fs from "fs/promises";
export async function loadContent() {
const data = await fs.readFile(
path.join(process.env.DATA_DIR as string, "data.txt"),
"utf-8",
);
return data;
} This worked and the app built successfully. I am stating this as a solution as I am also doing the same thing for our Pigment CSS docs where we'll be authoring content in MDX and reading the contents through the One thing to note here is that as long as your function where you are using built-in modules are not being called at the file scope, rather somewhere inside one of the next.js primitives, it should be fine. Here's an example - function loadContent() {
}
const content = await loadContent();
export default function PageComponent() {
return <div>{content}</div>;
} This will throw an error because function loadContent() {
}
export default function PageComponent() {
const content = await loadContent();
return <div>{content}</div>;
} This should work as the actual call is inside another function. @mathieuhasum Can you follow the above and see if it works for you ? |
Thanks for the insights. I'll try again with this information and keep you updated. If I can't identify the root cause, I'll create a reproducible example by stripping down the project I have. 🤔 Maybe there is a problem of loading from the wrong scope indeed. For your information, as I was trying to debug yesterday I quickly swapped the package from PigmentCSS to Linaria. (From what I understand, they both leverage @wyw-in-js). And it did make the issue disappear. Will try to figure it out tonight or next weekend. |
I think I spoke too soon. The issue is still there during dev. What I stated above is valid for build command. Edit: Moving the import to be dynamic and inside the function call worked. But this is a workaround and not a proper solution - import * as path from "path";
export async function loadContent() {
const fs = await import("fs/promises");
const data = await fs.readFile(
path.join(process.env.DATA_DIR as string, "data.txt"),
"utf-8",
);
return data;
} |
Surely not a perfect solution, but I confirm your workaround works 👍 export default async function PageComponent() {
const blocks = await ...
for (const block of blocks) {
if (block.type === "image" ) {
const { ensureImageDownloaded } = await import("@jitl/notion-api");
await ensureImageDownloaded({
url: block.image.file.url,
directory: "public/images",
...
}),
}
}
return <>...</> |
Steps to reproduce
Repro URL:
https://github.com/joshwcomeau/pigmentcss-fs-issue
npm run dev
Context
In my project, I'm using the
fs/promises
module to load MDX content. This obviously wouldn't work in-browser, but I'm doing this specifically inside a Server Component, within the next.js App Router. So none of this code is included in the client-side bundles.It seems as though Pigment is unable to load any Node built-ins, but I don't think it has to; I don't think any of this stuff affects the generated CSS.
I also realize that this is likely an issue with @wyw-in-js, rather than Pigment CSS itself, but I wanted to highlight it here since that repo doesn't seem active.
Your environment
npx @mui/envinfo
Search keywords: import, Node, fs, sandbox
The text was updated successfully, but these errors were encountered: