跳到主要内容

如何使用ES Module

前言

在云函数 Node.js 环境中无法直接采用 ES Module 规范编写代码,主要原因在于,云函数默认支持的入口文件(index.js)必须遵循 CommonJS 规范,并且文件名必须为 「index.js」。然而,Node.js 对于符合 ES Module 规范的模块文件要求其扩展名为 .mjs。因此,在云函数的入口文件中,我们无法直接使用 ES Module 规范进行编码。此外,Node.js 默认支持 CommonJS 模块,即通过 require 加载和 module.exports 输出。而对于采用 importexportES Module 模块,Node.js 无法直接识别。若要让 Node.js 正确识别这些模块,则必须将这些模块的后缀名改为 .mjs 这样 Node.js 即可识别它是 ES Module 模块。如果不希望将后缀名改成 .mjs,可以在项目的 package.json 文件中,指定 type 字段为 module。一旦设置了以后,该目录里面的 JS 脚本,就被解释用 ES Module 模块。

本篇文档介绍如何在云函数 Node.js 环境中编写符合 ES Module 规范的代码的方法,以及如何对现有云函数代码进行改造以适配 ES Module 规范。本文将从以下两个使用场景出发:

  • 场景一:如何在全新的云函数中编写符合 ES Module 规范的代码。

  • 场景二:改造现有的云函数代码使其支持 ES Module 规范。

通过以上两个场景的详细解析,您将能够全面掌握在云函数 Node.js 环境中运用 ES Module 规范的方法与技巧。

如何在全新的云函数中编写符合 ES Module 规范的代码

创建 Nodejs v14环境云函数

提示

Nodejs 版本必须大于等于14。

创建入口文件 entry.mjs

创建一个名为 entry.mjs 的文件,作为 ES Module 入口点。此文件将使用 ES Module 语法导入其他模块并导出一个函数。

// entry.mjs
import { foo } from './util.js';

// 入口函数
export const entry = (event, context) => {
foo(event, context);
};

在上述代码中,假设 util.js 模块中的 foo 函数是我们的业务代码,并且在 entry.mjs 中使用 ES Module 语法导入 foo 函数,并在入口函数 entry 中调用。

引入入口文件

接下来,在 index.js 中,需要动态地引入 entry.mjs 模块,并调用其导出的 entry 函数。

// index.js
exports.main = async (event, context) => {
const { entry } = await import('./entry.mjs');
return entry(event, context);
};

完整代码目录结构如下:

改造现有的云函数代码使其支持 ES Module 规范

对于现有的云函数代码想要适配 ES Module 规范,本着对代码最小侵入性以及改造成本最低原则,我们可以这样做:

创建入口文件 entry.mjs

创建一个名为 entry.mjs 的文件,作为 ES Module 入口点。此文件将使用 ES Module 语法导入现有的业务代码。

// entry.mjs

// 假设src文件夹是现有的业务代码
import { foo } from './src';

// 入口函数
export const entry = (event, context) => {
foo(event, context);
};

在上述代码中,假设 src 文件夹里存放的是业务代码,我们在 entry.mjs 中使用 ES Module 语法导入业务代码,并在入口函数 entry 中调用。

创建 package.json 文件

由于 Node.js 要求 ES6 模块必须采用 .mjs 作为文件后缀名,如果把现有的所有代码文件后缀名都手动一个个改成 .mjs 就太麻烦了,我们可以在业务代码目录下,创建一个名为 package.json 的文件,并写入以下内容:

{
"type": "module"
}

这将告诉 Node.js 将此目录视为 ES Module,并允许你使用 ESM 语法导入和导出模块。

完整代码目录结构如下:

总结

本文档详细介绍了如何在云函数的 Node.js 环境中编写和改造代码以适配 ES Module 规范。主要涉及两个场景:

  • 全新云函数的编写:

    • 创建 entry.mjs 作为 ES Module 入口。

    • index.js 中动态引入并调用 entry.mjs

  • 现有云函数的改造:

    • 同样创建 entry.mjs 作为入口。

    • 添加 package.json 指定 "type": "module",避免更改所有文件后缀。