middy: Cannot use import statement outside a module - Middy 3.0.4 w/ Jest, TypeScript

Describe the bug Cannot run Jest tests with any versions of Middy above 3.x, as imports are not resolving for Middy dependencies. I have attempted using babel-jest to resolve .js dependencies with the same issue. This is a Serverless framework app with about 13 TypeScript functions we deploy to individual Lambdas to AWS.

What is also strange is that the functions will build fine with Serverless framework for deployments. It seems to be only tests that cannot parse import statements correctly.

Error mesage: Screen Shot 2022-06-07 at 11 42 09 AM

Environment (please complete the following information):

Dev dependencies

Test dependencies

  • Jest [^26.6.3]
  • TS-Jest [^26.5.6]

jest.config.js:

module.exports = {
  collectCoverage: true,
  coverageDirectory: "jest-coverage",
  moduleFileExtensions: ["js", "ts", "json", "node"],
  modulePaths: ["<rootDir>"],
  testMatch: ["**/*.spec.ts"],
  transform: {
    "^.+\\.ts?$": "ts-jest",
  },
  verbose: true,
  testEnvironment: 'node'
};

tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./",
    "esModuleInterop": true,
    "preserveConstEnums": true,
    "strictNullChecks": true,
    "sourceMap": true,
    "allowJs": false,
    "target": "es6",
    "typeRoots": ["node_modules/@types"],
    "resolveJsonModule": true,
    "moduleResolution": "node"
  }
}

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 3
  • Comments: 18 (8 by maintainers)

Most upvoted comments

I feel like there is no winning with this one.

The TypeScript community wants something like this: https://gist.github.com/cef62/a14c3003095fe56fba2b69d6c57e5777?permalink_comment_id=4183778#gistcomment-4183778 while AWS is using the backwards compatible notation for older version of NodeJS (<=nodejs12.x), likely because they still have to support them (Note: module is not an officially supported field – https://stackoverflow.com/questions/42708484/what-is-the-module-package-json-field-for). Both on complete opposites.

I opted to go with what the NodeJS documentation recommended as best practice for the lowest version we support (>= nodejs14.x). https://nodejs.org/docs/latest-v14.x/api/packages.html#packages_dual_commonjs_es_module_packages

I’ve gone ahead and documented working configurations for the most popular transpilers and bundlers (https://middy.js.org/docs/best-practices/bundling). If a build tool isn’t keeping up to date the community will need to help them update or switch to another tool.

Personally, I use rollup & esbuild and haven’t had an issue yet in my transition to fully ESM.

I’ve released 3.1.0-rc.0 that now includes main and TS 4.7+ support. Let me know if it’s better or worse.

Ran into the same issue with a similar stack (Node, TypeScript, Serverless, middy 3, Jest, ts-jest).

The root of the problem seems to be that jest/ts-jest will transform your code in to commonjs-compatible JS before running your tests. By default, anything in node_modules will not be transformed. So if you’re importing ESM-compatible JS from node_modules you’ll get this SyntaxError.

A simple solution is to set Jest’s moduleFileExtensions option to prefer cjs over js file extensions, e.g.:

moduleFileExtensions: ["cjs", "js", "mjs", "jsx", "ts", "tsx", "json", "node"],

I don’t know if this is necessarily the best, but the other options (start using Babel, convert project to ESM) were cans of worms I didn’t want to open. @tylerzisk @Ben-Donnelly maybe this works for you?

Some links I found helpful:

Has this been reported to https://github.com/kulshekhar/ts-jest/issues? Curious if they have any ideas? I doubt middy is the first to ship esm packages.