<@U02Q7J6A17S> happy birthday
# general
t
@Mischa Spiegelmock happy birthday
m
thank you!
r
@thdxr so is esm for deploy builds only or does this also work in local dev mode?
t
works for both if you have type: "module" in your root package.json
r
hmm something odd is going on here. I just stepped up to 0.60.2 so not sure which release is messing with this. I was trying ESM but then reverted to just cjs. so no type module in my root package.json and no bundle config for my functions. I just have one api like this
Copy code
export const any = () => {
  console.log('ok')
  return {
    statusCode: 200,
    body: JSON.stringify({
      msg: 'Okey Dokey',
    }),
  }
}
wired up like this
Copy code
$default: 'handler.any',
then
Copy code
npm start
When I hit that API i can see my console log but always getting a 200 and a null for the body
Copy code
HTTP/1.1 200 OK
Date: Tue, 18 Jan 2022 17:03:51 GMT
Content-Type: application/json
Content-Length: 4
Connection: close
Apigw-Requestid: MJrmkg06IAMESjA=

null
am I missing something obvious? :/
swapping to
GET
just to make sure its not a any problem.
Copy code
'GET /': 'handler.get',
same thing. @thdxr did anything change around this? Do I need a different handler response?
t
async on the handler?
r
dude,.... 🤦‍♂️
t
we've all been there
r
ugh thanks... alright lemme go back to ESM and make sure thats working. it threw a crazy error first attempt
hmm ok so with that simple case it worked, as soon as i moved to something a little more complex with imports I am getting this
Copy code
{
  "errorType": "Runtime.UnhandledPromiseRejection",
  "errorMessage": "Error: Dynamic require of \"path\" is not supported",
  "reason": "Error: Dynamic require of \"path\" is not supported",
  "promise": {},
  "stack": [
    "Runtime.UnhandledPromiseRejection: Error: Dynamic require of \"path\" is not supported",
    "    at process.<anonymous> (file:///home/aphex/test-sst/node_modules/@serverless-stack/aws-lambda-ric/lib/index.js:34:23)",
    "    at process.emit (events.js:400:28)",
    "    at processPromiseRejections (internal/process/promises.js:245:33)",
    "    at processTicksAndRejections (internal/process/task_queues.js:96:32)"
  ]
}
I will try to figure out what is trying to do that...
@thdxr yeah so it looks like
aws-lambda-ric
maybe a big blocker here. I can't seem to load anything that uses require at all. For example my basic handler just does
Copy code
import './dep'
and
dep.ts
just does
Copy code
require('path')
will throw
Copy code
{
  "errorType": "Runtime.UnhandledPromiseRejection",
  "errorMessage": "Error: Dynamic require of \"path\" is not supported",
  "reason": "Error: Dynamic require of \"path\" is not supported",
  "promise": {},
  "stack": [
    "Runtime.UnhandledPromiseRejection: Error: Dynamic require of \"path\" is not supported",
    "    at process.<anonymous> (file:///home/aphex/dev/test-sst/node_modules/@serverless-stack/aws-lambda-ric/lib/index.js:34:23)",
    "    at process.emit (events.js:400:28)",
    "    at processPromiseRejections (internal/process/promises.js:245:33)",
    "    at processTicksAndRejections (internal/process/task_queues.js:96:32)"
  ]
}
This isn't a problem for my code, but it pretty much means I can only use a very few npm modules out there, that have gone full ESM. I think this is the issue here. https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/issues/22
j
FYI, updating to 0.60.0 said it was going to go to 0.60.2, but package.json did go to 0.60.0
Copy code
% npx sst update 0.60.0
Updating @serverless-stack/cli to 0.60.0
Updating @serverless-stack/resources to 0.60.0
Updating @aws-cdk/aws-apigatewayv2-alpha@2.7.0-alpha.0
Updating aws-cdk-lib@2.7.0
SST: 0.60.2
CDK: 2.7.0
t
@Ross Gerbasi if you're using esm you cannot use
require
anywhere
I'm using local debugging in an esm project right now
r
@thdxr that makes sense for my local modules the problem is other modules. for example just a simple node package with
type: module
will work with a index.js of this
Copy code
import JWT from 'jwt-simple'

console.log(JWT)
however jwt-simple uses require, but since its package.json int type module it should be ok. and seems to be fine in a normal node situation
t
Yeah this requires you to be using libraries that ship ESM
Or at least ship cjs without use of dynamic require
r
it looks like you all have taken over
aws-lambda-ric
though, is it possible to change how it imports things?
t
This isn't an issue with aws-lambda-ric, the error is just showing up there
r
because if thats the case, lets be honest, we cant really use ESM for a while
t
The issue is the following:
Copy code
// This is ok
const x = require("thing")

// This is not ok
function thing() {
  const x = require("thing")
}
r
yeah dynamic requires... hmmm
t
The latter is considered a dynamic require which is not allowed in ESM because all dynamic imports are async in esm and should be done with
await import("thing")
dynamic requires are rarely needed and a lot of libraries do them unnecessarily. I'm choosing to drop any library doing this (it's a good sign it's not well maintained)
r
I understand, we need to start a new site, caniuseesm.com 🙂
lets you put in a npm package and shows you ESM alternatives
t
haha yeah. We discovered yesterday that apollo-server is using dynamic requires in a bunch of places that don't need it and they don't ship ESM which means you get a bunch of junk even if you're not using it
r
Yeah yikes, this is gonna be hard, finding alternatives that have made sure they are not using any non-esm packages as well.
t
Yeah it's really just the dynamic require, I think people used it without thinking too hard - even the SST codebase has it in a few places
r
ok so wait a second, esbuild makes this worse i think
looking at this simple token library it doesnt have a dynamic require. https://github.com/hokaccha/node-jwt-simple/blob/master/lib/jwt.js
however esbuild bundles this, like this
Copy code
var require_jwt = __commonJS({
  "node_modules/jwt-simple/lib/jwt.js"(exports, module) {
    var crypto = __require("crypto");
    var algorithmMap = {
      HS256: "sha256",
      HS384: "sha384",
      HS512: "sha512",
      RS256: "RSA-SHA256"
    };
    var typeMap = {
      HS256: "hmac",
      HS384: "hmac",
      HS512: "hmac",
      RS256: "sign"
    };
t
hm what happens if you add this to
bundle.nodeModules
r
yes that does work
it compiles down to this now
Copy code
import "jwt-simple";
var get = async ({ authToken, event }) => {
  console.log("ok222");
  return {
    msg: "Okey Dokey"
  };
};
export {
  get
};
t
I wonder if this is a tsconfig issue
r
well esbuld doesnt do much with tsconfig sadly
t
Copy code
"compilerOptions": {
    "module": "esnext",
yeah it shouldn't but it is weird it's transpiling it that way
not sure this helps much but in my compiled output if i change
Copy code
var require_jwt = __commonJS({
  "node_modules/jwt-simple/lib/jwt.js"(exports, module) {
    var crypto = __require("crypto");
to
Copy code
var require_jwt = __commonJS({
  "node_modules/jwt-simple/lib/jwt.js"(exports, module) {
    var crypto = import("crypto");
it does work.. I wonder if there is a way to tell esbuild to do this. Essentially the bundled esbuild output is not module compatible, needs to use import syntax.
t
Does that actually work when executed? I think that returns a promise
r
no haha not at all haha
this will get ya there though.
Copy code
// node_modules/jwt-simple/lib/jwt.js
var require_jwt = __commonJS({
  async "node_modules/jwt-simple/lib/jwt.js"(exports, module) {
    var crypto = await import("crypto");
@thdxr looks like this has been recently talked about here. https://github.com/evanw/esbuild/issues/1927 someone made a regex script 😕 https://github.com/evanw/esbuild/issues/1921#issuecomment-1010490128 but I think we are stuck here as esbuild does not produce module safe syntax when bundled 😢
Alright opened another issue, maybe we will get something in esbuild someday... https://github.com/evanw/esbuild/issues/1944 for now though i am sadly going to have to go back to cjs and miss out on TLA 😢
t
Do you have a lot of modules this breaks on? Or just jwt-simple
r
it would be any module that uses another module with a
require
so almost all of them sadly
I guess i could set them as external modules, would pretty much be all modules are external, only bundle code in the
src
folder. How does that work for a deploy? does it deploy a
node_modules
or are deploys always bundled?
t
it'll deploy a node_modules, local and prod are pretty close now in behavior
r
Alright so i guess thats an option? move to esm and external all the dependencies
t
Yeah but I'd do them one by one to see what you actually have to move
r
Yup, but yeah i think ill stick with cjs for now. hopefully esbuild can fix that
m
Does
aws-sdk@3
export esm modules?