-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Support for native .node
modules
#1051
Comments
You could argue that esbuild should handle this itself. However, it currently doesn't do this. The const nativeNodeModulesPlugin = {
name: 'native-node-modules',
setup(build) {
// If a ".node" file is imported within a module in the "file" namespace, resolve
// it to an absolute path and put it into the "node-file" virtual namespace.
build.onResolve({ filter: /\.node$/, namespace: 'file' }, args => ({
path: require.resolve(args.path, { paths: [args.resolveDir] }),
namespace: 'node-file',
}))
// Files in the "node-file" virtual namespace call "require()" on the
// path from esbuild of the ".node" file in the output directory.
build.onLoad({ filter: /.*/, namespace: 'node-file' }, args => ({
contents: `
import path from ${JSON.stringify(args.path)}
try { module.exports = require(path) }
catch {}
`,
}))
// If a ".node" file is imported within a module in the "node-file" namespace, put
// it in the "file" namespace where esbuild's default loading behavior will handle
// it. It is already an absolute path since we resolved it to one above.
build.onResolve({ filter: /\.node$/, namespace: 'node-file' }, args => ({
path: args.path,
namespace: 'file',
}))
// Tell esbuild's default loading behavior to use the "file" loader for
// these ".node" files.
let opts = build.initialOptions
opts.loader = opts.loader || {}
opts.loader['.node'] = 'file'
},
} |
.node
modules
Squashed commit of the following: commit 496340f43970424f81cdcfef3430b119e15fbb0f Author: Ruslan Fadeev <kinrany@yandex.com> Date: Thu Mar 25 17:11:23 2021 +0300 Push persistence to container registry commit b65aea0 Author: Ruslan Fadeev <kinrany@yandex.com> Date: Thu Mar 25 17:05:09 2021 +0300 Split build for persistence into two stages commit e5b8cfa Author: Ruslan Fadeev <kinrany@yandex.com> Date: Thu Mar 25 16:05:22 2021 +0300 Revert building worker with esbuild for now See evanw/esbuild#1051 commit 2812a18 Author: Ruslan Fadeev <kinrany@yandex.com> Date: Thu Mar 25 03:26:34 2021 +0300 Fix commit 78e81ad Author: Ruslan Fadeev <kinrany@yandex.com> Date: Thu Mar 25 02:09:07 2021 +0300 Try running "prisma generate" explicitly commit 09d7b99 Author: Ruslan Fadeev <kinrany@yandex.com> Date: Thu Mar 25 02:05:34 2021 +0300 Rewrite persistence service with esbuild commit c2fb6a2 Author: Ruslan Fadeev <kinrany@yandex.com> Date: Thu Mar 25 01:36:10 2021 +0300 Do not push to container registry for now
I tested the above plugin with the But from the discussion in #972, it sounds like So the solution here is to mark this module as external with |
Would it make sense for esbuild to copy packages that shouldn't be bundled into a new Perhaps even minify each package, but keep the separation between packages. The problem I'm still having in my case is that |
@evanw Would love a solution to this as well. I'm using So tried creating a plugin, see kentcdodds/mdx-bundler#74 But it yells at using |
+1 |
Noticed that one of my dependencies (limax - https://github.com/lovell/limax) also uses .node but it isn't supported by esbuild yet. Is there at least a workaround for this? Development is a struggle without a dev-server 🤣 EDIT: welp, a workaround (at least in my case) was easier than I thought (using vitejs!): import { UserConfig, defineConfig } from 'vite'
const configuration: UserConfig = {
...
optimizeDeps: {
exclude: [
'limax',
],
},
}
export default defineConfig(configuration) Excluding the package/dependency which has a Also see: https://vitejs.dev/config/#optimizedeps-exclude I hope for anyone who stumbles over this issue can make an use of this (: |
I get this same thing in a Jenkins environment with ssh2 library using serverless framework + serverless-esbuild plugin. I fixed it by adding it to the external list
|
Would it be okay if we added additional options to the onLoad / onResolve callback, specifying additional files to include? That way onResolve could return any additional |
I I am getting error: Cannot use the "file" loader without an output path |
this doesnt work because esbuild doesnt know what to do with .node files. (ssh2 and cpu-something) evanw/esbuild#1051 or switch to js instead of ts see if helps or just replace .node files with something?
Hey did you figure out a solution to this issue? I am having the same problem |
@LinirZamir the |
with the esbuild and the dev server. evanw/esbuild#1051 (comment)
What comment? |
On my side using On AWS cdk i did that: bundling: {
externalModules: props.nodeModules.dependencies,
loader: {
".node": "file",
},
minify: true,
sourceMap: true,
}, |
For those finding this issue when trying to use I can successfully use sharp in a lambda nodejs CDK function using (Note: Use new lambdaNodejs.NodejsFunction(this, "SOME_ID", {
// ...
bundling: {
externalModules: ["sharp"],
nodeModules: ["sharp"],
commandHooks: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
beforeBundling(inputDir: string, outputDir: string): string[] {
return [];
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
beforeInstall(inputDir: string, outputDir: string): string[] {
return [];
},
afterBundling(inputDir: string, outputDir: string): string[] {
return [`cd ${outputDir}`, "rm -rf node_modules/sharp && npm install --no-save --arch=x86 --platform=linux sharp"];
}
}
}
// ...
}); Taken from aws-solutions/serverless-image-handler |
Any clue how I can make this work with serialport? |
For those using serverless-esbuild and encountering this with serverless.yml:
This will cause the sshcrypto.node file to be copied to the same folder as the js file generated by esbuild and the resulting js should point to the copied file's path correctly. This is if you don't have ssh2 in the lambda's environment (which some people might have in a layer). |
This config works for me:
|
Worked for me when deploying an SST Ion Remix app with the new sst.aws.Remix('MyApp', {
transform: {
server: {
nodejs: {
esbuild: {
loader: {
'.node': 'file',
},
},
},
},
},
}); |
I'm trying to use esbuild to minify my Node project, to make my container images smaller with a multi-stage build.
I need lovell/sharp, which has a
.node
module. This breaks the build.I could mark that module as external. But I'm also using pnpm, so the package and its dependencies are actually behind symlinks. It seems I'd have to manually move modules and replace paths in esbuild output to make this work.
Ideally esbuild would assume that native modules have no other dependencies and just place them next to the regular output.
The text was updated successfully, but these errors were encountered: