middyjs / middy

🛵 The stylish Node.js middleware engine for AWS Lambda 🛵
https://middy.js.org
MIT License
3.73k stars 376 forks source link

(Aware of other issues) No "exports" main defined in /var/task/node_modules/@middy/core/package.json #1208

Closed EMDAccount closed 5 months ago

EMDAccount commented 6 months ago

Describe the bug Hello, I saw the other bugs reported on this issue and how it's normally caused by using CJS in v5 but I've migrated to ES6 completely and still getting this

CustomMessage failed with error No "exports" main defined in /var/task/node_modules/@middy/core/package.json.

To Reproduce Package.json is using "type": "module"

tsconfig.json has

  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "lib": [
      "es2022"
    ],
    "outDir": "./dist",
    "declaration": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "inlineSourceMap": true,
    "inlineSources": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    "typeRoots": [
      "./node_modules/@types",
      "./types"
    ],
    "moduleResolution": "node",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true
  },
  "include": [
    "src/**/*",
    "infrastructure/**/*.ts",
    "graphql/**/*.ts",
    "lib/**/*.ts",
    "test/**/*.ts",
    "types/**/*.ts"
  ],
  "exclude": [
    "node_modules",
    "cdk.out",
    "./dist/**/*" // Excluding the output directory
  ]
}

cdk.json has

  "app": "npx tsx infrastructure/Launcher.ts",
  "watch": {
    "include": ["**"],
    "exclude": [
      "README.md",
      "cdk*.json",
      "**/*.d.ts",
      "**/*.js",
      "tsconfig.json",
      "package*.json",
      "yarn.lock",
      "node_modules",
      "test"
    ]
  },
  "context": {
    "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
    "@aws-cdk/core:checkSecretUsage": true,
    "@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
    "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
    "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
    "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
    "@aws-cdk/aws-iam:minimizePolicies": true,
    "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
    "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
    "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
    "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
    "@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
    "@aws-cdk/core:enablePartitionLiterals": true,
    "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
    "@aws-cdk/aws-iam:standardizedServicePrincipals": true,
    "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true
  }
}

my lambda is exported as

import { captureLambdaHandler } from "@aws-lambda-powertools/tracer/middleware";
import { injectLambdaContext } from "@aws-lambda-powertools/logger/middleware";
import { logMetrics } from "@aws-lambda-powertools/metrics/middleware";

export const handler = middy(lambdaHandler)
  .use(captureLambdaHandler(tracer))
  .use(injectLambdaContext(logger, { clearState: true }))
  .use(logMetrics(metrics, { captureColdStartMetric: true }));

Environment

zdvhm commented 6 months ago

We're facing the same issue and this blocks us from upgrading v.4.7.0 -> v.5

willfarrell commented 5 months ago

Are you both using TypeScript? From my understanding TS transpiles (tsc?) to commonJS first before importing dependencies, which would cause this issue.

OffensiveBias-08-145 commented 5 months ago

Are you both using TypeScript? From my understanding TS transpiles (tsc?) to commonJS first before importing dependencies, which would cause this issue.

It would be disappointing if the library no longer supports TS. If that is the case with v5, then some sort of LTS v4 needs to be produced and continued support.

I have encountered this issue in JS and TS with lambdas, Nodejs, and other frameworks.

willfarrell commented 5 months ago

Does the sample compiler options found at https://middy.js.org/docs/intro/typescript/ need to be updated? If so, a PR would be most welcome.

EMDAccount commented 5 months ago

Yes we're using typescript.. that sounds like it would be the issue and needs updating. Unfortunately I'm not too familiar with how the PR would look like for this fix

lmammino commented 5 months ago

Hello, I spent a bit of time trying to troubleshoot this with @willfarrell today and we were not able to fully reproduce your issue, this is what we did:

package.json

{
  "name": "middy-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "type": "module",
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "aws-lambda": "^1.0.7",
    "typescript": "^5.4.5"
  },
  "dependencies": {
    "@middy/core": "^5.3.3"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "lib": [
      "es2022"
    ],
    "outDir": "./dist",
    "declaration": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": false,
    "inlineSourceMap": true,
    "inlineSources": true,
    "experimentalDecorators": true,
    "strictPropertyInitialization": false,
    "typeRoots": [
      "./node_modules/@types",
      "./types"
    ],
    "moduleResolution": "node",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "cdk.out",
    "./dist/**/*" // Excluding the output directory
  ]
}

src/test.ts

// testing an import of middy using ESM
import middy from '@middy/core'

// testing a top level await promise
await Promise.resolve("hello")

// testing building a simple handler
export const handler = middy(async function(_event: any, _context: any) {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Hello world'
    })
  }
})

Then we run:

node_modules/.bin/tsc

and if we execute the compiled file with:

node dist/test.js

It runs correctly with no error...

Can you see if what we did makes sense to you and spot any difference with your current setup?

Also, can you double check that your compiled files are actually using ESM (import/export) and not CommonJS (require)?

Hopefully this helps...

PS: note that our compiled file looks like this:

import middy from '@middy/core';
await Promise.resolve("hello");
export const handler = middy(async function (_event, _context) {
    return {
        statusCode: 200,
        body: JSON.stringify({
            message: 'Hello world'
        })
    };
});

and that we are using:

❯ node_modules/.bin/tsc --version
Version 5.4.5
EMDAccount commented 5 months ago

Will try troubleshooting this week with your setup above, I wonder if it's only an issue once deployed to AWS for some reason