typescriptazure-functionsazure-functions-runtime

Error [ERR_MODULE_NOT_FOUND]: Worker was unable to load entry point "dist/src/functions/trigger.js"


I am trying to create an Azure Function with typescript. I am fairly new to both. I followed the docs and create one Azure function using the steps mentioned in the Azure Docs.

Docs: [Azure function With Typecript](https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-vs-code-typescript?pivots=nodejs-model-v4)

When I created the function using Httptrigger template it worked just fine. I was able to access httptrigger and got the Hello World! in response. I am using programming model v4, host.json v2, Runtime worker: node, worker runtime version is ~4 and node version 20.

My current directory structure is as follows:

az-createquote-functionapp/
├── .vscode/
├── dist/
├── node_modules/
├── src/
│   ├── functions/
│   │   └── createQuoteHttp.ts
│   ├── index.ts
│   └── telemetry.ts
│   ├── processors/
│   │   └── IRequestProcessorInterface.ts
│   │   └── RequestProcessor.ts
├── .gitignore
├── .funcignore
├── eslint.config.js
├── host.json
├── local-settings.json
├── package-lock.json
├── package.json
└── tsconfig.json
My tsconfig.json:
{
  "compilerOptions": {
    "module": "ESNext",
    "target": "ESNext",
    "moduleResolution": "Node",
    "outDir": "dist",
    "rootDir": ".",
    "sourceMap": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "forceConsistentCasingInFileNames": true,
  },
  "include": [
    "./**/*.ts",
  ],
  "exclude": [
    "node_modules",
    "dist"
  ]
}
My package.json

{
  "name": "az-createquote-functionapp",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "clean": "rimraf dist",
    "prestart": "npm run clean && npm run build",
    "start": "func start  --verbose",
    "lint": "eslint '**/*.{js,mjs,cjs,ts}'",
    "lint:fix": "eslint '**/*.{js,mjs,cjs,ts}' --fix",
    "test": "echo \"No tests yet...\""
  },
  "dependencies": {
    "@azure/functions": "^4.5.0",
    "@azure/functions-opentelemetry-instrumentation": "^0.1.0",
    "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.24",
    "@azure/openapi": "^3.0.104",
    "@opentelemetry/api": "^1.9.0",
    "@opentelemetry/auto-instrumentations-node": "^0.49.1",
    "@opentelemetry/exporter-trace-otlp-http": "^0.52.1",
    "@opentelemetry/sdk-node": "^0.52.1",
    "drizzle-orm": "^0.33.0",
    "pg": "^8.12.0"
  },
  "devDependencies": {
    "@eslint/js": "^9.8.0",
    "@types/node": "^20.14.15",
    "@types/pg": "^8.11.6",
    "drizzle-kit": "^0.24.0",
    "eslint": "^9.8.0",
    "globals": "^15.9.0",
    "rimraf": "^5.0.0",
    "typescript": "^4.9.5",
    "typescript-eslint": "^8.0.0"
  },
  "overrides": {
    "eslint": "^9.8.0"
  },
  "type": "module",
  "main": "dist/src/{index.js,functions/*.js}"
}
My function httptrigger.ts
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
import { RequestProcessor } from '../processors/RequestProcessor';

export async function createQuoteHttp(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);
    try {
        // Use the request processor instance to handle the request
        const requestProcessor = new RequestProcessor();
        await requestProcessor.process(request, context);
    } catch (error : unknown) {
        if (error instanceof Error) {
            context.log(error.message);
        }
    }
    const name = request.query.get('name') || await request.text() || 'world';
    return { body: `Hello, ${name}!` };
};

app.http('createQuoteHttp', {
    route: 'V1/createQuote',
    methods: ['POST'],
    authLevel: 'anonymous',
    handler: createQuoteHttp
});
// processors/RequestProcessor.ts
import { HttpRequest, InvocationContext } from '@azure/functions';
import { IRequestProcessorInterface } from './IRequestProcessorInterface';

export class RequestProcessor implements IRequestProcessorInterface {
  async process(request: HttpRequest, context: InvocationContext): Promise<void> {
    context.log(request.body);
  }
}

As soon as I tried to import my processor or any other service as a matter of fact. I start getting following error:

Error [ERR_MODULE_NOT_FOUND]: Worker was unable to load entry point "dist/src/functions/createQuoteHttp.js": Cannot find module '/xxx/yyy/projects/az-createquote-functionapp/dist/src/processors/RequestProcessor' imported from /xxx/yyy/projects/az-createquote-functionapp/dist/src/functions/createQuoteHttp.js

However, files are present in the correct location in the dist folder. Trigger with default template works but as soon as I try to create any directory or other files and import it either in the index.ts or in my trigger.ts. I start getting this error. I need to build lot of files and directories to segregate logics but I am not sure why it is failing.

I have tried changing the node versions, changing the module resolution etc. I am fairly new to both typescript and azure functions. I checked log of documentation and tried to google it but for everyone the error might be the same but issue was always different.


Solution

  • You need to have below codes in the mentioned files.

    tsconfig-

    {
      "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "outDir": "dist",
        "rootDir": ".",
        "sourceMap": true,
        "strict": false
      }
    }
    

    package.json-

    {
      "name": "78860727",
      "version": "1.0.0",
      "description": "",
      "scripts": {
        "build": "tsc",
        "watch": "tsc -w",
        "clean": "rimraf dist",
        "prestart": "npm run clean && npm run build",
        "start": "func start --verbose",
        "test": "echo \"No tests yet...\""
      },
      "dependencies": {
        "@azure/functions": "^4.0.0"
      },
      "devDependencies": {
        "@types/node": "^20.x",
        "typescript": "^4.0.0",
        "rimraf": "^5.0.0"
      },
      "main": "dist/src/{index.js,functions/*.js}"
    }
    

    RequestProcessor-

    import { HttpRequest, InvocationContext } from '@azure/functions';
    import { IRequestProcessorInterface } from './IRequestProcessorInterface';
    
    export class RequestProcessor implements IRequestProcessorInterface {
      async process(request: HttpRequest, context: InvocationContext): Promise<void> {
        const name = await request.query.get('name');
        context.log('Response is:', name);
      }
    }
    

    createQuoteHttp-

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
    import { RequestProcessor } from '../processors/RequestProcessor';
    
    export async function createQuoteHttp(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function processed request for url "${request.url}"`);
        try {
            const requestProcessor = new RequestProcessor();
            await requestProcessor.process(request, context);
        } catch (error : unknown) {
            if (error instanceof Error) {
                context.log(error.message);
            }
        }
        const name = await request.text() || await request.json() || 'world';
        return { body: `Hello, ${name}!` };
    };
    
    app.http('createQuoteHttp', {
        route: 'V1/createQuote',
        methods: ['POST'],
        authLevel: 'anonymous',
        handler: createQuoteHttp
    });
    

    I am able to get the expected response.

    Azure Functions Core Tools
    Core Tools Version:       4.0.5907 Commit hash: N/A +807e89766a92b14fd07b9f0bc2bea1d8777ab209 (64-bit)
    Function Runtime Version: 4.834.3.22875
    
    [2024-08-13T08:48:56.674Z] Debugger listening on ws://*****/9b7c121***ff0f9
    [2024-08-13T08:48:56.676Z] For help, see: https://nodejs.org/en/docs/inspector
    [2024-08-13T08:48:56.762Z] Worker process started and initialized.
    [2024-08-13T08:48:56.827Z] Debugger attached.
    
    Functions:
    
            createQuoteHttp: [POST] http://localhost:7071/api/V1/createQuote
    
    For detailed output, run func with --verbose flag.
    [2024-08-13T08:49:13.411Z] Executing 'Functions.createQuoteHttp' (Reason='This function was programmatically called via the host APIs.', Id=865814c4-1dfa-438d-9396-0f4d9a853e25)
    [2024-08-13T08:49:13.546Z] Response is: Afreen
    [2024-08-13T08:49:13.546Z] Http function processed request for url "http://localhost:7071/api/V1/createQuote?name=Afreen"
    [2024-08-13T08:49:13.575Z] Executed 'Functions.createQuoteHttp' (Succeeded, Id=865814c4-1dfa-438d-9396-0f4d9a853e25, Duration=188ms)
    

    enter image description here

    Try to execute the code in debugging mode. Navigate to Run -> click Start debugging