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.
The problem you're facing—functions not appearing in the Azure Portal—can occur due to:
- Incorrect project structure: Azure Functions expects a specific folder structure, especially for TypeScript projects where compiled JavaScript files are used.
- Missing or incorrect
function.json
files: For the v3 programming model, these files define the function's bindings and entry points. - 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.
- Missing dependencies: Shared library files or dependencies might not be correctly included or referenced.
- Configuration issues: Settings like
WEBSITE_RUN_FROM_PACKAGE
orAzureWebJobsFeatureFlags
may not be set correctly.
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 runningtsc
(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 infunction.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
).
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 thedist/
folder.module
: Usecommonjs
for Azure Functions compatibility.
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).
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.
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.
Compile your TypeScript files to JavaScript:
npm run build
This generates the dist/
folder with compiled .js
files, maintaining the same structure as src/
.
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.
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: - Set
AzureWebJobsFeatureFlags
(for v4 model, if in preview): Add:
After deployment:
- Go to the Azure Portal > Function App > Functions.
- Check if your function (e.g.,
httpTrigger1
) appears. - 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 thedist/
folder,host.json
, andpackage.json
are present. - Errors: Check Application Insights or the Function App logs for runtime errors (e.g., missing dependencies or incorrect
scriptFile
paths).
- 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 thedist/
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.
- Ensure the compiled JavaScript files are included in the deployment package. The
- Library file not found:
- Ensure the library file (
myLibrary.js
) is in thedist/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.
- Ensure the library file (
- 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. Removenode_modules
from.funcignore
if present. - Ensure the
main
field inpackage.json
points to the correct entry point if custom (default isindex.js
for v3).
- Check if
- TypeScript compilation issues:
- 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.
- Initialize the project:
func init MyFunctionApp --typescript
- Create a function:
func new --template "Http Trigger" --name httpTrigger1
- Add your library file (
src/lib/myLibrary.ts
) and update the handler to use it. - Build the project:
npm run build
- Test locally:
npm run start
- Deploy:
func azure functionapp publish <FUNCTION_APP_NAME>
- Verify in the Azure Portal.
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.