Azure Functions JavaScript-utvecklarguide

Den här guiden innehåller detaljerad information som hjälper dig att utveckla Azure Functions med JavaScript.

Som utvecklare Express.js, Node.js JavaScript eller JavaScript bör du läsa någon av följande artiklar om du inte har Azure Functions att läsa någon av följande artiklar:

Komma igång Begrepp Interaktiv utbildning

Grundläggande om JavaScript-funktioner

En JavaScript-funktion (Node.js) är en exporterad funktion som körs när den utlöses ( utlösare function konfigureras i function.jspå). Det första argumentet som skickas till varje funktion är ett -objekt som används för att ta emot och skicka context bindningsdata, logga och kommunicera med körningen.

Mappstrukturen

Den mappstruktur som krävs för ett JavaScript-projekt ser ut så här. Det här standardvärdet kan ändras. Mer information finns i avsnittet scriptFile nedan.

FunctionsProject
 | - MyFirstFunction
 | | - index.js
 | | - function.json
 | - MySecondFunction
 | | - index.js
 | | - function.json
 | - SharedCode
 | | - myFirstHelperFunction.js
 | | - mySecondHelperFunction.js
 | - node_modules
 | - host.json
 | - package.json
 | - extensions.csproj

I roten av projektet finns det en delad filhost.js som kan användas för att konfigurera funktionsappen. Varje funktion har en mapp med en egen kodfil (.js) och en bindningskonfigurationsfil (function.jspå). Namnet på function.json den överordnade katalogen är alltid namnet på din funktion.

De bindningstillägg som krävs i version 2.x av Functions-körningen definieras i filen, med de extensions.csproj faktiska biblioteksfilerna i bin mappen . När du utvecklar lokalt måste du registrera bindningstillägg . När du utvecklar funktioner i Azure Portal görs den här registreringen åt dig.

Exportera en funktion

JavaScript-funktioner måste exporteras via module.exports (eller exports ). Den exporterade funktionen ska vara en JavaScript-funktion som körs när den utlöses.

Som standard söker Functions-körningen efter din funktion i index.js , där delar samma överordnade katalog som dess motsvarande index.js function.json . I standardfallet ska den exporterade funktionen vara den enda exporten från filen eller exporten med namnet run eller index . Om du vill konfigurera filplatsen och exportnamnet för funktionen kan du läsa om hur du konfigurerar funktionens startpunkt nedan.

Den exporterade funktionen skickas ett antal argument vid körning. Det första argumentet som krävs är alltid ett context -objekt. Om funktionen är synkron (returnerar inte ett Promise) måste du skicka objektet eftersom anrop krävs context context.done för korrekt användning.

// You should include context, other arguments are optional
module.exports = function(context, myTrigger, myInput, myOtherInput) {
    // function logic goes here :)
    context.done();
};

Exportera en asynkron funktion

När du använder deklarationen eller async function vanliga JavaScript Promises i version 2.x av Functions-körningen behöver du inte uttryckligen anropa återanropet för att signalera att funktionen har context.done slutförts. Funktionen slutförs när den exporterade asynkrona funktionen/Promise har slutförts. För funktioner som kör version 1.x måste du fortfarande anropa context.done när koden har körts klart.

Följande exempel är en enkel funktion som loggar att den utlöstes och omedelbart slutför körningen.

module.exports = async function (context) {
    context.log('JavaScript trigger function processed a request.');
};

När du exporterar en asynkron funktion kan du också konfigurera en utdatabindning för att ta return värdet. Detta rekommenderas om du bara har en utdatabindning.

Om du vill tilldela return utdata med ändrar du name egenskapen till $return i function.json .

{
  "type": "http",
  "direction": "out",
  "name": "$return"
}

I det här fallet bör funktionen se ut som i följande exempel:

module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');
    // You can call and await an async method here
    return {
        body: "Hello, world!"
    };
}

Bindningar

I JavaScript konfigureras och definieras bindningar i en funktions function.jspå. Funktioner interagerar med bindningar på flera olika sätt.

Indata

Indata delas in i två kategorier i Azure Functions: en är utlösarindata och den andra är ytterligare indata. Utlösare och andra indatabindningar (bindningar direction === "in" för ) kan läsas av en funktion på tre sätt:

  • [Rekommenderas] Som parametrar som skickas till din funktion. De skickas till funktionen i samma ordning som de definieras ifunction.js . Egenskapen name som definieras function.jspå behöver inte matcha namnet på parametern, även om den bör det.

    module.exports = async function(context, myTrigger, myInput, myOtherInput) { ... };
    
  • Som medlemmar i context.bindings -objektet. Varje medlem namnges av egenskapen name som definieras ifunction.jspå.

    module.exports = async function(context) { 
        context.log("This is myTrigger: " + context.bindings.myTrigger);
        context.log("This is myInput: " + context.bindings.myInput);
        context.log("This is myOtherInput: " + context.bindings.myOtherInput);
    };
    
  • Som indata med Hjälp av arguments JavaScript-objektet. Detta är i stort sett detsamma som att skicka indata som parametrar, men gör att du kan hantera indata dynamiskt.

    module.exports = async function(context) { 
        context.log("This is myTrigger: " + arguments[1]);
        context.log("This is myInput: " + arguments[2]);
        context.log("This is myOtherInput: " + arguments[3]);
    };
    

Utdata

Utdata (bindningar direction === "out" för ) kan skrivas till av en funktion på flera olika sätt. I samtliga fall motsvarar egenskapen för bindningen som definieras ifunction.jspå namnet på den name objektmedlem som skrivs till i din funktion.

Du kan tilldela data till utdatabindningar på något av följande sätt (kombinera inte dessa metoder):

  • [Rekommenderas för flera utdata] Returnera ett -objekt. Om du använder en asynkron/Promise-returnerande funktion kan du returnera ett objekt med tilldelade utdata. I exemplet nedan heter utdatabindningarna "httpResponse" och "queueOutput" ifunction.jspå.

    module.exports = async function(context) {
        let retMsg = 'Hello, world!';
        return {
            httpResponse: {
                body: retMsg
            },
            queueOutput: retMsg
        };
    };
    

    Om du använder en synkron funktion kan du returnera det här objektet med hjälp av context.done (se exempel).

  • [Rekommenderas för enskilda utdata] Returnerar ett värde direkt och använder $return bindningsnamn. Detta fungerar bara för asynkrona/Promise-returnerande funktioner. Se exempel på export av en asynkron funktion.

  • Tilldela värden context.bindings till Du kan tilldela värden direkt till context.bindings.

    module.exports = async function(context) {
        let retMsg = 'Hello, world!';
        context.bindings.httpResponse = {
            body: retMsg
        };
        context.bindings.queueOutput = retMsg;
        return;
    };
    

Datatypen Bindningar

Om du vill definiera datatypen för en indatabindning använder du dataType egenskapen i bindningsdefinitionen. Om du till exempel vill läsa innehållet i en HTTP-begäran i binärt format använder du typen binary :

{
    "type": "httpTrigger",
    "name": "req",
    "direction": "in",
    "dataType": "binary"
}

Alternativen för dataType är: binary , och stream string .

context-objekt

Körningen använder ett context -objekt för att skicka data till och från din funktion och körningen. Används för att läsa och ange data från bindningar och för att skriva till loggar är objektet context alltid den första parametern som skickas till en funktion.

För funktioner med synkron kod inkluderar kontextobjektet återanropet done som du anropar när funktionen har bearbetat klart. Det är done inte nödvändigt att anropa explicit när du skriver asynkron kod. done Återanropet anropas implicit.

module.exports = (context) => {

    // function logic goes here

    context.log("The function has executed.");

    context.done();
};

Kontexten som skickas till funktionen exponerar executionContext en egenskap, som är ett objekt med följande egenskaper:

Egenskapsnamn Typ Beskrivning
invocationId Sträng Tillhandahåller en unik identifierare för det specifika funktionsanropet.
functionName Sträng Anger namnet på den funktion som körs
functionDirectory Sträng Tillhandahåller functions-appkatalogen.

I följande exempel visas hur du returnerar invocationId .

module.exports = (context, req) => {
    context.res = {
        body: context.executionContext.invocationId
    };
    context.done();
};

context.bindings-egenskap

context.bindings

Returnerar ett namngivet objekt som används för att läsa eller tilldela bindningsdata. Indata och utlösarbindningsdata kan nås genom att läsa egenskaper på context.bindings . Utdatabindningsdata kan tilldelas genom att lägga till data i context.bindings

Följande bindningsdefinitioner i din function.jspå ger dig åtkomst till innehållet i en kö från och tilldelar utdata till context.bindings.myInput en kö med hjälp av context.bindings.myOutput .

{
    "type":"queue",
    "direction":"in",
    "name":"myInput"
    ...
},
{
    "type":"queue",
    "direction":"out",
    "name":"myOutput"
    ...
}
// myInput contains the input data, which may have properties such as "name"
var author = context.bindings.myInput.name;
// Similarly, you can set your output data
context.bindings.myOutput = { 
        some_text: 'hello world', 
        a_number: 1 };

Du kan välja att definiera utdata för utdatabindning context.done med hjälp av metoden i stället för context.binding -objektet (se nedan).

context.bindingData-egenskap

context.bindingData

Returnerar ett namngivet objekt som innehåller utlösarmetadata och funktionsanropsdata ( invocationId sys.methodName , , , sys.utcNow sys.randGuid ). Ett exempel på utlösarmetadata finns i det här event hubs-exemplet.

context.done-metod

context.done([err],[propertyBag])

Låter körningen veta att koden har slutförts. När funktionen använder async function deklarationen behöver du inte använda context.done() . context.doneMotringning anropas implicit. Asynkrona funktioner är tillgängliga i Nod 8 eller senare, vilket kräver version 2.x av Functions-körningen.

Om funktionen inte är en asynkron funktion måste du anropa för att meddela context.done körningen att funktionen har slutförts. Körningen går ut om den saknas.

Med metoden kan du skicka tillbaka både ett användardefinierat fel till körningen och ett context.done JSON-objekt som innehåller utdatabindningsdata. Egenskaper som skickas context.done för att skriva över allt som angetts i context.bindings objektet.

// Even though we set myOutput to have:
//  -> text: 'hello world', number: 123
context.bindings.myOutput = { text: 'hello world', number: 123 };
// If we pass an object to the done function...
context.done(null, { myOutput: { text: 'hello there, world', noNumber: true }});
// the done method overwrites the myOutput binding to be: 
//  -> text: 'hello there, world', noNumber: true

context.log-metod

context.log(message)

Gör att du kan skriva till strömningsfunktionsloggarna på standardspårningsnivån, med andra tillgängliga loggningsnivåer. Spårningsloggning beskrivs i detalj i nästa avsnitt.

Skriva spårningsutdata till loggar

I Functions använder du metoderna context.log för att skriva spårningsutdata till loggarna och konsolen. När du context.log() anropar skrivs ditt meddelande till loggarna på standardspårningsnivån, vilket är informationsspårningsnivån. Functions integreras med Azure Application Insights för att bättre samla in loggar för funktionsappen. Program Insights, som är en del av Azure Monitor, tillhandahåller resurser för insamling, visuell rendering och analys av både programtelemetri och spårningsutdata. Mer information finns i övervaka Azure Functions.

I följande exempel skriver vi en logg på informationsspårningsnivån, inklusive anrops-ID:t:

context.log("Something has happened. " + context.invocationId); 

Alla context.log metoder stöder samma parameterformat som stöds av metoden Node.js util.format. Tänk på följande kod, som skriver funktionsloggar med hjälp av standardspårningsnivån:

context.log('Node.js HTTP trigger function processed a request. RequestUri=' + req.originalUrl);
context.log('Request Headers = ' + JSON.stringify(req.headers));

Du kan också skriva samma kod i följande format:

context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);
context.log('Request Headers = ', JSON.stringify(req.headers));

Anteckning

Använd inte för console.log att skriva spårningsutdata. Eftersom utdata från fångas på funktionsappnivå är det inte kopplat till ett specifikt funktionsanrop och visas inte i loggarna för console.log en specifik funktion. Dessutom stöder inte version 1.x av Functions-körningen användning för console.log att skriva till konsolen.

Spårningsnivåer

Förutom standardnivån är följande loggningsmetoder tillgängliga som gör att du kan skriva funktionsloggar på specifika spårningsnivåer.

Metod Beskrivning
error(message) Skriver en händelse på felnivå till loggarna.
warn(message) Skriver en händelse på varningsnivå till loggarna.
info(message) Skriver till loggning på informationsnivå eller lägre.
verbose(message) Skriver till utförlig nivåloggning.

I följande exempel skriver samma logg på varningsnivån, i stället för på informationsnivån:

context.log.warn("Something has happened. " + context.invocationId); 

Eftersom felet är den högsta spårningsnivån skrivs den här spårningen till utdata på alla spårningsnivåer så länge loggning är aktiverat.

Konfigurera spårningsnivån för loggning

Med Functions kan du definiera tröskelvärdet för spårningsnivå för skrivning till loggarna eller konsolen. De specifika tröskelvärdesinställningarna beror på din version av Functions-körningen.

Om du vill ange tröskelvärdet för spårningar som skrivs till logging.logLevel loggarna använder du egenskapen i host.jspå filen. Med det här JSON-objektet kan du definiera ett standardtröskelvärde för alla funktioner i funktionsappen, plus att du kan definiera specifika tröskelvärden för enskilda funktioner. Mer information finns i Så här konfigurerar du övervakning för Azure Functions.

Logga anpassad telemetri

Som standard skriver Functions utdata som spårningar till Application Insights. Om du vill ha mer kontroll kan du i stället använda Application Insights Node.js SDK för att skicka anpassade telemetridata till din Application Insights-instans.

const appInsights = require("applicationinsights");
appInsights.setup();
const client = appInsights.defaultClient;

module.exports = function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    // Use this with 'tagOverrides' to correlate custom telemetry to the parent function invocation.
    var operationIdOverride = {"ai.operation.id":context.traceContext.traceparent};

    client.trackEvent({name: "my custom event", tagOverrides:operationIdOverride, properties: {customProperty2: "custom property value"}});
    client.trackException({exception: new Error("handled exceptions can be logged with this method"), tagOverrides:operationIdOverride});
    client.trackMetric({name: "custom metric", value: 3, tagOverrides:operationIdOverride});
    client.trackTrace({message: "trace message", tagOverrides:operationIdOverride});
    client.trackDependency({target:"http://dbname", name:"select customers proc", data:"SELECT * FROM Customers", duration:231, resultCode:0, success: true, dependencyTypeName: "ZSQL", tagOverrides:operationIdOverride});
    client.trackRequest({name:"GET /customers", url:"http://myserver/customers", duration:309, resultCode:200, success:true, tagOverrides:operationIdOverride});

    context.done();
};

Parametern tagOverrides anger operation_Id till funktionens anrops-ID. Med den här inställningen kan du korrelera all automatiskt genererad och anpassad telemetri för ett visst funktionsanrop.

HTTP-utlösare och bindningar

HTTP- och webhook-utlösare och HTTP-utdatabindningar använder begäran- och svarsobjekt för att representera HTTP-meddelanden.

Begär objekt

Objektet context.req (begäran) har följande egenskaper:

Egenskap Beskrivning
Kroppen Ett -objekt som innehåller brödtexten i begäran.
Headers Ett objekt som innehåller begärandehuvudena.
Metod HTTP-metoden för begäran.
originalUrl URL:en för begäran.
Params Ett -objekt som innehåller routningsparametrarna för begäran.
Fråga Ett -objekt som innehåller frågeparametrarna.
rawBody Meddelandets brödtext som en sträng.

Svarsobjekt

-objektet context.res (svar) har följande egenskaper:

Egenskap Beskrivning
Kroppen Ett -objekt som innehåller brödtexten i svaret.
Headers Ett -objekt som innehåller svarshuvudena.
isRaw Anger att formateringen hoppas över för svaret.
Status HTTP-statuskoden för svaret.
Cookies En matris med HTTP-cookieobjekt som anges i svaret. Ett HTTP-cookieobjekt har name egenskaperna , och andra value cookie-egenskaper, till exempel maxAge eller sameSite .

Åtkomst till begäran och svar

När du arbetar med HTTP-utlösare kan du komma åt HTTP-begäran och svarsobjekt på flera olika sätt:

  • Från req res - och -egenskaper för context -objektet. På så sätt kan du använda det konventionella mönstret för att komma åt HTTP-data från kontextobjektet, i stället för att behöva använda det fullständiga context.bindings.name mönstret. I följande exempel visas hur du kommer åt req res objekten och på context :

    // You can access your HTTP request off the context ...
    if(context.req.body.emoji === ':pizza:') context.log('Yay!');
    // and also set your HTTP response
    context.res = { status: 202, body: 'You successfully ordered more coffee!' }; 
    
  • Från de namngivna indata- och utdatabindningarna. På så sätt fungerar HTTP-utlösaren och bindningarna på samma sätt som andra bindningar. I följande exempel anges svarsobjektet med hjälp av en namngiven response bindning:

    {
        "type": "http",
        "direction": "out",
        "name": "response"
    }
    
    context.bindings.response = { status: 201, body: "Insert succeeded." };
    
  • [Endast svar] Genom att anropa context.res.send(body?: any) . Ett HTTP-svar skapas med body indata som svarstext. context.done() anropas implicit.

  • [Endast svar] Genom att anropa context.done() . En särskild typ av HTTP-bindning returnerar svaret som skickas till context.done() metoden . Följande HTTP-utdatabindning definierar en $return utdataparameter:

    {
      "type": "http",
      "direction": "out",
      "name": "$return"
    }
    
     // Define a valid response object.
    res = { status: 201, body: "Insert succeeded." };
    context.done(null, res);   
    

Observera att begäran- och svarsnycklarna är i gemener.

Skalning och samtidighet

Som standard övervakar Azure Functions automatiskt belastningen på ditt program och skapar ytterligare värdinstanser för Node.js efter behov. Functions använder inbyggda (inte användarkonfigurerbara) tröskelvärden för olika utlösartyper för att avgöra när instanser ska läggas till, till exempel ålder på meddelanden och köstorlek för QueueTrigger. Mer information finns i Så här fungerar förbruknings- och Premium planer.

Det här skalningsbeteendet är tillräckligt för många Node.js program. För CPU-bundna program kan du förbättra prestanda ytterligare med hjälp av flera språkarbetare.

Som standard har varje Functions-värdinstans en enda språkarbetareprocess. Du kan öka antalet arbetsprocesser per värd (upp till 10) med hjälp av FUNCTIONS_WORKER_PROCESS_COUNT för program. Azure Functions sedan att jämnt distribuera samtidiga funktionsanrop mellan dessa arbetare.

Den FUNCTIONS_WORKER_PROCESS_COUNT gäller för varje värd som Functions skapar när du skalar ut ditt program för att möta efterfrågan.

Nodversion

I följande tabell visas aktuella Node.js versioner för varje huvudversion av Functions-körningen, efter operativsystem:

Functions-version Nodversion (Windows) Nodversion (Linux)
3.x (rekommenderas) ~14 (rekommenderas)
~12
~10
node|14 (rekommenderas)
node|12
node|10
2.x ~12
~10
~8
node|10
node|8
1.x 6.11.2 (låst av körningen) saknas

Du kan se den aktuella versionen som körningen använder genom att logga process.version från valfri funktion.

Ställa in Node-versionen

För Windows-funktionsappar anger du versionen i Azure som mål genom att ange WEBSITE_NODE_DEFAULT_VERSION appinställningen till en LTS-version som stöds, till exempel ~14 .

För Linux-funktionsappar kör du följande Azure CLI-kommando för att uppdatera Node-versionen.

az functionapp config set --linux-fx-version "node|14" --name "<MY_APP_NAME>" --resource-group "<MY_RESOURCE_GROUP_NAME>"

Beroendehantering

För att kunna använda community-bibliotek i din JavaScript-kod, som visas i exemplet nedan, måste du se till att alla beroenden är installerade på din funktionsapp i Azure.

// Import the underscore.js library
var _ = require('underscore');
var version = process.version; // version === 'v6.5.0'

module.exports = function(context) {
    // Using our imported underscore.js library
    var matched_names = _
        .where(context.bindings.myInput.names, {first: 'Carla'});

Anteckning

Du bör definiera en package.json fil i roten för funktionsappen. Genom att definiera filen kan alla funktioner i appen dela samma cachelagrade paket, vilket ger bästa möjliga prestanda. Om en versionskonflikt uppstår kan du lösa den genom att lägga till package.json en fil i mappen för en specifik funktion.

När du distribuerar funktionsappar från källkontrollen utlöses en i mappen under distributionen av alla filer som finns package.json npm install i din lagringsplatsen. Men när du distribuerar via portalen eller CLI måste du installera paketen manuellt.

Det finns två sätt att installera paket på funktionsappen:

Distribuera med beroenden

  1. Installera alla nödvändiga paket lokalt genom att köra npm install .

  2. Distribuera koden och se till att node_modules mappen ingår i distributionen.

Använda Kudu

  1. Gå till https://<function_app_name>.scm.azurewebsites.net.

  2. Klicka på Cmd för felsökningskonsolen. >

  3. Gå till D:\home\site\wwwroot och dra sedan package.jsfilen till wwwroot-mappen längst upp på sidan.
    Du kan också ladda upp filer till funktionsappen på andra sätt. Mer information finns i Så här uppdaterar du funktionsappfiler.

  4. När filen package.jsfilen har laddats upp kör du kommandot npm install i Kudu-fjärrkörningskonsolen.
    Den här åtgärden laddar ned de paket som anges package.jspå filen och startar om funktionsappen.

Miljövariabler

Lägg till egna miljövariabler i en funktionsapp, både i dina lokala och molnbaserade miljöer, till exempel drifthemligheter (anslutningssträngar, nycklar och slutpunkter) eller miljöinställningar (till exempel profilering av variabler). Få åtkomst till de här inställningarna process.env med hjälp av i funktionskoden.

I lokal utvecklingsmiljö

När du kör lokalt innehåller functions-projektet local.settings.json en -fil, där du lagrar dina miljövariabler i Values -objektet.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "translatorTextEndPoint": "https://api.cognitive.microsofttranslator.com/",
    "translatorTextKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "languageWorkers__node__arguments": "--prof"
  }
}

I Azure-molnmiljö

När du kör i Azure kan du med funktionsappen ange användning av programinställningar, till exempel tjänstanslutningssträngar, och exponera dessa inställningar som miljövariabler under körningen.

Det finns flera sätt att lägga till, uppdatera och ta bort inställningar för funktionsappen:

Ändringar i inställningarna för funktionsappen kräver att funktionsappen startas om.

Komma åt miljövariabler i kod

Få åtkomst till programinställningar som miljövariabler med hjälp av , som visas här i det andra och tredje anropet där vi loggar process.env context.log() AzureWebJobsStorage WEBSITE_SITE_NAME miljövariablerna och :

module.exports = async function (context, myTimer) {

    context.log("AzureWebJobsStorage: " + process.env["AzureWebJobsStorage"]);
    context.log("WEBSITE_SITE_NAME: " + process.env["WEBSITE_SITE_NAME"]);
};

ECMAScript-moduler (förhandsversion)

Anteckning

Eftersom ECMAScript-moduler för närvarande är märkta experimentella i Node.js 14, är de tillgängliga som en förhandsgranskningsfunktion i Node.js 14 Azure Functions. Tills Node.js 14-stöd för ECMAScript-moduler blir stabilt kan du förvänta dig möjliga ändringar av dess API eller beteende.

ECMAScript-moduler (ES-moduler) är det nya officiella standardmodulsystemet för Node.js. Hittills använder kodexe exemplen i den här artikeln CommonJS-syntaxen. När du Azure Functions i Node.js 14 kan du skriva dina funktioner med hjälp av syntaxen för ES-moduler.

Om du vill använda ES-moduler i en funktion ändrar du dess filnamn så att det använder ett .mjs tillägg. Följande index.mjs-filexempel är en HTTP-utlöst funktion som använder syntax för ES-moduler för att importera uuid biblioteket och returnera ett värde.

import { v4 as uuidv4 } from 'uuid';

export default async function (context, req) {
    context.res.body = uuidv4();
};

Konfigurera funktionens startpunkt

Egenskaperna function.json och kan användas för att konfigurera platsen och namnet på den exporterade scriptFile entryPoint funktionen. Dessa egenskaper kan vara viktiga när ditt JavaScript transpileras.

Använda scriptFile

Som standard körs en JavaScript-funktion från index.js , en fil som delar samma överordnade katalog som dess motsvarande function.json .

scriptFile kan användas för att hämta en mappstruktur som ser ut som i följande exempel:

FunctionApp
 | - host.json
 | - myNodeFunction
 | | - function.json
 | - lib
 | | - sayHello.js
 | - node_modules
 | | - ... packages ...
 | - package.json

for function.json ska innehålla en egenskap som pekar på filen med den exporterade funktionen som ska myNodeFunction scriptFile köras.

{
  "scriptFile": "../lib/sayHello.js",
  "bindings": [
    ...
  ]
}

Använda entryPoint

I scriptFile (eller index.js ) måste en funktion exporteras med för module.exports att kunna hittas och köras. Som standard är funktionen som körs när den utlöses den enda exporten från filen, exporten med namnet run eller exporten med namnet index .

Detta kan konfigureras med entryPoint hjälp av i , som i följande function.json exempel:

{
  "entryPoint": "logFoo",
  "bindings": [
    ...
  ]
}

I Functions v2.x, som stöder parametern i this användarfunktioner, kan funktionskoden sedan vara som i följande exempel:

class MyObj {
    constructor() {
        this.foo = 1;
    };

    logFoo(context) { 
        context.log("Foo is " + this.foo); 
        context.done(); 
    }
}

const myObj = new MyObj();
module.exports = myObj;

I det här exemplet är det viktigt att notera att även om ett objekt exporteras så finns det inga garantier för att bevara tillståndet mellan körningar.

Lokal felsökning

När den startas --inspect med parametern lyssnar Node.js en felsökningsklient på den angivna porten. I Azure Functions 2.x kan du ange argument som ska överföras till Node.js som kör koden genom att lägga till miljövariabeln eller appinställningen languageWorkers:node:arguments = <args> .

Om du vill felsöka lokalt lägger du till under ilocal.settings.jspå filen och bifogar en "languageWorkers:node:arguments": "--inspect=5858" Values felsökare till port 5858.

När du felsöker med VS Code läggs parametern automatiskt till med hjälp av värdet i --inspect port projektets launch.jspå filen.

I version 1.x fungerar languageWorkers:node:arguments inte inställningen. Felsökningsporten kan väljas med --nodeDebugPort parametern på Azure Functions Core Tools.

TypeScript

När du använder version 2.x av Functions-körningen kan du skapa funktionsappar med hjälp av både Azure Functions för Visual Studio Code och Azure Functions Core Tools med hjälp av en mall som stöder TypeScript-funktionsappprojekt. Mallen genererar och projektfiler som gör det enklare att samla in, köra och publicera package.json tsconfig.json JavaScript-funktioner från TypeScript-kod med dessa verktyg.

En .funcignore genererad fil används för att ange vilka filer som undantas när ett projekt publiceras till Azure.

TypeScript-filer (.ts) transpileras till JavaScript-filer (.js) i dist utdatakatalogen. TypeScript-mallar använder scriptFile parametern function.json i för att ange platsen för .js-fil i dist mappen. Utdataplatsen anges av mallen med hjälp outDir av parametern i tsconfig.json filen . Om du ändrar den här inställningen eller namnet på mappen kan körningen inte hitta koden som ska köras.

Hur du lokalt utvecklar och distribuerar från ett TypeScript-projekt beror på ditt utvecklingsverktyg.

Visuell Studio-kod

Med Azure Functions för Visual Studio Code kan du utveckla dina funktioner med TypeScript. Core Tools är ett krav för Azure Functions tillägget.

Om du vill skapa en TypeScript-funktionsapp i Visual Studio Code väljer TypeScript du som språk när du skapar en funktionsapp.

När du trycker på F5 för att köra appen lokalt görs transpilering innan värden (func.exe) initieras.

När du distribuerar funktionsappen till Azure med hjälp av knappen Distribuera till funktionsapp... genererar Azure Functions-tillägget först en produktionsklar version av JavaScript-filer från TypeScript-källfilerna.

Azure Functions Core Tools

Det finns flera sätt på vilka ett TypeScript-projekt skiljer sig från ett JavaScript-projekt när du använder Core Tools.

Skapa projekt

Om du vill skapa ett TypeScript-funktionsappprojekt med Core Tools måste du ange språkalternativet TypeScript när du skapar funktionsappen. Du kan göra detta på något av följande sätt:

  • Kör func init kommandot, välj node som språkstack och välj sedan typescript .

  • Kör kommandot func init --worker-runtime typescript.

Kör lokalt

Om du vill köra funktionsappens kod lokalt med hjälp av Core Tools använder du följande kommandon i stället för func host start :

npm install
npm start

Kommandot npm start motsvarar följande kommandon:

  • npm run build
  • func extensions install
  • tsc
  • func start

Publicera till Azure

Innan du använder kommandot för att distribuera till Azure skapar du en produktionsklar version av [func azure functionapp publish] JavaScript-filer från TypeScript-källfilerna.

Följande kommandon förbereder och publicerar TypeScript-projektet med Core Tools:

npm run build:production 
func azure functionapp publish <APP_NAME>

I det här kommandot <APP_NAME> ersätter du med namnet på funktionsappen.

Överväganden för JavaScript-funktioner

När du arbetar med JavaScript-funktioner bör du vara medveten om övervägandena i följande avsnitt.

Välj App Service enskild vCPU

När du skapar en funktionsapp som använder App Service plan rekommenderar vi att du väljer en plan för en enskild vCPU i stället för en plan med flera virtuella processorer. I dag kör Functions JavaScript-funktioner mer effektivt på virtuella datorer med en enskild vCPU och större virtuella datorer ger inte förväntade prestandaförbättringar. Om det behövs kan du manuellt skala ut genom att lägga till fler instanser av virtuella datorer med en enskild virtuell processor, eller så kan du aktivera autoskalning. Mer information finns i Skala antalet instanser manuellt eller automatiskt.

Kallstart

När du Azure Functions i den serverlösa värdmodellen är kallstarter en verklighet. Kallstart syftar på det faktum att det tar längre tid att starta när funktionsappen startar första gången efter en period av inaktivitet. För JavaScript-funktioner med särskilt stora beroendeträd kan kallstart vara betydande. Kör dina funktioner som en paketfil när det är möjligt för att påskynda kallstartsprocessen. Många distributionsmetoder använder körningen från paketmodellen som standard, men om du har stora kallstarter och inte körs på det här sättet kan den här ändringen erbjuda en betydande förbättring.

Anslutningsgränser

När du använder en tjänstspecifik klient i ett Azure Functions ska du inte skapa en ny klient med varje funktionsanrop. Skapa i stället en enda statisk klient i det globala omfånget. Mer information finns i Hantera anslutningar i Azure Functions.

Använd async och await

När du Azure Functions i JavaScript bör du skriva kod med async await nyckelorden och . Genom att skriva kod async med och i stället för await återanrop eller .then och med Promises kan du undvika två vanliga .catch problem:

  • Utlösa undantag utan fel som kraschar Node.js,vilket kan påverka körningen av andra funktioner.
  • Oväntat beteende, till exempel saknade loggar från context.log, som orsakas av asynkrona anrop som inte väntar korrekt.

I exemplet nedan anropas den asynkrona metoden med fs.readFile en fel-första återanropsfunktion som den andra parametern. Den här koden orsakar båda problemen som nämns ovan. Ett undantag som inte uttryckligen fångas in i rätt omfång kraschade hela processen (problemet #1). Anrop utanför omfånget för återanropsfunktionen innebär att funktionsanropet kan avslutas innan filen läses context.done() (problemet #2). I det här exemplet resulterar context.done() anropet för tidigt i att loggposter som börjar med Data from file: saknas.

// NOT RECOMMENDED PATTERN
const fs = require('fs');

module.exports = function (context) {
    fs.readFile('./hello.txt', (err, data) => {
        if (err) {
            context.log.error('ERROR', err);
            // BUG #1: This will result in an uncaught exception that crashes the entire process
            throw err;
        }
        context.log(`Data from file: ${data}`);
        // context.done() should be called here
    });
    // BUG #2: Data is not guaranteed to be read before the Azure Function's invocation ends
    context.done();
}

Med async await nyckelorden och kan du undvika båda dessa fel. Du bör använda Node.js för att omvandla util.promisify funktionerna i fel-första återanropsformat till inväntande funktioner.

I exemplet nedan misslyckas alla ohanterade undantag som utlöses under funktionskörningen endast det enskilda anrop som utlöste ett undantag. Nyckelordet await innebär att steg som följer endast körs när har readFileAsync readFile slutförts. Med async await och behöver du inte heller anropa context.done() motringning.

// Recommended pattern
const fs = require('fs');
const util = require('util');
const readFileAsync = util.promisify(fs.readFile);

module.exports = async function (context) {
    let data;
    try {
        data = await readFileAsync('./hello.txt');
    } catch (err) {
        context.log.error('ERROR', err);
        // This rethrown exception will be handled by the Functions Runtime and will only fail the individual invocation
        throw err;
    }
    context.log(`Data from file: ${data}`);
}

Nästa steg

Mer information finns i följande resurser: