如何在CommonJS中使用ES6模块?

20

今天,使用动态导入可以将ES6模块导入到CommonJS模块中。下面最受欢迎的问题解释得很好! - brandizzi
2个回答

26
在Node.js中,如果您想在一个CommonJS模块中导入一个ES模块,您可以使用动态的import和ES模块上的.mjs文件扩展名。例如:

index.js CommonJS

const crypto = require('crypto');  // to show this is a commonJS module

import('./path/to/mod.mjs').then(mod =>
  console.log(mod.msg);    //  "Hello world!"
);

mod.mjs ES模块

export const msg = "Hello world!";
两个关于如何在CommonJS模块中使用import来导入lodash-es包的示例:
import('lodash-es').then(_ => {
  console.log(_.pad(_.toUpper('hello world'), 17, '*'));
});
Promise.all([
  import('lodash-es/pad.js'),
  import('lodash-es/toUpper.js'),
])
.then(([{ default: pad }, { default: toUpper }]) => {
  console.log(pad(toUpper('hello world'), 17, '#'));
});

或者你可以将需要的内容导入到一个不同的 CommonJS 模块中,然后导出一个 Promise ,这样你就可以使用 importrequire 导入它了。

utils.js

module.exports = Promise.all([
  import('lodash-es/pad.js'),
  import('lodash-es/toUpper.js'),
]);

index.js

require('./utils.js').then(([{ default: pad }, { default: toUpper }]) => {
  console.log(pad(toUpper('hello world'), 17, '*'));
}); 

很棒的答案!这是否需要某种未在此处提及的配置(类似于ESModule包中package.json中的"type":"module")? - Parzh from Ukraine
@DimaParzhitsky 不,它并不是。文件扩展名描述了每个文件的模块类型。 - MikeM
请注意,传递给import的字符串不一定是相对路径,它也可以是node_modules文件夹中包的名称。 - MikeM
好的,这是一个帮助。我如何使用它来导入一个ES6包,比如loadash-es?是写一个临时文件然后导出我需要的东西吗? - David Boshton
@DavidBoshton 我已经添加了一些更多的例子。 - MikeM
显示剩余2条评论

6
ES模块和CommonJS是互斥的,因此您不能“在CommonJS中使用ES6模块”。然而,在某种程度上,如果您只是指require()函数,您可以“在ES模块中使用CommonJS”。您可以使用module.createRequire()创建一个require()函数的实例:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);

// sibling-module.js is a CommonJS module.
const siblingModule = require('./sibling-module');

NodeJS文档中有一章关于两个模块系统之间的互操作性。非常有帮助,您可能想要查看它。


1
你也可以简单地使用 import './sibling-module';,通常没有必要创建一个 require 函数。 - Bergi
2
从你的回答中并不明显,而且原帖作者似乎很无知... - Bergi
7
这不再是事实。随着Node实现动态导入,你现在可以使用import() 函数(返回一个模块的promise)和import语法也支持导入Commonjs模块来在Commonjs中使用ES模块。 - slebetman
1
@slebetman,我尝试了与CommonJS互操作性的示例,它只能使用“.cjs”扩展名,但似乎文档中没有提到,谢谢! - Archsx
1
问题是关于在CommonJs中使用es6,而不是反过来。 - apollo
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接