Azure Functions JavaScript 開發人員指南Azure Functions JavaScript developer guide

本指南包含使用 JavaScript 撰寫 Azure Functions 的複雜性相關資訊。This guide contains information about the intricacies of writing Azure Functions with JavaScript.

JavaScript 函式是匯出的 function,會在觸發時執行 (觸發程序是在 function.json 中設定)。A JavaScript function is an exported function that executes when triggered (triggers are configured in function.json). 傳遞至每個函式的第一個context引數是物件, 用來接收和傳送系結資料、記錄, 以及與執行時間通訊。The first argument passed to every function is a context object, which is used for receiving and sending binding data, logging, and communicating with the runtime.

本文假設您已經讀過 Azure Functions 開發人員參考This article assumes that you have already read the Azure Functions developer reference. 完成函數快速入門, 以使用Visual Studio Code在入口網站中建立您的第一個函式。Complete the Functions quickstart to create your first function, using Visual Studio Code or in the portal.

本文也支援TypeScript 應用程式開發This article also supports TypeScript app development.

資料夾結構Folder structure

JavaScript 專案的必要資料夾結構如下所示。The required folder structure for a JavaScript project looks like the following. 此預設值可以變更。This default can be changed. 如需詳細資訊,請參閱下面的 scriptFile 一節。For more information, see the scriptFile section below.

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

在專案根目錄中,有共用的 host.json 檔案可用來設定函式應用程式。At the root of the project, there's a shared host.json file that can be used to configure the function app. 每個函式都有本身程式碼檔案 (.js) 和繫結設定檔 (function.json) 的資料夾。Each function has a folder with its own code file (.js) and binding configuration file (function.json). function.json 的父目錄名稱一律是函式的名稱。The name of function.json's parent directory is always the name of your function.

在函式執行階段的版本 2.x 中所需的繫結擴充功能,是以 bin 資料夾中的實際程式庫檔案在 extensions.csproj 檔案中所定義。The binding extensions required in version 2.x of the Functions runtime are defined in the extensions.csproj file, with the actual library files in the bin folder. 在本機開發時,您必須註冊繫結擴充功能When developing locally, you must register binding extensions. 開發 Azure 入口網站中的函式時,就會為您完成這項註冊。When developing functions in the Azure portal, this registration is done for you.

匯出函數Exporting a function

JavaScript 函式必須透過 module.exports (或 exports) 匯出。JavaScript functions must be exported via module.exports (or exports). 您匯出的函式應該是可經觸發而執行的 JavaScript 函式。Your exported function should be a JavaScript function that executes when triggered.

根據預設,Functions 執行階段會在 index.js 中尋找您的函式,其中 index.js 與對應的 function.json 會共用相同的父目錄。By default, the Functions runtime looks for your function in index.js, where index.js shares the same parent directory as its corresponding function.json. 在預設情況中,您匯出的函式應該是僅來自其檔案的匯出,或是名為 runindex 的匯出。In the default case, your exported function should be the only export from its file or the export named run or index. 若要設定檔案位置,並匯出函式的名稱,請參閱以下的設定您的函式進入點To configure the file location and export name of your function, read about configuring your function's entry point below.

您匯出的函式在執行時,會傳入多個引數。Your exported function is passed a number of arguments on execution. 它所採用的第一個引數一律為 context 物件。The first argument it takes is always a context object. 如果您的函式是同步的 (不會傳回承諾), 您context必須傳遞物件, context.done因為需要呼叫才可正確使用。If your function is synchronous (doesn't return a Promise), you must pass the context object, as calling context.done is required for correct use.

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

匯出非同步函式Exporting an async function

在 2.x 版的 Functions 執行階段中使用 async function 宣告或純 JavaScript Promises 時,您不需要明確呼叫 context.done 回呼以表明函式已完成。When using the async function declaration or plain JavaScript Promises in version 2.x of the Functions runtime, you do not need to explicitly call the context.done callback to signal that your function has completed. 在匯出的非同步函式/Promise 完成時,函式便會完成。Your function completes when the exported async function/Promise completes. 針對以 1.x 版的執行階段為目標的函式,您仍須在程式碼執行完成時呼叫 context.doneFor functions targeting the version 1.x runtime, you must still call context.done when your code is done executing.

下列範例說明的簡單函式會記錄其已遭到觸發,並立即完成執行。The following example is a simple function that logs that it was triggered and immediately completes execution.

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

在匯出非同步函式時,您也可以將輸出繫結設定為採用 return 值。When exporting an async function, you can also configure an output binding to take the return value. 如果您只有一個輸出繫結,建議使用此方式。This is recommended if you only have one output binding.

若要使用 return 來指派輸出,請在 function.json 中將 name 屬性變更為 $returnTo assign an output using return, change the name property to $return in function.json.

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

在此情況下,您的函式會如下列範例所示:In this case, your function should look like the following example:

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!"
    };
}

繫結Bindings

在 JavaScript 中,繫結會設定並定義於函式的 function.json 中。In JavaScript, bindings are configured and defined in a function's function.json. Functions 會透過數種方式與繫結互動。Functions interact with bindings a number of ways.

輸入Inputs

在 Azure Functions 中輸入會分成兩個類別:一個是觸發程序輸入,另一個是額外的輸入。Input are divided into two categories in Azure Functions: one is the trigger input and the other is the additional input. 函式可透過三種方式讀取觸發程序和其他輸入繫結 (direction === "in" 的繫結):Trigger and other input bindings (bindings of direction === "in") can be read by a function in three ways:

  • [建議] 作為參數傳至您的函式。[Recommended] As parameters passed to your function. 這些繫結會按照在 function.json 中定義的順序傳遞至函式。They are passed to the function in the same order that they are defined in function.json. name函式中定義的屬性不需要符合您的參數名稱, 但它應該是。The name property defined in function.json does not need to match the name of your parameter, although it should.

    module.exports = async function(context, myTrigger, myInput, myOtherInput) { ... };
    
  • 作為 context.bindings 物件的成員。As members of the context.bindings object. 每個成員都會由 function.json 中定義的 name 屬性命名。Each member is named by the name property defined in function.json.

    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);
    };
    
  • 使用 JavaScript arguments 物件作為輸入。As inputs using the JavaScript arguments object. 這基本上相當於將輸入傳入作為參數,但可讓您以動態方式處理輸入。This is essentially the same as passing inputs as parameters, but allows you to dynamically handle inputs.

    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]);
    };
    

outputsOutputs

函式可透過數種方式寫入輸出 (direction === "out" 的繫結)。Outputs (bindings of direction === "out") can be written to by a function in a number of ways. 在所有情況下,在 function.json 中為繫結定義的 name 屬性都會對應至在您的函式中寫入的物件成員名稱。In all cases, the name property of the binding as defined in function.json corresponds to the name of the object member written to in your function.

您可以用下列其中一種方式將資料指派給輸出系結 (請勿結合這些方法):You can assign data to output bindings in one of the following ways (don't combine these methods):

  • [建議用於多個輸出] 傳回物件。[Recommended for multiple outputs] Returning an object. 如果您使用的是非同步/承諾傳回函式, 您可以傳回具有指派之輸出資料的物件。If you are using an async/Promise returning function, you can return an object with assigned output data. 在下列範例中,輸出繫結在 function.json 中會命名為 "httpResponse" 和 "queueOutput"。In the example below, the output bindings are named "httpResponse" and "queueOutput" in function.json.

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

    如果您使用同步函式,則可以使用 context.done 傳回此物件 (請參閱範例)。If you are using a synchronous function, you can return this object using context.done (see example).

  • [建議用於單一輸出] 直接傳回值並使用 $return 繫結名稱。[Recommended for single output] Returning a value directly and using the $return binding name. 這僅適用於非同步/Promise 傳回函式。This only works for async/Promise returning functions. 請參閱匯出非同步函式中的範例。See example in exporting an async function.

  • 將值指派給 context.bindings 您可以直接將值指派給 context.bindings。Assigning values to context.bindings You can assign values directly to context.bindings.

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

繫結資料類型Bindings data type

若要定義輸入繫結的資料類型,請使用繫結定義中的 dataType 屬性。To define the data type for an input binding, use the dataType property in the binding definition. 例如,若要以二進位格式讀取 HTTP 要求的內容,請使用類型 binaryFor example, to read the content of an HTTP request in binary format, use the type binary:

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

dataType 的選項是:binarystreamstringOptions for dataType are: binary, stream, and string.

context 物件context object

執行階段使用 context 物件來將資料傳遞至函式並從中傳出,而且可讓您與執行階段進行通訊。The runtime uses a context object to pass data to and from your function and to let you communicate with the runtime. 如果您匯出的函式是同步的,內容物件可用來讀取和設定繫結中的資料、寫入記錄,以及使用 context.done 回呼。The context object can be used for reading and setting data from bindings, writing logs, and using the context.done callback when your exported function is synchronous.

context 物件一律為函式的第一個參數。The context object is always the first parameter to a function. 它具有重要的方法 (像是 context.donecontext.log),因此應納入。It should be included because it has important methods such as context.done and context.log. 您可以任意方式命名物件 (例如 ctxc)。You can name the object whatever you would like (for example, ctx or c).

// You must include a context, but other arguments are optional
module.exports = function(ctx) {
    // function logic goes here :)
    ctx.done();
};

context.bindings 屬性context.bindings property

context.bindings

傳回用來讀取或指派系結資料的已命名物件。Returns a named object that is used to read or assign binding data. 您可以藉由讀取的屬性context.bindings來存取輸入和觸發程式系結資料。Input and trigger binding data can be accessed by reading properties on context.bindings. 輸出系結資料可以藉由將資料加入至來指派context.bindingsOutput binding data can be assigned by adding data to context.bindings

例如,function.json 中的下列繫結定義可讓您使用 context.bindings.myOutputcontext.bindings.myInput 存取佇列的內容並且將輸出指派到佇列。For example, the following binding definitions in your function.json let you access the contents of a queue from context.bindings.myInput and assign outputs to a queue using 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 };

您可以使用 context.done 方法選擇定義輸出繫結資料,而不使用 context.binding 物件 (如下所示)。You can choose to define output binding data using the context.done method instead of the context.binding object (see below).

context.bindingData 屬性context.bindingData property

context.bindingData

傳回包含觸發程序中繼資料和函式引動過程資料的具名物件 (invocationIdsys.methodNamesys.utcNowsys.randGuid)。Returns a named object that contains trigger metadata and function invocation data (invocationId, sys.methodName, sys.utcNow, sys.randGuid). 如需觸發程序中繼資料的範例,請參閱此事件中樞範例For an example of trigger metadata, see this event hubs example.

context.done 方法context.done method

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

通知執行階段您的程式碼已完成。Lets the runtime know that your code has completed. 如果您的函式使用 async function 宣告,您就不需要使用 context.done()When your function uses the async function declaration, you do not need to use context.done(). 隱含地呼叫 context.done 回呼。The context.done callback is implicitly called. 非同步函式可在 Node 8 或更新版本中使用,而這需要 2.x 版的 Functions 執行階段。Async functions are available in Node 8 or a later version, which requires version 2.x of the Functions runtime.

如果您的函式不是非同步函式,您必須呼叫 context.done 來通知執行階段您的函式已完成。If your function is not an async function, you must call context.done to inform the runtime that your function is complete. 如果沒有,執行將會逾時。The execution times out if it is missing.

context.done 方法可讓您將使用者定義的錯誤傳回到執行階段,並傳回包含輸出繫結資料的 JSON 物件。The context.done method allows you to pass back both a user-defined error to the runtime and a JSON object containing output binding data. 傳至 context.done 的屬性會覆寫 context.bindings 物件上設定的任何屬性。Properties passed to context.done overwrite anything set on the context.bindings object.

// 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 方法context.log method

context.log(message)

可讓您寫入預設追蹤層級的資料流函式記錄。Allows you to write to the streaming function logs at the default trace level. context.log 上有其他可用的記錄方法,可讓您在其他追蹤層級寫入函式記錄︰On context.log, additional logging methods are available that let you write function logs at other trace levels:

方法Method 描述Description
error(message)error(message) 寫入錯誤層級或更低層級的記錄。Writes to error level logging, or lower.
warn(message)warn(message) 寫入警告層級或更低層級的記錄。Writes to warning level logging, or lower.
info(message)info(message) 寫入資訊層級或更低層級的記錄。Writes to info level logging, or lower.
verbose(message)verbose(message) 寫入詳細資訊層級記錄。Writes to verbose level logging.

下列範例會依警告追蹤層級寫入記錄︰The following example writes a log at the warning trace level:

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

您可以在 host.json 檔案中設定用於記錄的追蹤層級閾值You can configure the trace-level threshold for logging in the host.json file. 如需寫入記錄的詳細資訊,請參閱以下的寫入追蹤輸出For more information on writing logs, see writing trace outputs below.

參閱監視 Azure Functions 深入了解如何檢視和查詢函式記錄。Read monitoring Azure Functions to learn more about viewing and querying function logs.

將追蹤輸出寫入主控台中Writing trace output to the console

在 Functions 中,您可以使用 context.log 方法,將追蹤輸出寫入主控台中。In Functions, you use the context.log methods to write trace output to the console. 在 Functions v2.x 中,會在函式應用程式層級擷取使用 console.log 的追蹤輸出。In Functions v2.x, trace outputs using console.log are captured at the Function App level. 這表示來自console.log的輸出不會系結至特定的函式調用, 也不會顯示在特定函式的記錄中。This means that outputs from console.log are not tied to a specific function invocation and aren't displayed in a specific function's logs. 不過,這些輸出會傳播至 Application Insights。They do, however, propagate to Application Insights. 在 Functions v1.x 中,您不能使用 console.log 來寫入主控台中。In Functions v1.x, you cannot use console.log to write to the console.

當您呼叫 context.log() 時,會在預設追蹤層級 (也就是「資訊」追蹤層級) 將您的訊息寫入主控台中。When you call context.log(), your message is written to the console at the default trace level, which is the info trace level. 下列程式碼會依資訊追蹤層級寫入主控台中︰The following code writes to the console at the info trace level:

context.log({hello: 'world'});  

此程式碼相當於上述程式碼:This code is equivalent to the code above:

context.log.info({hello: 'world'});  

此程式碼會依錯誤層級寫入主控台中︰This code writes to the console at the error level:

context.log.error("An error has occurred.");  

因為 error 是最高追蹤層級,所以只要啟用記錄,這項追蹤就會寫入所有追蹤層級的輸出。Because error is the highest trace level, this trace is written to the output at all trace levels as long as logging is enabled.

所有 context.log 方法都與 Node.js util.format 方法 (英文) 支援相同的參數格式。All context.log methods support the same parameter format that's supported by the Node.js util.format method. 請考慮下列程式碼,它會使用預設追蹤層級寫入函式記錄︰Consider the following code, which writes function logs by using the default trace level:

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

您也能以下列格式撰寫相同的程式碼:You can also write the same code in the following format:

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

設定用於主控台記錄的追蹤層級Configure the trace level for console logging

Functions 1.x 讓您定義寫入至主控台的閾值追蹤層級,這可讓您輕鬆地控制追蹤從函式寫入主控台的方式。Functions 1.x lets you define the threshold trace level for writing to the console, which makes it easy to control the way traces are written to the console from your function. 若要設定寫入至主控台之所有追蹤的閾值,請使用 host.json 檔案中的 tracing.consoleLevel 屬性。To set the threshold for all traces written to the console, use the tracing.consoleLevel property in the host.json file. 這個設定會套用到函式應用程式中的所有函式。This setting applies to all functions in your function app. 下列範例會設定追蹤閾值來啟用詳細資訊記錄︰The following example sets the trace threshold to enable verbose logging:

{
    "tracing": {
        "consoleLevel": "verbose"
    }
}  

consoleLevel 的值對應至 context.log 方法的名稱。Values of consoleLevel correspond to the names of the context.log methods. 若要停用主控台的所有追蹤記錄,請將 consoleLevel 設為 offTo disable all trace logging to the console, set consoleLevel to off. 如需詳細資訊,請參閱 host.json 參考For more information, see host.json reference.

HTTP 觸發程序和繫結HTTP triggers and bindings

HTTP 和 Webhook 觸發程序以及 HTTP 輸出繫結會使用要求和回應物件來代表 HTTP 傳訊。HTTP and webhook triggers and HTTP output bindings use request and response objects to represent the HTTP messaging.

要求物件Request object

context.req (要求) 物件具有下列屬性:The context.req (request) object has the following properties:

屬性Property 描述Description
bodybody 包含要求本文的物件。An object that contains the body of the request.
headersheaders 包含要求標頭的物件。An object that contains the request headers.
methodmethod 要求的 HTTP 方法。The HTTP method of the request.
originalUrloriginalUrl 要求的 URL。The URL of the request.
paramsparams 包含要求之路由傳送參數的物件。An object that contains the routing parameters of the request.
queryquery 包含查詢參數的物件。An object that contains the query parameters.
rawBodyrawBody 字串格式的訊息內文。The body of the message as a string.

回應物件Response object

context.res (回應) 物件具有下列屬性:The context.res (response) object has the following properties:

屬性Property 描述Description
bodybody 包含回應本文的物件。An object that contains the body of the response.
headersheaders 包含回應標頭的物件。An object that contains the response headers.
isRawisRaw 表示略過回應的格式。Indicates that formatting is skipped for the response.
statusstatus 回應的 HTTP 狀態碼。The HTTP status code of the response.

存取要求和回應Accessing the request and response

使用 HTTP 觸發程序時,您可以使用許多方式來存取 HTTP 要求和回應物件︰When you work with HTTP triggers, you can access the HTTP request and response objects in a number of ways:

  • context 物件的 reqres 屬性中。From req and res properties on the context object. 如此一來,您可以使用傳統模式來存取內容物件中的 HTTP 資料,而不需使用完整 context.bindings.name 模式。In this way, you can use the conventional pattern to access HTTP data from the context object, instead of having to use the full context.bindings.name pattern. 下列範例示範如何存取 context 上的 reqres 物件:The following example shows how to access the req and res objects on the 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!' }; 
    
  • 從具名輸入和輸出繫結。From the named input and output bindings. 如此一來,HTTP 觸發程序和繫結的運作方式會與任何其他繫結相同。In this way, the HTTP trigger and bindings work the same as any other binding. 下列範例會使用具名 response 繫結來設定回應物件:The following example sets the response object by using a named response binding:

    {
        "type": "http",
        "direction": "out",
        "name": "response"
    }
    
    context.bindings.response = { status: 201, body: "Insert succeeded." };
    
  • [僅回應] 藉由呼叫 context.res.send(body?: any)[Response only] By calling context.res.send(body?: any). HTTP 回應是以做為回應主體的輸入 body 所建立。An HTTP response is created with input body as the response body. 隱含地呼叫 context.done()context.done() is implicitly called.

  • [僅回應] 藉由呼叫 context.done()[Response only] By calling context.done(). 一種特殊類型的 HTTP 系結會傳回傳遞至context.done()方法的回應。A special type of HTTP binding returns the response that is passed to the context.done() method. 下列 HTTP 輸出繫結定義 $return 輸出參數︰The following HTTP output binding defines a $return output parameter:

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

節點版本Node version

下表顯示 Functions 執行階段每個主要版本所使用的 Node.js 版本:The following table shows the Node.js version used by each major version of the Functions runtime:

Functions 版本Functions version Node.js 版本Node.js version
1.x1.x 6.11.2 (由執行階段鎖定)6.11.2 (locked by the runtime)
2.x2.x ACTIVE LTS AND_維護 LTS_ node.js 版本 (建議使用建議使用8.11.1 和 10.14.1)。Active LTS and Maintenance LTS Node.js versions (8.11.1 and 10.14.1 recommended). 使用 WEBSITE_NODE_DEFAULT_VERSION 應用程式設定來設定版本。Set the version by using the WEBSITE_NODE_DEFAULT_VERSION app setting.

您可以藉由檢查以上的應用程式設定,或藉由從任何函式列印 process.version,來查看執行階段目前正在使用的版本。You can see the current version that the runtime is using by checking the above app setting or by printing process.version from any function.

相依性管理Dependency management

若要使用 JavaScript 程式碼中的社群程式庫,如下列範例所示,您必須確定已在 Azure 中的函數應用程式上安裝所有的相依性。In order to use community libraries in your JavaScript code, as is shown in the below example, you need to ensure that all dependencies are installed on your Function App in 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'});

注意

您應該定義函式應用程式根目錄的 package.json 檔案。You should define a package.json file at the root of your Function App. 定義檔案可讓應用程式中的所有函式共用相同的快取套件,以提供最佳效能。Defining the file lets all functions in the app share the same cached packages, which gives the best performance. 發生版本衝突時,您可以在特定函式的資料夾中新增 package.json 檔案來解決它。If a version conflict arises, you can resolve it by adding a package.json file in the folder of a specific function.

從原始檔控制部署函式應用程式時,存在於存放庫中的任何 package.json 檔案,都會在部署期間觸發其資料夾中的 npm installWhen deploying Function Apps from source control, any package.json file present in your repo, will trigger an npm install in its folder during deployment. 但是,在透過入口網站或 CLI 部署時,您就必須手動安裝套件。But when deploying via the Portal or CLI, you will have to manually install the packages.

有兩種方式可在您的函數應用程式上安裝套件:There are two ways to install packages on your Function App:

使用相依性進行部署Deploying with Dependencies

  1. 執行 npm install 在本機安裝所有必要的套件。Install all requisite packages locally by running npm install.

  2. 部署您的程式碼,並確定 node_modules 資料夾包含在部署中。Deploy your code, and ensure that the node_modules folder is included in the deployment.

使用 KuduUsing Kudu

  1. 移至 https://<function_app_name>.scm.azurewebsites.netGo to https://<function_app_name>.scm.azurewebsites.net.

  2. 按一下 [偵錯主控台] > [CMD]。Click Debug Console > CMD.

  3. 移至 D:\home\site\wwwroot,然後將 package.json 檔案拖曳至頁面上半部的 wwwroot 資料夾。Go to D:\home\site\wwwroot, and then drag your package.json file to the wwwroot folder at the top half of the page.
    您也可以使用其他方法將檔案上傳至函數應用程式。You can upload files to your function app in other ways also. 如需詳細資訊,請參閱如何更新函式應用程式檔案For more information, see How to update function app files.

  4. 上傳 package.json 檔案之後,請在 Kudu 遠端執行主控台中執行 npm install 命令。After the package.json file is uploaded, run the npm install command in the Kudu remote execution console.
    此動作會下載 package.json 檔案中指出的套件,並重新啟動函數應用程式。This action downloads the packages indicated in the package.json file and restarts the function app.

環境變數Environment variables

在 Functions 中,應用程式設定 (例如服務連接字串) 在執行期間會公開為環境變數。In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. process.env可以使用來存取這些設定, 如下所示, 在第二個和context.log()第三個呼叫AzureWebJobsStorageWEBSITE_SITE_NAME , 我們會在其中記錄和環境變數:You can access these settings using process.env, as shown here in the second and third calls to context.log() where we log the AzureWebJobsStorage and WEBSITE_SITE_NAME environment variables:

module.exports = async function (context, myTimer) {
    var timeStamp = new Date().toISOString();

    context.log('Node.js timer trigger function ran!', timeStamp);
    context.log("AzureWebJobsStorage: " + process.env["AzureWebJobsStorage"]);
    context.log("WEBSITE_SITE_NAME: " + process.env["WEBSITE_SITE_NAME"]);
};

有數種方式可供您新增、更新和刪除函式應用程式設定:There are several ways that you can add, update, and delete function app settings:

在本機執行時,應用程式設定會讀取自 local.settings.json 專案檔。When running locally, app settings are read from the local.settings.json project file.

設定函式進入點Configure function entry point

function.json 屬性 scriptFileentryPoint 可用來對於匯出的函式設定位置和名稱。The function.json properties scriptFile and entryPoint can be used to configure the location and name of your exported function. 如果已轉換 JavaScript,這些屬性就可能有其重要性。These properties can be important when your JavaScript is transpiled.

使用 scriptFileUsing scriptFile

預設會從 index.js 執行 JavaScript 函式,這是與對應的 function.json 共用相同父目錄的檔案。By default, a JavaScript function is executed from index.js, a file that shares the same parent directory as its corresponding function.json.

scriptFile 可用來取得如下列範例所示的資料夾結構:scriptFile can be used to get a folder structure that looks like the following example:

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

myNodeFunctionfunction.json 應該包含 scriptFile 屬性,這個屬性指向有匯出的函式要執行的檔案。The function.json for myNodeFunction should include a scriptFile property pointing to the file with the exported function to run.

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

使用 entryPointUsing entryPoint

scriptFile (或 index.js) 中,必須使用 module.exports 匯出函式,才能找到並執行該函式。In scriptFile (or index.js), a function must be exported using module.exports in order to be found and run. 觸發時執行的函式預設是僅來自該檔案的匯出,名為 run 的匯出,或名為 index 的匯出。By default, the function that executes when triggered is the only export from that file, the export named run, or the export named index.

這可以在 function.json 中使用 entryPoint 設定,如下列範例所示:This can be configured using entryPoint in function.json, as in the following example:

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

在 Functions v2.x (在使用者函式中支援 this 參數) 中,函式程式碼則可能如下列範例所示:In Functions v2.x, which supports the this parameter in user functions, the function code could then be as in the following example:

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

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

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

在此範例中, 請務必注意, 雖然正在匯出物件, 但不保證會在執行之間保留狀態。In this example, it is important to note that although an object is being exported, there are no guarantees for preserving state between executions.

本機調試Local Debugging

--inspect參數啟動時, node.js 進程會在指定的埠上接聽偵錯工具用戶端。When started with the --inspect parameter, a Node.js process listens for a debugging client on the specified port. 在 Azure Functions 2.x 中, 您可以指定引數來傳入 node.js 進程, 藉由新增環境變數或應用程式設定languageWorkers:node:arguments = <args>來執行程式碼。In Azure Functions 2.x, you can specify arguments to pass into the Node.js process that runs your code by adding the environment variable or App Setting languageWorkers:node:arguments = <args>.

若要在本機進行"languageWorkers:node:arguments": "--inspect=5858"調試Values , 請在您的本機. settings. json檔案中新增, 並將偵錯工具附加至埠5858。To debug locally, add "languageWorkers:node:arguments": "--inspect=5858" under Values in your local.settings.json file and attach a debugger to port 5858.

使用 VS Code 進行偵錯工具時--inspect , 會使用專案的啟動port json 檔案中的值, 自動新增參數。When debugging using VS Code, the --inspect parameter is automatically added using the port value in the project's launch.json file.

在1.x 版中, 設定languageWorkers:node:arguments將無法使用。In version 1.x, setting languageWorkers:node:arguments will not work. 您可以在 Azure Functions Core Tools 上, 使用--nodeDebugPort參數來選取 debug 埠。The debug port can be selected with the --nodeDebugPort parameter on Azure Functions Core Tools.

TypeScriptTypeScript

當您以2.x 版的函式執行時間為目標時, Visual Studio Code 和Azure Functions Core ToolsAzure Functions都可讓您使用支援 TypeScript 函數應用程式專案的範本來建立函數應用程式。When you target version 2.x of the Functions runtime, both Azure Functions for Visual Studio Code and the Azure Functions Core Tools let you create function apps using a template that support TypeScript function app projects. 範本會產生package.jsontsconfig.json專案檔, 讓您可以使用這些工具, 輕鬆地從 TypeScript 程式碼轉換、執行及發佈 JavaScript 函式。The template generates package.json and tsconfig.json project files that make it easier to transpile, run, and publish JavaScript functions from TypeScript code with these tools.

產生.funcignore的檔案是用來指出當專案發行至 Azure 時要排除的檔案。A generated .funcignore file is used to indicate which files are excluded when a project is published to Azure.

TypeScript 檔案 (. ts) 會轉換至輸出目錄中的dist JavaScript 檔案 (.js)。TypeScript files (.ts) are transpiled into JavaScript files (.js) in the dist output directory. TypeScript 範本使用中function.json scriptFile參數來表示dist資料夾中對應 .js 檔案的位置。TypeScript templates use the scriptFile parameter in function.json to indicate the location of the corresponding .js file in the dist folder. 輸出位置是由範本使用outDir檔案tsconfig.json中的參數來設定。The output location is set by the template by using outDir parameter in the tsconfig.json file. 如果您變更此設定或資料夾的名稱, 執行時間就無法找到要執行的程式碼。If you change this setting or the name of the folder, the runtime is not able to find the code to run.

注意

TypeScript 的實驗性支援已存在版本1.x 的函式執行時間。Experimental support for TypeScript exists version 1.x of the Functions runtime. 當叫用函式時, 實驗版本會將 TypeScript 檔案 transpiles 至 JavaScript 檔案。The experimental version transpiles TypeScript files into JavaScript files when the function is invoked. 在2.x 版中, 這個實驗性支援已由工具驅動的方法所取代, 此方法會在主控制項初始化之前, 以及在部署過程中進行轉譯。In version 2.x, this experimental support has been superseded by the tool-driven method that does transpilation before the host is initialized and during the deployment process.

您在本機開發和部署 TypeScript 專案的方式, 取決於您的開發工具。The way that you locally develop and deploy from a TypeScript project depends on your development tool.

Visual Studio CodeVisual Studio Code

Visual Studio Code 擴充功能的Azure Functions可讓您使用 TypeScript 開發函式。The Azure Functions for Visual Studio Code extension lets you develop your functions using TypeScript. 核心工具是 Azure Functions 延伸模組的需求。The Core Tools is a requirement of the Azure Functions extension.

若要在 Visual Studio Code 中建立 TypeScript 函數應用程式TypeScript , 請在建立函數應用程式時選擇您的語言。To create a TypeScript function app in Visual Studio Code, choose TypeScript as your language when you create a function app.

當您按F5在本機執行應用程式時, 轉譯會在主機 (func) 初始化之前完成。When you press F5 to run the app locally, transpilation is done before the host (func.exe) is initialized.

當您使用 [部署至函式應用程式 ... ] 按鈕將函式應用程式部署到 Azure 時, Azure Functions 延伸模組會先從 TypeScript 來源檔案產生已準備好用於生產環境的 JavaScript 檔案組建。When you deploy your function app to Azure using the Deploy to function app... button, the Azure Functions extension first generates a production-ready build of JavaScript files from the TypeScript source files.

Azure Functions Core ToolsAzure Functions Core Tools

在使用核心工具時, TypeScript 專案與 JavaScript 專案的差異有好幾種。There are several ways in which a TypeScript project differs from a JavaScript project when using the Core Tools.

建立專案Create project

若要使用 Core Tools 建立 TypeScript 函數應用程式專案, 您必須在建立函數應用程式時指定 TypeScript 語言選項。To create a TypeScript function app project using Core Tools, you must specify the TypeScript language option when you create your function app. 您可以透過下列其中一種方式來執行這項操作:You can do this in one of the following ways:

  • 執行命令, 選取node作為語言堆疊, 然後選取typescriptfunc initRun the func init command, select node as your language stack, and then select typescript.

  • 執行 func init --worker-runtime typescript 命令。Run the func init --worker-runtime typescript command.

執行本機Run local

若要使用核心工具在本機執行函式應用程式程式碼, 請使用func host start下列命令, 而不是:To run your function app code locally using Core Tools, use the following commands instead of func host start:

npm install
npm start

npm start命令相當於下列命令:The npm start command is equivalent to the following commands:

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

發行至 AzurePublish to Azure

使用func azure functionapp publish命令部署至 Azure 之前, 您可以從 TypeScript 來源檔案建立已準備好用於生產環境的 JavaScript 檔案組建。Before you use the func azure functionapp publish command to deploy to Azure, you create a production-ready build of JavaScript files from the TypeScript source files.

下列命令會使用 Core Tools 來準備及發佈您的 TypeScript 專案:The following commands prepare and publish your TypeScript project using Core Tools:

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

在此命令中, <APP_NAME>將取代為您的函數應用程式名稱。In this command, replace <APP_NAME> with the name of your function app.

JavaScript 函式的考量Considerations for JavaScript functions

當您使用 JavaScript 函式時,請留意下列小節中的考量事項。When you work with JavaScript functions, be aware of the considerations in the following sections.

選擇單一 vCPU App Service 方案Choose single-vCPU App Service plans

當您建立使用 App Service 方案的函數應用程式時,建議您選取單一 vCPU 方案,而非具有多個 vCPU 的方案。When you create a function app that uses the App Service plan, we recommend that you select a single-vCPU plan rather than a plan with multiple vCPUs. 目前 Functions 在單一 vCPU VM 上執行 JavaScript 函式會較有效率,而使用較大的 VM 並不會產生預期的效能改進。Today, Functions runs JavaScript functions more efficiently on single-vCPU VMs, and using larger VMs does not produce the expected performance improvements. 必要時, 您可以藉由新增更多單一 vCPU VM 實例來手動相應放大, 或者您可以啟用自動調整。When necessary, you can manually scale out by adding more single-vCPU VM instances, or you can enable autoscale. 如需詳細資訊,請參閱手動或自動調整執行個體計數規模For more information, see Scale instance count manually or automatically.

冷啟動Cold Start

在無伺服器裝載模型中開發 Azure Functions 時,可進行冷啟動。When developing Azure Functions in the serverless hosting model, cold starts are a reality. 冷啟動是指函數應用程式在閒置一段時間之後進行的第一次啟動,這需要較長的時間啟動。Cold start refers to the fact that when your function app starts for the first time after a period of inactivity, it takes longer to start up. 尤其是對於大型相依性樹狀結構的 JavaScript 函式,冷啟動可能會有很大的影響。For JavaScript functions with large dependency trees in particular, cold start can be significant. 若要加速執行冷啟動程序,請盡可能以套件檔案的形式執行函式To speed up the cold start process, run your functions as a package file when possible. 根據預設,許多部署方法都使用從套件執行的模式,但如果在進行許多冷啟動時未以此方式執行,此變更將可達到大幅改善的效果。Many deployment methods use the run from package model by default, but if you're experiencing large cold starts and are not running this way, this change can offer a significant improvement.

連接限制Connection Limits

當您在 Azure Functions 應用程式中使用服務特定的用戶端時, 請勿使用每個函式呼叫來建立新的用戶端。When you use a service-specific client in an Azure Functions application, don't create a new client with every function invocation. 相反地, 請在全域範圍中建立單一靜態用戶端。Instead, create a single, static client in the global scope. 如需詳細資訊, 請參閱管理 Azure Functions 中的連接For more information, see managing connections in Azure Functions.

使用asyncawaitUse async and await

以 JavaScript 撰寫 Azure Functions 時, 您應該使用asyncawait關鍵字來撰寫程式碼。When writing Azure Functions in JavaScript, you should write code using the async and await keywords. 使用asyncawait , 而不是回呼或與.catch承諾來撰寫程式碼, 有助於避免兩個常見的.then問題:Writing code using async and await instead of callbacks or .then and .catch with Promises helps avoid two common problems:

  • 擲回無法攔截例外狀況, 而導致 node.js 進程損毀, 可能會影響其他函數的執行。Throwing uncaught exceptions that crash the Node.js process, potentially affecting the execution of other functions.
  • 非預期的行為, 例如來自 coNtext .log 的遺漏記錄, 因為未正確等待的非同步呼叫所造成。Unexpected behavior, such as missing logs from context.log, caused by asynchronous calls that are not properly awaited.

在下列範例中, 會叫用fs.readFile具有錯誤第一個回呼函式的非同步方法作為第二個參數。In the example below, the asynchronous method fs.readFile is invoked with an error-first callback function as its second parameter. 這段程式碼會導致上述這兩個問題。This code causes both of the issues mentioned above. 在正確的範圍中未明確攔截到的例外狀況會損毀整個進程 (問題 #1)。An exception that is not explicitly caught in the correct scope crashed the entire process (issue #1). context.done()回呼函式範圍之外呼叫, 表示函式呼叫可能會在讀取檔案之前結束 (問題 #2)。Calling context.done() outside of the scope of the callback function means that the function invocation may end before the file is read (issue #2). 在此範例中, context.done()如果呼叫過早, 會導致遺漏記錄Data from file:專案, 從開始。In this example, calling context.done() too early results in missing log entries starting with Data from file:.

// 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();
}

async使用和await關鍵字有助於避免這兩個錯誤。Using the async and await keywords helps avoid both of these errors. 您應該使用 node.js 公用程式util.promisify函式, 將錯誤優先的回呼樣式函數轉換成可等候函數。You should use the Node.js utility function util.promisify to turn error-first callback-style functions into awaitable functions.

在下列範例中, 函式執行期間擲回的任何未處理例外狀況, 只會使引發例外狀況的個別調用失敗。In the example below, any unhandled exceptions thrown during the function execution only fail the individual invocation that raised an exception. 關鍵字表示只有在完成之後readFileAsync readFile才執行下列步驟。 awaitThe await keyword means that steps following readFileAsync only execute after readFile is complete. 使用async context.done()await時, 您也不需要呼叫回呼。With async and await, you also don't need to call the context.done() callback.

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

module.exports = async function (context) {
    try {
        const 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}`);
}

後續步驟Next steps

如需詳細資訊,請參閱下列資源:For more information, see the following resources: