在避免或最小化危险的同时编写双重包
【Writing dual packages while avoiding or minimizing hazards】
首先,上一节中描述的风险发生在一个包同时包含 CommonJS 和 ES 模块源文件,并且这两种源文件都可用于 Node.js,无论是通过单独的主入口点还是导出的路径提供的情况下。一个包也可能被编写为任何版本的 Node.js 仅接收 CommonJS 源文件,而包中可能包含的任何单独的 ES 模块源文件仅用于诸如浏览器等其他环境。这样的包可以被任何版本的 Node.js 使用,因为 import 可以引用 CommonJS 文件;但它不会提供使用 ES 模块语法的任何优势。
【First, the hazard described in the previous section occurs when a package
contains both CommonJS and ES module sources and both sources are provided for
use in Node.js, either via separate main entry points or exported paths. A
package might instead be written where any version of Node.js receives only
CommonJS sources, and any separate ES module sources the package might contain
are intended only for other environments such as browsers. Such a package
would be usable by any version of Node.js, since import can refer to CommonJS
files; but it would not provide any of the advantages of using ES module syntax.】
一个包也可能在重大更改版本升级中从 CommonJS 切换到 ES 模块语法。这有一个缺点,即包的最新版本只能在支持 ES 模块的 Node.js 版本中使用。
【A package might also switch from CommonJS to ES module syntax in a breaking change version bump. This has the disadvantage that the newest version of the package would only be usable in ES module-supporting versions of Node.js.】
每种模式都有利弊,但有两种广泛的方法可以满足以下条件:
【Every pattern has tradeoffs, but there are two broad approaches that satisfy the following conditions:】
- 该包可以通过
require和import使用。 - 该软件包可以在当前版本的 Node.js 以及缺乏 ES 模块支持的旧版本 Node.js 中使用。
- 包的主入口,例如
'pkg',可以被require用于解析为 CommonJS 文件,也可以被import用于解析为 ES 模块文件。(导出的路径同理,例如'pkg/feature'。) - 该包提供具名导出,例如
import { name } from 'pkg',而不是import pkg from 'pkg'; pkg.name。 - 该软件包可能在其他 ES 模块环境中使用,例如浏览器。
- 前一节中描述的危险已被避免或最小化。