简体   繁体   English

我可以在 IBM Cloud Functions (node.js) 中使用 ES 模块还是仅支持 Common JS?

[英]Can I use ES modules in IBM Cloud Functions (node.js) or is only Common JS supported?

When I create a Node.js v16 function action from a zip file containing a simple estest.js :当我从包含简单estest.js的 zip 文件创建 Node.js v16 函数操作时:

function main(params) {
    return { message: 'Hello World' };
}

and package.json containing "type": "module" I get:package.json包含"type": "module"我得到:

{
  "error": "Initialization has failed due to: Error [ERR_REQUIRE_ESM]: require() of ES Module /nodejsAction/1AfjbP59/estest.js from /nodejsAction/runner.js not supported.estest.js is treated as an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which declares all .js files in that package scope as ES modules.\nInstead rename estest.js to end in .cjs, change the requiring code to use dynamic import() which is available in all CommonJS modules, or change \"type\": \"module\" to \"type\": \"commonjs\" in /nodejsAction/1AfjbP59/package.json to treat all .js files as CommonJS (using .mjs for all ES modules instead).\n\n    at eval (eval at <anonymous> (/nodejsAction/runner.js:51:31), <anonymous>:1:1)\n    at /nodejsAction/runner.js:51:31"
}

I have not found any IBM Cloud documentation which states that only the legacy Common JS style is supported.我没有找到任何声明仅支持旧的 Common JS 样式的 IBM Cloud 文档。

EDIT:编辑:

Action created using:使用创建的操作:

ibmcloud fn action create test/estest estest.zip --kind nodejs:16

After some more research I've concluded the action itself can't be an ES Module.经过更多研究,我得出结论,动作本身不能是 ES 模块。

I tried renaming it to estest.mjs (without "type":"module" in package.json ) which gave:我尝试将其重命名为estest.mjs (在package.json中没有"type":"module" ),它给出了:

{"error": "Initialization has failed due to: Error [ERR_REQUIRE_ESM]: require() of ES Module /nodejsAction/azrfHRlh/estest.mjs not supported.\nInstead change the require of /nodejsAction/azrfHRlh/estest.mjs to a dynamic import() which is available in all CommonJS modules.\n    at eval (eval at <anonymous> (/nodejsAction/runner.js:51:31), <anonymous>:1:1)\n    at /nodejsAction/runner.js:51:31"}

which I believe is due to this require() in runner.js (the IBM Cloud / OpenWhisk implementation which tries to load my estest.mjs ES Module):我认为这是由于runner.js中的require() (尝试加载我的estest.mjs ES 模块的 IBM Cloud / OpenWhisk 实现):

//  The module to require.
let whatToRequire = index !== undefined ? path.join(moduleDir, index) : moduleDir;
let handler = eval('require("' + whatToRequire + '").' + main);

require() does not support ES modules: https://nodejs.org/api/esm.html#esm_require . require()不支持 ES 模块: https ://nodejs.org/api/esm.html#esm_require 。

Solution解决方案

As the error message suggests, the solution was to create a CommonJS wrapper ( estest.cjs ) which does a dynamic import() of my ES module estest.mjs and use "main": "estest.cjs" in package.json :正如错误消息所暗示的那样,解决方案是创建一个 CommonJS 包装器( estest.cjs ),它执行我的 ES 模块estest.mjs的动态import()并在package.json中使用"main": "estest.cjs"

estest.cjs estest.cjs
async function main(params) {
    const { mjstest } = await import('./estest.mjs');
    return mjstest(params);
}

exports.main = main;
estest.mjs estest.mjs
export const mjstest = (params) => {
    return { message: `Hello ${params.name || 'World'}` };
}
package.json包.json
{
    "name": "estest",
    "version": "1.0.0",
    "main": "estest.cjs"
}

I think the clue is in the error message:我认为线索在错误消息中:

supported.estest.js is treated as an ES module file as it is a .js file

have you tried changing the extension to supported.estest.mjs ?您是否尝试将扩展名更改为supported.estest.mjs

It might also be worth specifying the node version in package.json eg.package.json中指定节点版本可能也是值得的,例如。

  "engines": {
    "node": ">=16.x"
  },

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM