在 Azure Typescript 函数中使用 ES 模块包

问题描述 投票:0回答:2

我无法在我的 Azure Function 中使用包 p-map。我收到以下错误:

Worker failed to load function: 'serverless' with function id: '<id>'.
Result: Failure
Exception: Worker was unable to load function serverless: 'Error [ERR_REQUIRE_ESM]: require() of ES Module <es-module> from /usr/local/Cellar/azure-functions-core-tools@4/4.0.4483/workers/node/worker-bundle.js not supported.
Instead change the require of index.js in /usr/local/Cellar/azure-functions-core-tools@4/4.0.4483/workers/node/worker-bundle.js to a dynamic import() which is available in all CommonJS modules.'

该项目是按照Azure 文档中的步骤创建的。以下是index.ts中的内容:

import { AzureFunction, Context, HttpRequest } from "@azure/functions";
import pMap from "p-map";
import got from "got";

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
    const sites = [
        'https://avajs.dev',
        'https://github.com'
    ];

    const mapper = async site => {
        const {requestUrl} = await got.head(site);
        return requestUrl;
    };

    const result = await pMap(sites, mapper, {concurrency: 2});
    

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: result
    };

};

export default httpTrigger;

我的 tsconfig.json 如下所示:

{
  "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "outDir": "dist",
    "rootDir": ".",
    "sourceMap": true,
    "strict": false,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true
  }
}

最后,这是我的package.json:

{
  "name": "azure-functions-test",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "watch": "tsc -w",
    "prestart": "npm run build",
    "start": "func start",
    "test": "echo \"No tests yet...\""
  },
  "dependencies": {
    "got": "^12.0.4",
    "p-map": "^5.3.0"
  },
  "devDependencies": {
    "@azure/functions": "^3.0.0",
    "typescript": "^4.0.0"
  }
}

p-map 严格来说是一个 ES 模块,不能在 CommonJS 项目中使用。

我是否遗漏了某些内容,或者是否无法在 Azure Functions 中使用 ES 模块包?预先感谢。

上述代码的 GitHub 存储库,用于在本地进行测试:azure-functions-test

typescript azure azure-functions commonjs esmodules
2个回答
2
投票

根据 Node.js 网站上的 docs,在

"type": "module"
中指定
package.json
还应指示 Node 是否应使用 ESM。

以下是我为让 ESM 在我的 Function App 中为我的函数工作所做的工作:

tsconfig.json

{
  "compilerOptions": {
    "module": "ESNext",
    "target": "ESNext",
    "moduleResolution": "Node",
    "outDir": "dist",
    "rootDir": ".",
    "sourceMap": true,
    "strict": false,
    "noImplicitAny": true,
    "noUnusedLocals": true
  }
}

一些相关功能应用设置:

WEBSITE_NODE_DEFAULT_VERSION
~16
(使用 Node.js 16 运行时运行)
FUNCTIONS_EXTENSION_VERSION
~4

然后,如果您的原始扩展名是

.js
,请确保导入带有
.ts
扩展名的 ES 样式导出。因此,如果您有一个名为
custom.ts
且具有导出功能的文件,那么您应该将它们导入为
import { something } from "custom.js";

对于任何使用默认导出(CommonJS 风格)的 npm 包,您应该使用其默认导出导入包,即

import * as pkg from "pkg";

相关链接:

https://github.com/Azure/azure-functions-nodejs-worker/issues/104

https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2-v3-v4-export%2Cv2-v3-v4-done%2Cv2%2Cv2- log-custom-telemetry%2Cv2-accessing-request-and-response%2Cwindows-setting-the-node-version#ecmascript-modules(请注意,本文档讨论了使用

.mjs
扩展导入 ESM 导出,但我没有不必这样做。)


0
投票

我通过将index.ts 文件重命名为index.mts 解决了我的问题。这在我的 dist 文件夹中构建了一个 index.mjs 文件(运行后

npm run build
),解决了问题。

需要注意的一件事是,您还必须编辑 function.json 的 scriptFile 键,以便它使用您的 .mjs 文件而不是不存在的 .js 文件。

© www.soinside.com 2019 - 2024. All rights reserved.