-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
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
Cannot bundle .node files #14289
Comments
Start a new pull request in StackBlitz Codeflow. |
This issue is preventing me from using many modules. No workaround or package has worked. |
I managed to bundle nodejs-polars using this config but it's incredibly hacky. |
Well, that's one hell of a hack. But I'll have to study and use it I guess. Thank you so much. Resolving .node files should be a feature in Vite. |
The same problem occurs with I have confirmed that it works by adding the following settings to vite: {
optimizeDeps: {
exclude: ["fsevents"],
},
}, Error log
|
|
|
We've managed to get |
Are there any plans on this one? Even though @goastler shared a nice blog, it doesn't solve anything for the general public. |
The handling of Further, there's more complications with files other than tldr; probably better for someone who knows more about these files to implement a plugin / build support in vite |
related #5688 |
For those searching for a solution, I (chatgpt to be honest) came up with a quick plugin: function nativeFilesPlugin(): PluginOption {
const files = new Map<string, { readonly fileName: string; readonly fileContent: Buffer }>();
return {
name: 'node-binaries-plugin',
async load(id) {
if (!id.endsWith('.node')) {
return null;
}
const fileContent = await fs.readFile(id);
const hash = createHash('sha256').update(fileContent).digest('hex').slice(0, 8);
const fileName = `${path.basename(id, '.node')}.${hash}.node`;
files.set(id, { fileName, fileContent });
return `export default require('./${fileName}');`;
},
generateBundle(_, bundle) {
for (const [id, { fileName, fileContent }] of files.entries()) {
this.emitFile({ type: 'asset', fileName, source: fileContent });
delete bundle[id];
}
},
};
} I'm building into build: {
rollupOptions: {
output: {
format: 'cjs',
},
},
commonjsOptions: {
requireReturnsDefault: 'auto',
}
} |
It looks like an even simpler version also works: {
name: 'require-node-binaries-plugin',
transform: (code, id) => {
if (id.endsWith('.node')) {
return code.replace(/export default "(.+)"/, 'export default require(".$1")');
}
return;
},
} paired with |
Small update here. Native assets didn't work in my project because I'm using So I had to revert to the original naive plugin, and, unfortunately, add a special hard-coded case for function nativeFilesPlugin(): PluginOption {
interface NativeFile {
readonly fileName: string;
readonly fileContent: Buffer;
}
const nativeFiles = new Map<string, NativeFile>();
const uws = require.resolve('uWebSockets.js');
const readNativeFile = async (filePath: string): Promise<NativeFile> => {
const fileContent = await readFile(filePath);
const hash = createHash('sha256').update(fileContent).digest('hex').slice(0, 8);
const fileName = `${path.basename(filePath, '.node')}.${hash}.node`;
return { fileName, fileContent };
};
return {
name: 'native-files-plugin',
async load(id) {
if (id === uws) {
// Special handling for the ESM-wrapper around CJS-module with dynamic requires (uWebSockets.js).
const nativeFile = await readNativeFile(
// Yes, build the file name at build time, not runtime 🤷♂️(we can't do dynamic `import {} from ''`)
path.resolve(path.dirname(uws), './uws_' + process.platform + '_' + process.arch + '_' + process.versions.modules + '.node'),
);
nativeFiles.set(id, nativeFile);
return `export default require('./${nativeFile.fileName}')`;
} else if (id.endsWith('.node')) {
const nativeFile = await readNativeFile(id);
nativeFiles.set(id, nativeFile);
return `export default require('./${nativeFile.fileName}');`;
}
return;
},
generateBundle(_, bundle) {
for (const [id, { fileName, fileContent }] of Array.from(nativeFiles.entries())) {
this.emitFile({ type: 'asset', fileName, source: fileContent });
delete bundle[id];
}
},
};
} I believe the issue should be handled on rollup's side, not on vite's, as I believe it's purely rollup's job to bundle everything into a module graph that vite would understand. There's also an on-going work on Rolldown (a Rust replacement for rollup), so maybe it should even go there, or maybe it's already supported there, I can't test it right now. |
In my case, everything was solved after deleting |
Describe the bug
I am trying to create a server side bundle that includes packages containing .node files. In this specific instance, the problematic package is nodejs-polars.
I have tried various plugins to resolve this but none of them seem to work.
My config is as follows:
Reproduction
https://stackblitz.com/edit/vitejs-vite-xp1ggj?file=vite.config.ts,package.json&terminal=dev
Steps to reproduce
Run
vite build --config vite.config.ts
System Info
The text was updated successfully, but these errors were encountered: