This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-01
Channels
- # announcements (10)
- # asami (2)
- # babashka (10)
- # beginners (55)
- # biff (37)
- # calva (9)
- # cherry (1)
- # clj-kondo (11)
- # clojure (221)
- # clojure-bay-area (12)
- # clojure-europe (77)
- # clojure-hungary (3)
- # clojure-nl (5)
- # clojure-norway (12)
- # clojurescript (11)
- # cursive (1)
- # data-science (11)
- # emacs (27)
- # figwheel (3)
- # fulcro (11)
- # graphql (5)
- # helix (7)
- # honeysql (3)
- # humbleui (9)
- # interceptors (2)
- # introduce-yourself (2)
- # kaocha (12)
- # lsp (27)
- # malli (6)
- # nbb (70)
- # off-topic (6)
- # re-frame (6)
- # react (3)
- # reitit (9)
- # releases (2)
- # scittle (29)
- # shadow-cljs (26)
- # sql (13)
- # tools-deps (61)
Did anybody manage to run an nbb-based lambda function with serverless recently? There's some examples out there (like this one: https://github.com/vharmain/nbb-serverless-example/blob/main/index.mjs) that maybe worked some time ago, but for some reason, .mjs files are currently simply ignored by serverless. If I try to run this very example I'm getting: "Error: Cannot find module './index.js'". Every attempt to work around this problem: renaming index.mjs to index.js means I cannot "import" in it because it's not an ESM Module, turning the entire thing into an ESM module via package.json/type:module leads to other issues (apparently serverless adds some code using "require" during the build). I just can't seem to make it work and I can't tell why.. when it looks like it did work 10 months ago.
That's what I thought too, but while running: "serverless invoke local --function hello" A file called "s_hello.js" is generated that has a "require" in it. And then the following error is thrown: ✖️ ReferenceError: require is not defined in ES module scope, you can use import instead This file is being treated as an ES module because it has a '.js' file extension and '/.../package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension. at file:///.../s_hello.js:2:21
@roseneck Did you research their github issues? I'm sure someone else ran into this. But what you can do instead of do this in a .js file which is a commonJS one:
async function foo () {
await import("./foo.mjs")
}
foo()
Maybe this issue? https://github.com/serverless/serverless/issues/11308
Perhaps @U6N4HSMFW knows something here
Do you think I could just do it like this: in my index.js
async function loadStuff () {
const nbb = await import('nbb');
const cljsFile = await nbb.loadFile('./function.cljs')
}
exports.handler=loadStuff();
Yea, that's one of several issues that kind of fit, but I didn't find a solution yet.
This is a workaround that we had in https://github.com/vharmain/nbb-lambda-adapter before we could just use ESM
Looks like calling import as an async function did the trick!
yes nice! but now I think it's good to add some caching, since you don't want to do all this work on every lambda invocation
So something like this:
var cachedHandler;
async function loadStuff () {
if (cachedHandler) {
return cachedHandler;
}
const nbb = await import('nbb');
cachedHandler = await nbb.loadFile('./function.cljs');
return cachedHandler;
}
exports.handler=loadStuff;
You mean if the function is still warm? Yea, good idea!
I'm not entirely sure the above is 100% correct since handler is now set to a function that returns a promise of the handler, but you can probably figure this out :)
E.g. this may work better:
var cachedHandler;
async function handler(payLoad) {
if (cachedHandler) {
return cachedHandler(payLoad);
}
const nbb = await import('nbb');
cachedHandler = await nbb.loadFile('./function.cljs');
return cachedHandler(payLoad);
}
exports.handler=loadStuff;
Hm.. .it says: TypeError: cachedHandler is not a function
Not sure why.
(ns function) (defn handler [event _ctx] (js/console.log event) (js/Promise.resolve #js{:hullo "world"}))
still the example code
Is it cachedHandler.handler(payload)?
I think you need to add something like:
#js {:handler handler}
at the bottom and then write:
cachedHandler = (await nbb.loadFile('./function.cljs')).handler;
When you have defn
as the last expression, the return value is a SCI Var which JS doesn't recognize as a function
I gotta to go and will fiddle around more later, thanks a ton for your help!
user=> (defn foo [] 1)
#'user/foo
user=> (set! (.-foo js/globalThis) foo)
nil
user=> (js/eval "foo()")
1
user=> (set! (.-foo js/globalThis) #'foo)
nil
user=> (js/eval "foo()")
"TypeError: foo is not a function"
I will try the example later when I get home and check if some issues have popped up
I’d expect it to just work as long as the lambda Nodejs runtime supports top-level await.. since 14.something.something
Yea I would totally expect that too and lambda definitely supports esm (zipping it up and uploading it manually works).
It must be something about serverless, but I can't tell what I'm doing wrong.
I just tried a fresh clone from the repo and ran the instructions in the example and it works :thinking_face:
I can maybe help debug what’s wrong with your setup @roseneck. Could you please paste your serverless.yml
contents here if possible?
> npx sls --version > Framework Core: 2.72.3 (local) > Plugin: 5.5.4 > SDK: 4.3.2 > Components: 3.18.2
AHH sorry didn’t notice that this was about serverless invoke local
. I just tested that the deployed one works. I’m not sure if the invoke local
has ever worked since I don’t use it.
And yes.. https://github.com/serverless/serverless/issues/11308 looks relevant
I’m afraid that if you want to use invoke local
your options are:
• patch serverless with this unmerged PR https://github.com/serverless/serverless/pull/11366/files
• use nbb-lambda-adapter instead that should work with non-`.mjs` stuff https://github.com/vharmain/nbb-lambda-adapter
It's not just local.. I just used local for faster feedback. I just did a fresh checkout of your repo and did a deploy with the following versions: Operating System: linux Node Version: 18.10.0 Framework Version: 2.72.3 (local) Plugin Version: 5.5.4 SDK Version: 4.3.2 Components Version: 3.18.2 Here's what I got: ~ serverless invoke --function add ✔️ 2m 19s Running "serverless" from node_modules Serverless: Using provider credentials, configured via dashboard: https://app.serverless.com/hankstenberg/apps/add/nbb-serverless-example/dev/eu-west-1/providers { "errorType": "Error", "errorMessage": "Cannot find module './index.js'\nRequire stack:\n- /var/task/s_add.js\n- /var/runtime/UserFunction.js\n- /var/runtime/Runtime.js\n- /var/runtime/index.js", "trace": [ "Error: Cannot find module './index.js'", "Require stack:", "- /var/task/s_add.js", "- /var/runtime/UserFunction.js", "- /var/runtime/Runtime.js", "- /var/runtime/index.js", " at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)", " at Module.require.i.require (/var/task/serverlesssdk/index.js:9:73131)", " at require (internal/modules/cjs/helpers.js:101:18)", " at Object.<anonymous> (/var/task/s_add.js:25:23)", " at Module._compile (internal/modules/cjs/loader.js:1085:14)", " at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)", " at Module.load (internal/modules/cjs/loader.js:950:32)", " at Function.Module._load (internal/modules/cjs/loader.js:790:12)", " at Module.require (internal/modules/cjs/loader.js:974:19)", " at require (internal/modules/cjs/helpers.js:101:18)" ] }
My node Version is v18.10.0
npx serverless invoke --function add --data '{"body":"{\"x\":1,\"y\":2}"}'
{
"statusCode": 200,
"body": "{\"result\":3}"
}
I just updated the example repo
• latest serverless and nbb
• add example how to use invoke
• add mention that invoke local
does not work
https://github.com/vharmain/nbb-serverless-example
Thanks for notifying about the issue!
I really don't understand what is wrong with my setup. So I checked out your updated repo. I cd'ed into it. I ran: • "npm update". • npx sls --org my-org • I said: "yes, I want to deploy now" • Deployed successfully • I ran npx serverless invoke --function add --data '{"body":"{\"x\":1,\"y\":2}"}' And I'm getting: "errorType": "Error", "errorMessage": "Cannot find module './index.js'\nRequire stack:\n- /var/task/s_add.js\n- /var/runtime/UserFunction.js\n- /var/runtime/Runtime.js\n- /var/runtime/index.js", "trace": [ "Error: Cannot find module './index.js'", I have just the same versions: Framework Core: 3.23.0 (local) Plugin: 6.2.2 SDK: 4.3.2
v18.10.0
On branch main Your branch is up to date with 'origin/main'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: serverless.yml Untracked files: (use "git add <file>..." to include in what will be committed) package-lock.json no changes added to commit (use "git add" and/or "git commit -a")
diff --git a/serverless.yml b/serverless.yml index f613ea5..c9bbec3 100644 --- a/serverless.yml +++ b/serverless.yml @@ -1,3 +1,5 @@ +org: hankstenberg +app: add service: nbb-serverless-example frameworkVersion: '2 || 3'
Could old serverless still be lurking in package-lock.json? You can try nuking it and running npm install
Yes, I still tried, but no
My Node.. Don’t expect that to be the issue but you never know
node --version
v18.9.1
Note sure how to downgrade to that specific version right now... but I really don't think that this can be the issue. I'll try some other things first. Like... I don't know.. restarting my computer. 😉
I’m also starting to run out of ideas. 😕 I’m on MacOS. Please let me know if there’s something more I can provide for help
Thanks a lot for all the support, at least I know that it is something about my setup now that helps a ton! I'll start ruling out things one by one. ❤️👍