Dynamic require of "os" is not supportedDynamic require of "fs" is not supportedDynamic require of "path" is not supported
-
Comment Answer by user @ctjlewis on evan/esbuild pull request titled "Rewrite require() calls of Node built-ins to import statements when emitting ESM for Node#2067": link to comment evanw/esbuild#2067 (comment)
-
Similar answer, that doesn't check for the existance of the methods before creating them is provided by @guushamann on evanw/esbuild#1921 (comment)
Approach by @ctjlewis
See the BuildOptions below:
const ESM_REQUIRE_SHIM = `
await (async () => {
const { dirname } = await import("path");
const { fileURLToPath } = await import("url");
/**
* Shim entry-point related paths.
*/
if (typeof globalThis.__filename === "undefined") {
globalThis.__filename = fileURLToPath(import.meta.url);
}
if (typeof globalThis.__dirname === "undefined") {
globalThis.__dirname = dirname(globalThis.__filename);
}
/**
* Shim require if needed.
*/
if (typeof globalThis.require === "undefined") {
const { default: module } = await import("module");
globalThis.require = module.createRequire(import.meta.url);
}
})();
`;
/** Whether or not you're bundling. */
const bundle = true;
/** Tell esbuild to add the shim to emitted JS. */
const shimBanner = {
"js": ESM_REQUIRE_SHIM
};
/**
* ESNext + ESM, bundle: true, and require() shim in banner.
*/
const buildOptions: BuildOptions = {
...common,
format: "esm",
target: "esnext",
platform: "node",
banner: bundle ? shimBanner : undefined,
bundle,
};
esbuild(buildOptions);For a minified version of the shim, you can use the following (in general, you should not add minified code to the top of your bundle contexts because a stranger on GitHub tells you to, but feel free to verify it):
const ESM_REQUIRE_SHIM = `
await(async()=>{let{dirname:e}=await import("path"),{fileURLToPath:i}=await import("url");if(typeof globalThis.__filename>"u"&&(globalThis.__filename=i(import.meta.url)),typeof globalThis.__dirname>"u"&&(globalThis.__dirname=e(globalThis.__filename)),typeof globalThis.require>"u"){let{default:a}=await import("module");globalThis.require=a.createRequire(import.meta.url)}})();
`;The end result of these build options are a single ESM bundle with all non-builtin modules inlined, and a global require() shimmed for any CJS imports that are left in the bundle (e.g. builtins like events).
If your program depends on esbuild, you will need to add it to your externs, i.e. { external: ["esnext"] }.
Additional solution whenesbuild is running via nx using package @nx/esbuild
Comment answer by user @valclarkop on evan/esbuild How to fix "Dynamic require of "os" is not supported"#1921
File: project.json
{
"targets":{
"build":{
"executor":"@nx/esbuild:esbuild",
"esbuildOptions":{
"legalComments":"inline",
"banner":{
"js":"const require = (await import('node:module')).createRequire(import.meta.url);const __filename = (await import('node:url')).fileURLToPath(import.meta.url);const __dirname = (await import('node:path')).dirname(__filename);"
}
}
}
}
}
For sveltjs you can use this SHIM but, you also need to use this
sveltjspull request to be able to pass build options through to esbuild sveltejs/kit#9398