概述
import
是Javascript语言在nodejs和浏览器中的未来,用于ECMAScript模块(ESM模块)加载其他模块,无论是静态还是动态。
require()
是nodejs加载模块的最初方式,用于CommonJS模块。require()
在nodejs中有本地支持,但在浏览器中不支持(尽管有一些第三方库提供了类似于require的模块加载器)。
选择一种
通常情况下,您希望选择一种机制并将其用于整个项目,因为混合/匹配会使事情变得复杂。 import
在nodejs中曾经有过一些成长的烦恼,但现在的实现已经相当完整。 无论哪种方式,您可能会遇到一些不属于您选择的项目类型的模块,并且必须学习如何处理它们。
如果我要开始一个预计会持续很长时间并且我将在接下来的几年内工作的新项目,我会选择使用ESM模块和import
,因为这是Javascript模块的当前/未来架构。
如果我正在编写一个依赖于一堆只在CommonJS中可用的脚本的快速“完成它”的脚本,我可能会使用CommonJS require()
。
如果我要编写我想在nodejs和浏览器之间共享的模块,我会选择ESM,因为它在两者中都受支持。
你的问题
当我查看Node.JS文件系统模块“fs”的文档时,它没有提到使用const fs = require('fs);,而是讨论使用import方法import { mkdir } from 'fs'。
当前版本的fs
文档可以让您选择代码示例是否显示CJS或ESM模块语法。显然您正在查看以ESM语法显示的文档,您可以进行切换。两者都可以使用。
当您在文档中看到此图像
时,这意味着您可以将文档中的示例代码从CJS切换到ESM或反向切换。
SyntaxError: Cannot use import statement outside a module
在nodejs中,您必须以某种方式告诉nodejs您的顶级模块是CJS还是ESM。默认情况下,.js
文件被视为CJS,而.mjs
文件被视为ESM。如果nodejs认为您有一个CJS文件,则无法使用import
(那只适用于ESM模块)。
你也可以修改控制特定脚本的package.json
文件(通过添加"type": "module"
),如果想要将您的文件强制转换为ESM模块,那么就可以使用.js
文件作为ESM模块。
使用const fs = require('fs');
也完全没问题
是的,如果nodejs认为你正在使用CJS模块。
我想确保我的代码一致/正确,所以我该使用哪一个模块类型?为什么?
关于何时选择每个模块类型,请参见我的先前解释。如果您只是在学习,请学习如何告诉nodejs您正在使用ESM模块并使用import
,因为这是该语言的未来方向。require()
不会很快消失,但如果我们开始看到仅支持较新的ESM语法并且只能从ESM模块加载的新NPM包(共享模块),那将不足为奇。通过一些小心的工作,可以制作一个既可以通过ESM模块又可以通过CJS模块加载的可共享模块。此外,ESM模块正在获得一些功能(例如顶层await
),而CJS模块永远不会获得这些功能。
更多细节
有关详细信息,建议阅读此文章:
Node模块之争-为什么CommonJS和ESM模块无法相处