Fork me on GitHub
#shadow-cljs
<
2022-08-16
>
sirwobin15:08:42

What does "Cannot set property 'returnExports' of undefined" mean? I've created a node-library target in shadow-cljs, zipped the resulting js file and uploaded it as function code for an AWS lambda. When I call the lambda I get this error.

sirwobin15:08:37

I export one function called 'handler' in js and I'm confident that it is being called correctly. Some environment checking code was throwing exceptions correctly, I fixed the env and then got this error.

thheller15:08:09

is this script maybe trying to be loaded as a module? ESM?

thheller15:08:25

what is the full error? what is the build config?

thheller15:08:51

did you include the node_modules when bundling? assuming you use any npm packages?

thheller15:08:11

is there more than one error and maybe this one a symptom of the other?

sirwobin17:08:40

I haven't included the node_modules. I thought the closure compiler included necessary dependencies. While I haven't added any node_modules, shadow-cljs has quite a few. Should I include all node_modules?

thheller17:08:56

no, you only need to include the packages you actually use. you can also post-process the release build with something like https://github.com/vercel/ncc to bundle all npm dependencies

thheller17:08:16

shadow-cljs does not do that by default since generally it is not required or desirable for regular node builds

sirwobin06:08:32

Thank you for the help btw. 🙂 Very much appreciated. Shadow is

sirwobin06:08:00

My build config looks like this:

:builds
 {:lambda {:target :node-library
           :exports {:handler com.pds.external-api.core/handler}
           :output-to "target/lambda.mjs"
           :compiler-options {:output-feature-set :es2020}}}

sirwobin06:08:26

Does something not look right?

thheller06:08:42

well the hint seems to be that you have :output-to "target/lambda.mjs" meaning its expected to be a ES module?

thheller06:08:50

:node-library outputs commonjs so that won't work

thheller06:08:42

or just :output-to "target/lambda.js" and just run without modules?

sirwobin09:08:08

changing the build target to .js worked perfectly. Thank you! I copied that entry from an example without understanding the significance.

sirwobin09:08:43

So when I package the zip file, I should take care to include my own node_modules and their deps? Can shadow help me determine those deps or should I figure them out via dep trees and select what to zip?

sirwobin12:08:56

or should I just take everything in node_modules?

sirwobin14:08:19

FYI: transitive dependencies for any top level node package can be listed with npm ls -a --json | jq --arg v 'shadow-cljs' '[ .dependencies | .[$v] | .dependencies | .. | .dependencies? | objects | to_entries[] | .key ] | sort | unique' and changing the value of --arg v

thheller15:08:32

me recommendation is either post processing with ncc to get a completely standalone .js file

thheller15:08:53

or creating a dedicated directory that has its own package.json and only includes the packages you actually need in production

thheller15:08:09

and the build output going into that dir and then just zipping that entire dir

👍 1
sirwobin15:08:23

That's great advice. Thank you