Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Error: Cannot find module '#node-web-compat' #69

Closed
Robstaa opened this issue Apr 20, 2022 · 13 comments
Closed

[BUG] Error: Cannot find module '#node-web-compat' #69

Robstaa opened this issue Apr 20, 2022 · 13 comments
Labels
bug Something isn't working

Comments

@Robstaa
Copy link

Robstaa commented Apr 20, 2022

Describe the bug
When starting my typescript application, I immediately get the error

Error: Cannot find module '#node-web-compat'

The stack is the following:

- /Users/robstaa/code/comp/api/node_modules/aws-jwt-verify/dist/cjs/https.js
- /Users/robstaa/code/comp/api/node_modules/aws-jwt-verify/dist/cjs/jwk.js
- /Users/robstaa/code/comp/api/node_modules/aws-jwt-verify/dist/cjs/jwt-rsa.js
- /Users/robstaa/code/comp/api/node_modules/aws-jwt-verify/dist/cjs/index.js
- /Users/robstaa/code/comp/api/src/domains/authentication/verifyToken.ts

This is the verifyToken.ts file:

import { UnauthorizedError } from 'routing-controllers';
import { CognitoJwtVerifier } from 'aws-jwt-verify';
import { JwtExpiredError } from 'aws-jwt-verify/error';
import { TokenExpiredError } from './errors';

export const getToken = (authorization): string => {
    if (!authorization || authorization.split(' ')[0] !== 'Bearer') {
        throw new UnauthorizedError('No token provided');
    }

    const token = authorization.split(' ')[1];

    return token;
};

export const verifyToken = async (authorization): Promise<any> => {
    const verifier = CognitoJwtVerifier.create({
        userPoolId: process.env.COGNITO_USER_POOL_ID as string,
        clientId: process.env.COGNITO_CLIENT_ID as string,
        tokenUse: 'access',
    });
    try {    
        const token = getToken(authorization);
        const payload = await verifier.verify(token);
        return payload;
    } catch (e: any) {
        if (e instanceof JwtExpiredError) {
            throw new TokenExpiredError();
        } else {
            throw new UnauthorizedError(e.message);
        }
    }
};

Versions
Which version of aws-jwt-verify are you using?
=> "^3.0.0"
Are you using the library in Node.js or in the Web browser?
=> Node.js
If Node.js, which version of Node.js are you using? (Should be at least 14)
=> 17.3.0
If using TypeScript, which version of TypeScript are you using? (Should be at least 4)
=> "^4.5.4"
Also, to run the application in dev I am using ts-node-dev ("^1.1.8")

@Robstaa Robstaa added the bug Something isn't working label Apr 20, 2022
@Robstaa
Copy link
Author

Robstaa commented Apr 20, 2022

Just saw that this is a duplicate of #66

@hakanson
Copy link
Contributor

@Robstaa - did #66 solve your issue? Can this bug be closed?

@ottokruse
Copy link
Contributor

Just ran (a slightly modified version of) your code with ts-node-dev and that works fine for me. What exact versions does your [INFO] log line reveal?

npx ts-node-dev index.ts
[INFO] 08:56:57 ts-node-dev ver. 1.1.8 (using ts-node ver. 9.1.1, typescript ver. 4.6.3)

The modified version of your code (index.ts):

import { CognitoJwtVerifier } from 'aws-jwt-verify';
import { JwtExpiredError } from 'aws-jwt-verify/error';

class UnauthorizedError extends Error {}
class TokenExpiredError extends Error {}

export const getToken = (authorization: any): string => {
    if (!authorization || authorization.split(' ')[0] !== 'Bearer') {
        throw new UnauthorizedError('No token provided');
    }

    const token = authorization.split(' ')[1];

    return token;
};

export const verifyToken = async (authorization: any): Promise<any> => {
    const verifier = CognitoJwtVerifier.create({
        userPoolId: process.env.COGNITO_USER_POOL_ID as string,
        clientId: process.env.COGNITO_CLIENT_ID as string,
        tokenUse: 'access',
    });
    try {    
        const token = getToken(authorization);
        const payload = await verifier.verify(token);
        return payload;
    } catch (e: any) {
        if (e instanceof JwtExpiredError) {
            throw new TokenExpiredError();
        } else {
            throw new UnauthorizedError(e.message);
        }
    }
};
// tsconfig.json
{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
  }
}

@Robstaa
Copy link
Author

Robstaa commented Apr 21, 2022

Hi @ottokruse and @hakanson thanks for the quick reply!
Unfortunately I could not fix the issue yet, I am currently using https://github.com/ghdna/cognito-express but would like to replace that with aws-jwt-verify.

When I start the development env, this is the output:

[INFO] 09:45:22 ts-node-dev ver. 1.1.8 (using ts-node ver. 9.1.1, typescript ver. 4.5.4)
Error: Cannot find module '#node-web-compat'
Require stack:
...

The tsconfig.json looks like this:

{
  "compilerOptions": {
    "baseUrl": ".",
    "declaration": true,
    "declarationMap": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "importHelpers": true,
    "incremental": true,
    "lib": ["es7"],
    "module": "commonjs",
    "moduleResolution": "node",
    "noFallthroughCasesInSwitch": true,
    "noImplicitAny": false,
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "outDir": "dist",
    "resolveJsonModule": true,
    "sourceMap": true,
    "strict": true,
    "strictPropertyInitialization": false,
    "target": "es2017",
    "typeRoots": ["./node_modules/@types"],
    "types": ["reflect-metadata", "node"],
    "useUnknownInCatchVariables": true,
  },
  "include": ["src/**/*.*"],
  "exclude": ["node_modules", "src/**/*.test.ts", "**/__mocks__/*", "**/__mockData__/"]
}

@hakanson
Copy link
Contributor

Any chance you can create a minimal express app to demonstrate and host in a GitHub repo? That would be easier for us to git clone and find the problem, then we can PR back the fix.

@ottokruse
Copy link
Contributor

Any update @Robstaa ?

@lemiesz
Copy link

lemiesz commented May 18, 2022

I have a similar issue. Trying to bundle my function to be deployed as a edge lambda with

      const secureInterceptorNodejsFunction = new NodeJSLambda.NodejsFunction(
            this,
            'SecureInterceptorNodejsFunction',
            {
                bundling: {
                    define: {
                        'process.env.USER_POOL_ID': JSON.stringify('us-east-1_gEQ7Fw07X'),
                        'process.env.CLIENT_ID': JSON.stringify('5c5j92ba0b8nkrgulve36vfhfs'),
                    },
                    externalModules: ['#node-web-compact'],
                    minify: true,
                },
                entry: path.join(__dirname, '../authenticate-cognito-lambda/index.js'),
                awsSdkConnectionReuse: false,
                functionName: props?.functionName,
                role: this.role,
                runtime: MoteLambda.SecureRuntime.NODEJS_14_X,
                timeout: Duration.seconds(5),
                tracing: Lambda.Tracing.ACTIVE,
            },
        );

Getting the following error

 > node_modules/aws-jwt-verify/dist/cjs/https.js:9:35: error: Could not resolve "#node-web-compat" (mark it as external to exclude it from the bundle, or surround it with try/catch to handle the failure at run-time)

Edit:

Downgrading to 2.1.3 seems to have resolved the issue. Although issue is present in 3.0

@ottokruse
Copy link
Contributor

@lemiesz don't mark #node-web-compat as external module cause it isn't an external module.

When do you get that error?

Just tested and this CDK synths flawlessly for me:

import { Stack, StackProps, aws_lambda_nodejs } from "aws-cdk-lib";
import { Construct } from "constructs";
import * as path from "path";

export class JwttestStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const secureInterceptorNodejsFunction =
      new aws_lambda_nodejs.NodejsFunction(
        this,
        "SecureInterceptorNodejsFunction",
        {
          bundling: {
            define: {
              "process.env.USER_POOL_ID": JSON.stringify("<some_id>"),
              "process.env.CLIENT_ID": JSON.stringify("<some_id>"),
            },
            minify: true,
          },
          entry: path.join(
            __dirname,
            "../authenticate-cognito-lambda/index.js"
          ),
        }
      );
  }
}

@ottokruse
Copy link
Contributor

Closing for now -- will re-open if you can provide a reproducible sample.

@lemiesz
Copy link

lemiesz commented May 19, 2022

Error happens during bundling. However I see you are using CDK2.

I'm still on an old version (until I can upgrade the rest of our stack) "monocdk": "1.145.0",.
Downgrading to "aws-jwt-verify": "^2.1.3" allows me to use this without issue. However with version 3.0.0 It fails.

I've tried both with it marked as external (as per the error message recommendation), and without. Fails same way

Seems its just not compatible with monocdk

@ottokruse
Copy link
Contributor

CDK2 uses esbuild for bundling, and esbuild has supported subpath imports since Oct 2021 (evanw/esbuild#1691). Not sure what monocdk uses for bundling, maybe an older version of esbuild––you might try updating that.
Or don't bundle ...

@lemiesz
Copy link

lemiesz commented May 19, 2022

monocdk does indeed use esbuild.

Looks like I had installed 0.12.28, but it wasnt until 0.13.13 that the subpath imports change was merged.

Upgrading to the a newer version of esbuild has fixed my issues... thanks!

@SethO
Copy link

SethO commented Sep 4, 2022

Currently produces this error if you run this library in Jest tests with either esbuild-jest (v0.5.0) or @swc/jest (v0.2.22). I imagine both are tied to versions of esbuild that are incompatible.

The workaround from https://github.com/ottokruse/jest-subpath-import/blob/main/jest.config.fix.js works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants