将 ES 模块(.mjs)发布到 NPMJS,向后兼容 Node <8.5.0(双包)

Publish ES module (.mjs) to NPMJS, with backwards compatibility for Node <8.5.0 (Dual Package)

在 Node v8.5.0 之前, 是一个简单的过程:使用像 Babel 这样的工具转译 ES6 代码,然后将生成的 lib 目录发布到 NPMJS,而你的 GitHub repo 包含 src 个文件。

使用 v8.5.0, Node has released experimental support for native modules (export/import) via the --experimental-modules flag. It is now possible to publish purely-ES6 modules to NPMJS, and use them without any transpilation,只要涉及的文件具有 .mjs 扩展名。

如何I 发布 ES6 模块 (.mjs) 以便它也可以与不支持 ES 原生模块的旧 Node 版本一起使用?

在 13.7.0+ 上使用 conditional exports (which as of 13.10.0+ are no longer experimental). It's not well documented or obvious how to do this in a completely backwards-compatible way, but here's the trick which I previously researched 是可以实现的:

node_modules/mod/package.json

{
    "main": "./lib.js",
    "exports": {
        ".": [
            {
                "import": "./lib.mjs",
                "require": "./lib.js",
                "default": "./lib.js"
            },
            "./lib.js"
        ]
    }
}

node_modules/mod/lib.js

exports.format = 'cjs';

node_modules/mod/lib.mjs

export const format = 'mjs';

现在可以同时使用 CommonJS:

main.js

const {format} = require('mod');

console.log(format);
$ node main.js
cjs

和 ES 模块:

main.mjs

import {format} from 'mod';

console.log(format);
$ node main.mjs
mjs

在此之前,曾有可能在 package.json 中使用无扩展名的 main 条目,但此功能已被删除。如果有兴趣,请参阅此答案的修订历史。