Skip to content

Instantly share code, notes, and snippets.

@usametov
Created July 8, 2025 13:39
Show Gist options
  • Save usametov/572d35c56f6f4388e63864651f73576c to your computer and use it in GitHub Desktop.
Save usametov/572d35c56f6f4388e63864651f73576c to your computer and use it in GitHub Desktop.
azure deployment notes

When deploying a TypeScript Azure Function App with multiple files (e.g., a handler and a library) to Azure, the issue of functions not appearing in the Azure Portal often stems from incorrect project structure, configuration, or deployment settings. Below, I'll guide you through the steps to properly deploy a TypeScript Azure Function App with multiple files, ensuring the functions are visible in the Azure Portal.

Common Issues and Solutions

The problem you're facing—functions not appearing in the Azure Portal—can occur due to:

  1. Incorrect project structure: Azure Functions expects a specific folder structure, especially for TypeScript projects where compiled JavaScript files are used.
  2. Missing or incorrect function.json files: For the v3 programming model, these files define the function's bindings and entry points.
  3. Improper compilation or deployment: TypeScript files need to be compiled to JavaScript, and all necessary files (including dependencies and libraries) must be included in the deployment package.
  4. Missing dependencies: Shared library files or dependencies might not be correctly included or referenced.
  5. Configuration issues: Settings like WEBSITE_RUN_FROM_PACKAGE or AzureWebJobsFeatureFlags may not be set correctly.

Step-by-Step Guide to Deploy a TypeScript Azure Function App with Multiple Files

1. Verify Project Structure

Azure Functions expects a specific structure for TypeScript projects. A typical structure for a TypeScript Azure Function with a handler and a library file might look like this:

<project_root>/
├── src/
│   ├── functions/
│   │   ├── myFunction.ts  // Handler file for the function
│   ├── lib/
│   │   ├── myLibrary.ts   // Shared library file
├── dist/                  // Compiled JavaScript output
│   ├── functions/
│   │   ├── myFunction.js
│   ├── lib/
│   │   ├── myLibrary.js
├── node_modules/
├── .funcignore
├── host.json
├── package.json
├── tsconfig.json
└── local.settings.json
  • Handler file (myFunction.ts): Contains the function logic and trigger definitions (e.g., HTTP trigger).
  • Library file (myLibrary.ts): Contains reusable code imported by the handler.
  • dist/ folder: Contains compiled JavaScript files after running tsc (TypeScript compiler).
  • host.json: Configures the Azure Functions runtime.
  • package.json: Lists dependencies and scripts for building and deploying.
  • tsconfig.json: Configures TypeScript compilation settings.

Example myFunction.ts:

import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
import { myLibraryFunction } from "../lib/myLibrary";

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    const result = myLibraryFunction("Hello from library!");
    return { body: result };
}

app.http("httpTrigger1", {
    methods: ["GET", "POST"],
    handler: httpTrigger1,
});

Example myLibrary.ts:

export function myLibraryFunction(input: string): string {
    return `Processed: ${input}`;
}

Ensure:

  • The scriptFile property in function.json (if using v3 model) points to the compiled JavaScript file (e.g., ../dist/functions/myFunction.js).
  • The library file is correctly imported in the handler using a relative path (e.g., ../lib/myLibrary).

2. Configure tsconfig.json

Ensure your TypeScript compiler settings are correct to output compiled JavaScript files to the dist/ folder.

Example tsconfig.json:

{
  "compilerOptions": {
    "target": "es2018",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
  • outDir: Specifies the output directory for compiled JavaScript files (dist/).
  • rootDir: Ensures the source folder structure is preserved in the dist/ folder.
  • module: Use commonjs for Azure Functions compatibility.

3. Configure host.json

The host.json file defines runtime settings. For TypeScript, ensure it references the correct paths for compiled files.

Example host.json (for v4 model):

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true
      }
    }
  }
}

For the v3 model, you might need to ensure function.json files are generated correctly (see Step 4).

4. Generate function.json (if using v3 model)

If you're using the v3 programming model, each function requires a function.json file in the same directory as the compiled JavaScript file. For TypeScript, this file should point to the compiled JavaScript file in the dist/ folder.

Example myFunction/function.json (in <project_root>/dist/functions/myFunction/):

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["get", "post"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ],
  "scriptFile": "../dist/functions/myFunction.js"
}

Note: In the v4 programming model, function.json is not required as bindings are defined directly in code (as shown in the myFunction.ts example above). If you're using v4, skip this step.

5. Install Dependencies

Ensure all dependencies, including @azure/functions, are installed and listed in package.json.

Example package.json:

{
  "name": "my-azure-functions",
  "version": "1.0.0",
  "scripts": {
    "build": "tsc",
    "start": "func start",
    "deploy": "func azure functionapp publish <FUNCTION_APP_NAME>"
  },
  "dependencies": {
    "@azure/functions": "^4.0.0"
  },
  "devDependencies": {
    "typescript": "^4.0.0",
    "azure-functions-core-tools": "^4.x"
  }
}

Run npm install to install dependencies.

6. Build the Project

Compile your TypeScript files to JavaScript:

npm run build

This generates the dist/ folder with compiled .js files, maintaining the same structure as src/.

7. Test Locally

Before deploying, test the function locally to ensure it works:

npm run start
  • Verify that the function is accessible (e.g., http://localhost:7071/api/httpTrigger1?name=test).
  • Check the terminal logs for errors, such as missing dependencies or incorrect imports.

8. Deploy to Azure

Use Azure Functions Core Tools to deploy the project:

npm run deploy

Or, explicitly:

func azure functionapp publish <FUNCTION_APP_NAME>

Important Settings:

  • Set WEBSITE_RUN_FROM_PACKAGE: In the Azure Portal, go to your Function App > Settings > Configuration > Application settings, and add:
    • Name: WEBSITE_RUN_FROM_PACKAGE
    • Value: 1 This ensures the function app runs from a zip package, improving performance and avoiding file-locking issues.
  • Set AzureWebJobsFeatureFlags (for v4 model, if in preview): Add:
    • Name: AzureWebJobsFeatureFlags
    • Value: EnableWorkerIndexing This is required for the v4 programming model during its preview phase.

9. Verify Deployment in Azure Portal

After deployment:

  1. Go to the Azure Portal > Function App > Functions.
  2. Check if your function (e.g., httpTrigger1) appears.
  3. If no functions are visible, check the following:
    • Deployment Logs: In the Azure Portal, go to Deployment Center > Logs to verify the deployment succeeded.
    • File Structure: Use the Advanced Tools (Kudu) in the Azure Portal (https://<FUNCTION_APP_NAME>.scm.azurewebsites.net) to inspect the deployed files in /site/wwwroot. Ensure the dist/ folder, host.json, and package.json are present.
    • Errors: Check Application Insights or the Function App logs for runtime errors (e.g., missing dependencies or incorrect scriptFile paths).

10. Troubleshooting Common Issues

  • Functions not visible in Azure Portal:
    • Ensure the compiled JavaScript files are included in the deployment package. The func azure functionapp publish command should zip the entire project, including the dist/ folder.
    • If using the v3 model, verify that function.json files are correctly generated and reference the compiled .js files.
    • Check for runtime errors in the code (e.g., require statements for missing modules or files). A thrown error during function registration can cause functions to not load.
  • Library file not found:
    • Ensure the library file (myLibrary.js) is in the dist/lib/ folder and correctly referenced in the handler (e.g., ../lib/myLibrary).
    • Verify that node_modules and all dependencies are included in the deployment package.
  • Deployment succeeds but no functions:
    • Check if node_modules is deployed. If ignored (e.g., via .funcignore), dependencies won't be available, causing functions to fail. Remove node_modules from .funcignore if present.
    • Ensure the main field in package.json points to the correct entry point if custom (default is index.js for v3).
  • TypeScript compilation issues:
    • If compilation fails or files are missing, check tsconfig.json for correct outDir and include settings.
    • Avoid placing compiled files in the same directory as source files to prevent overwriting issues.

11. Additional Tips

  • Use Zip Deployment: Zip deployment is the recommended method for Azure Functions. It ensures all files, including your library and compiled JavaScript, are correctly packaged.
  • Avoid Portal Editing: Do not edit code in the Azure Portal, as it can overwrite deployed files. Develop and test locally, then deploy.
  • Use Source Control: Set up continuous deployment with GitHub or Azure DevOps to automate builds and deployments, ensuring the TypeScript compilation step is included.
  • Monitor with Application Insights: Enable Application Insights to debug runtime issues.

Example Deployment Workflow

  1. Initialize the project:
    func init MyFunctionApp --typescript
  2. Create a function:
    func new --template "Http Trigger" --name httpTrigger1
  3. Add your library file (src/lib/myLibrary.ts) and update the handler to use it.
  4. Build the project:
    npm run build
  5. Test locally:
    npm run start
  6. Deploy:
    func azure functionapp publish <FUNCTION_APP_NAME>
  7. Verify in the Azure Portal.

If Issues Persist

If the functions still don't appear:

  • Check Kudu: Access the Kudu console (https://<FUNCTION_APP_NAME>.scm.azurewebsites.net) and verify the contents of /site/wwwroot.
  • Recreate Function App: As a last resort, delete and recreate the Function App, then redeploy.
  • Log a Bug: If you suspect a platform issue, log a bug on the Microsoft feedback portal or Azure Functions GitHub issues page.

By following these steps, you should be able to deploy your TypeScript Azure Function App with a handler and library file, ensuring the functions are visible in the Azure Portal. If you encounter specific errors, share them, and I can provide more targeted assistance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment