当我查看Node.JS的“path”模块的文档时,它明确指出您必须通过这样做来导入模块:const path = require('path');
当我查看文件系统“fs”模块的Node.JS文档时,它没有提到执行const fs = require('fs);
,而是谈到使用导入方法import { mkdir } from 'fs';
,但当我尝试使用导入方法时,我得到了一个语法错误:SyntaxError: Cannot use import statement outside a module
使用const fs = require('fs');
工作正常,但我想确保我的代码是一致/正确的,所以我应该使用哪一个,为什么?如果不需要某些模块对我来说很重要,我想弄清楚如何使它正确工作。
2条答案
按热度按时间lf3rwulv1#
摘要
import
是nodejs和浏览器中Javascript语言的未来,用于ECMAScript模块(ESM模块)中,用于静态或动态加载其他模块。require()
是nodejs加载模块的原始方式,用于CommonJS模块。nodejs原生支持require()
,但浏览器不支持(尽管有一些第三方库为浏览器提供了require-like模块加载器)。选一个
您通常希望选择一种机制并将其用于整个项目,因为它使混合/匹配变得复杂。
import
在nodejs中有一段时间遇到了一些成长的烦恼,但现在实现已经相当完整了。无论哪种方式,您都可能会遇到一些模块,这些模块不是您为项目选择的类型,并且必须学习如何处理这些模块。如果我正在开始一个新项目,我预计会持续一段时间并工作多年,我会选择带有
import
的ESM模块,因为这是JavaScript中模块的当前/未来架构。如果我正在编写一个快速“搞定”的脚本,它依赖于一堆只能在CommonJS中使用的脚本,我可能会使用CommonJS
require()
。如果我正在编写我想在nodejs和浏览器之间共享的模块,我会选择ESM,因为两者都支持它。
您的问题
当我查看文件系统“fs”模块的Node.JS文档时,它没有提到执行const fs = require('fs);相反,它讨论了从'fs'使用导入方法import { mkdir }
当前版本的
fs
文档允许您选择是否希望代码示例显示CJS或ESM模块语法。当文档显示ESM语法时,您显然正在查看文档。你可以换一下。两个都行。当您在文档中看到这个图像x1c 0d1x时,它允许您将文档中的示例代码从CJS切换到ESM或返回。
语法错误:不能在模块外部使用import语句
在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()
不会很快消失,但如果我们开始看到新的NPM包(可共享模块)只支持更新的ESM语法,并且只能从ESM模块加载,我也不会感到惊讶。有可能(通过一些仔细的工作)制作一个可共享的模块,可以由ESM模块或CJS模块加载。此外,ESM模块正在获得一些CJS模块永远不会获得的功能(例如顶级
await
)。更多详情
有关更多详细信息,我建议阅读这篇文章:
Node Modules at War - Why CommonJS and ESM Modules Can't Get Along
5us2dqdw2#
正如@jfriend00所提到的,即使你不想混合使用require和imports,也有一些用例,你需要的一些包不能作为模块导入。在这种情况下,您可以在require语句之前使用以下代码。