javascript - 如何发布双npm包(CommonJS + module)以便子模块统一导入

标签 javascript node.js npm es6-modules commonjs

我一直在努力打包 NPM 包,以便它捆绑 CommonJS 和 ES 模块,但它们都使用相同的绝对模块路径导入。不仅仅是主模块。

例如,我可能有一个两个构建在包内都有其 或 目录

/package
  /modules
    index.js
    submodule.js
  /node
    index.js
    submodule.js

我希望能够透明地导入,以便在 Node 或浏览器(或 webpack 等)上加载正确的模块。

因此,调用 require('package/submodule') 将加载 /package/node/submodule.js从 'package/导入子模块submodule' 将加载 /package/modules/submodule.js

这是否可能,特别是它不会影响消费者并与旧版本的 Node 一起使用?

我尝试了各种东西,例如条件导出、type=module,但遇到了 jest + babel-jest 尝试导入错误模块的问题。

最佳答案

这没有详细记录或显而易见,但在 Node 13.7.0+ 中可以使用条件导出,就像 the way you would for the main entry point 一样。不过,您的 ES 模块需要使用 .mjs 文件扩展名。

node_modules/package/package.json

{
    "main": "./node/index.js",
    "exports": {
        ".": [
            {
                "import": "./modules/index.mjs",
                "require": "./node/index.js",
                "default": "./node/index.js"
            },
            "./node/index.js"
        ],
        "./submodule": [
            {
                "import": "./modules/submodule.mjs",
                "require": "./node/submodule.js",
                "default": "./node/submodule.js"
            },
            "./node/submodule.js"
        ]
    }
}

node_modules/package/modules/index.mjs

export const index = 'mjs-index';

node_modules/package/modules/submodule.mjs

export const submodule = 'mjs-submodule';

node_modules/package/node/index.js

exports.index = 'cjs-index';

node_modules/package/node/submodule.js

exports.submodule = 'cjs-submodule';

你的包可以像这样使用:

main.js

const {index} = require('package');
const {submodule} = require('package/submodule');

console.log(index);
console.log(submodule);

main.mjs

import {index} from 'package';
import {submodule} from 'package/submodule';

console.log(index);
console.log(submodule);

这是您在 Node 13.11.0 中获得的输出。

$ node main.js
cjs-index
cjs-submodule
$ node main.mjs
(node:44920) ExperimentalWarning: The ESM module loader is experimental.
mjs-index
mjs-submodule

Node <13

对于不支持子模块的旧版本 Node ,您将需要子模块路径中的一个文件。

例如,您可以添加此 stub :

node_modules/package/submodule.js

modules.exports = require('./node/submodule');

关于javascript - 如何发布双npm包(CommonJS + module)以便子模块统一导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60028301/

相关文章:

node.js - Firestore 无法与 AWS Lambda 配合使用

javascript - 在 Node.js/Express 中,如何自动将此 header 添加到每个 "render"响应中?

node.js - 为什么 tls.getLegacyCiphers() 不在 node.js v10.38 中?

docker - Dokku/Docker 部署应用程序失败

javascript - global cli npm 包适用于 windows 但不适用于 linux

javascript - 我无法在node.js中使用router.post方法

javascript - 关于 Fetch API 的一个小困惑

javascript - nodejs + WebSockets - 通过消息拒绝连接

javascript - 不提交表单的 HTML 按钮

node.js - 找不到兼容版本 : mongodb@3. 2.8