1. 使用时import ... from ...
,模块路径必须是字符串文字。使用时require
,模块路径可以是动态的。
例如,
const name = "module2";
const obj = require(`./${name}`);
但这在使用node
时会导致错误SyntaxError: Unexpected template string
。
const name = "module2";
import { func } from `./${name}`;
类似的代码import { func } from ("./partial/path" + someVariable);
也会导致语法错误。
为什么是这样?参见下一点。
2.命令执行不同。在上面的代码执行是,require
将内联运行。import
在脚本的其余部分之前运行。
假设module2.js
在顶部有console.log("require module2");
,那么如果我们运行这段代码:
console.log("require module1");
const obj = require("./module2");
console.log(`module2 = ${obj.module2}`);
结果如下:
require module1
require module2
module2 = require module2
使用ES模块时
console.log("require module1");
import module2 from "./module2.js";
console.log(`module2 = ${module2}`);
运行此操作将导致以下结果:
require module2
require module1
module2 = require module2
3..js
使用导入本地模块时require
,可以省略扩展名
,但使用import
时不能这样做。
在浏览器和Node.js中,默认情况下是这样。例如,require("./module2")
可以运行,但等效的使用import
必须写为import module2 from "./module2.js"
。如果您在Node.js中省略扩展名,则会出现类似以下错误:Error [ERR_MODULE_NOT_FOUND]: Cannot find module …
在Node.js中,您可以使用--experimental-specifier-resolution=node
选项来规避此行为,即,.js
当使用时,这将允许您省略扩展名import
。
此外,webpack具有更改此行为的选项。具体来说,如果resolve.enforceExtension
为true
,则需要扩展名。,此选项默认情况下是false
,这说明了为什么在许多框架中(例如Next.js,在后台使用webpack)可以在import
不指定文件扩展名的情况下使用。