复制链接https://stackblitz.com/edit/node-sp5xay?file=index.mjs
假设我们有这样一个项目:
.
├── dep
│ ├── a.mjs
│ ├── b.js
│ └── c.js
└── entry.mjs
// entry.mjs
import { foo } from "./dep/a.mjs";
console.log(foo);
// dep/a.mjs
export * from './b.js'
// dep/b.js
module.exports = require("./c.js"); // 💯
// why this not working ❌
// const m = require("./c.js");
// module.exports = m;
// dep/c.js
exports.foo = "foo";
我们在终点站
node entry.mjs
如果在dep/b.js
中使用以下语句,则会抛出错误,这非常令人困惑:
// why this not working ❌
const m = require("./c.js");
module.exports = m;
如果在dep/b.js
中我们用途:
module.exports = require("./c.js");
它将工作预期!
module.exports=require
有一些神奇的东西吗?比如符号链接?如果我错过了任何文档?
这个问题的根源是我看到了vue 3的源代码vue3 core source code export
2条答案
按热度按时间ehxuflar1#
module.exports=require
有什么神奇的东西吗?是的,它确实有一些魔力。问题是你正在把一个CommonJS模块导入到一个ES模块中。后者需要导出名称的静态声明,而前者没有提供。参见node.js文档:
module.exports
对象作为默认导出提供。*因此,不要执行
export * from './b.js'
,而是先执行import b from './b.js'
,然后在CommonJS模块对象上引用b.foo
。但是,
(着重号是我的)
事实上
是检测到的"重新导出模式"之一,但使用临时变量
你只是不能使用CommonJS模块中的命名导入,解决这个问题的正确方法当然是将模块重写为ESM语法,并使用
export * from "./c.js";
,而不是任何module.exports
赋值。nr9pn0ug2#
在Node.js中,
module.exports
对象用于指定当使用require
导入模块时,模块应提供哪些内容。第一条语句
module.exports = require('module')
将module.exports对象设置为使用require导入的模块对象的值。这意味着由module
模块导出的任何内容都将对导入它的代码可用。另一方面,
module.exports = {...}
将module.exports对象设置为一个对象文本,该对象文本包含导入模块的代码应该可以使用的属性和值。这允许您准确地指定模块中应该提供的内容,而不是依赖于另一个模块的导出。例如,假设您有一个名为
myModule
的模块,它导出单个函数:然后可以导入并使用此模块,如下所示:
另一方面,如果将module.exports设置为另一个模块的exports的值,如下所示:
然后,anotherModule的导出将可用于导入myModule的代码。例如: