End-to-end validation that the published dual CJS/ESM package actually works for real
consumers and on the real AWS Lambda runtime. Unlike the in-repo __tests__/module-compat
tests (which load dist/ directly with the optional AWS SDK present), this suite installs the
packed tarball into isolated consumer projects, honoring the published exports map and
files whitelist — the shape users actually get from npm.
It is excluded from the npm tarball by the root package.json files whitelist.
require('lambda-api')andimport 'lambda-api'load and serve without the optional@aws-sdk/*peer deps installed (the SDK is lazy — issue #290).- Issue #295: bundling a handler to ESM
.mjswith esbuild no longer throwsDynamic require of "querystring" is not supportedat load / Lambda cold start. - Deep imports (
lambda-api/lib/*), theexportssubpath map (incl.package.json), and TypeScriptnode16module resolution + types. - The S3 path (
getLinkpresign,sendFileGetObject) still works after the lazy-SDK refactor, against real S3.
npm run test:e2ePacks the tarball, installs it into isolated temp roots (with and without @aws-sdk/*), and
runs each fixture in e2e/fixtures/ in its own child process with synthetic API Gateway events.
No Docker required; suitable for CI on a Node 18/20/22 matrix.
cd e2e/localstack && npm install # one-time: installs the AWS SDK clients used to drive it
npm run test:e2e:localstack # from the repo rootRequires Docker. Brings up localstack/localstack via docker-compose.yml, deploys the
handler variants (CJS, ESM, an esbuild-bundled .mjs, and an S3 handler) as Lambda functions on
nodejs20.x, then invokes them directly and through a real API Gateway REST API, asserting
responses and checking logs for the #295 Dynamic require error. LocalStack executes functions
in the actual AWS Lambda Node runtime containers, so a passing run is the authoritative proof the
package loads clean at cold start. The suite tears LocalStack down when done.
e2e/
run-layer1.mjs # Layer 1 orchestrator (no Docker)
helpers/harness.mjs # pack tarball, isolated installs, child-process runner, assertions
fixtures/ # consumer apps: cjs, esm, deep-import-*, s3, typescript
localstack/
docker-compose.yml # LocalStack service
package.json # AWS SDK clients that drive LocalStack
run-all.mjs # deploy + invoke + assert + teardown
handlers/ # Lambda handler variants deployed to LocalStack
Add a fixture directory under e2e/fixtures/<name>/ (a package.json + handler that reads an
event path from process.argv[2] and writes the response JSON to stdout), then wire a check in
run-layer1.mjs. For a real-runtime case, add a handler under localstack/handlers/ and a
function entry in localstack/run-all.mjs.