import语句、import()、require() 用法和区别
import语句和import()属于ES6语法,而require()属于node中的。其中import()是ES2020引入函数,支持动态加载模块。
import命令能够接受什么参数,import()函数就能接受什么参数,两者区别主要是后者为动态加载。
import是静态加载资源,编译时放到代码块最顶层。
import()函数则是动态按需加载返回Promise 对象。import()
函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。
import()函数它是运行时执行,也就是说,什么时候运行到这一句,就会加载指定的模块。
import()
函数与所加载的模块没有静态连接关系,这点也是与import
语句不相同。import()
类似于 Node 的require
方法,区别主要是前者是异步加载,后者是同步加载。
参数 |
是否动态加载 | 与所加载的模块是否有静态连接关系 | |
import语句 | 引入的地址路径 | 否 | 是 |
import() | 引入的地址路径 | 是(异步加载) | 否 |
require() | 引入的地址路径 | 是(同步加载) | 否 |
参考资料: Native ECMAScript modules: dynamic import()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import
import defaultExport from "module-name"; import * as name from "module-name"; import { export } from "module-name"; import { export as alias } from "module-name"; import { export1 , export2 } from "module-name"; import { foo , bar } from "module-name/path/to/specific/un-exported/file"; import { export1 , export2 as alias2 , [...] } from "module-name"; import defaultExport, { export [ , [...] ] } from "module-name"; import defaultExport, * as name from "module-name"; import "module-name"; var promise = import("module-name");//这是一个处于第三阶段的提案。
defaultExport
导入模块的默认导出接口的引用名。
module-name
要导入的模块。通常是包含目标模块的.js
文件的相对或绝对路径名,可以不包括.js
扩展名。某些特定的打包工具可能允许或需要使用扩展或依赖文件,它会检查比对你的运行环境。只允许单引号和双引号的字符串。name
导入模块对象整体的别名,在引用导入模块时,它将作为一个命名空间来使用。
export, exportN
被导入模块的导出接口的名称。
alias, aliasN
将引用指定的导入的名称。
描述
name
参数是“导入模块对象”的名称,它将用一种名称空间来引用导入模块的接口。export参数指定单个的命名导出,而import * as name
语法导入所有导出接口,即导入模块整体。以下示例阐明该语法。
导入整个模块的内容
这将myModule
插入当前作用域,其中包含来自位于/modules/my-module.js
文件中导出的所有接口
import * as myModule from '/modules/my-module.js';
在这里,访问导出接口意味着使用模块名称(在本例为“myModule”)作为命名空间。例如,如果上面导入的模块包含一个接口doAllTheAmazingThings()
,你可以这样调用:
myModule.doAllTheAmazingThings();
仅为副作用而导入一个模块
整个模块仅为副作用(中性词,无贬义含义)而导入,而不导入模块中的任何内容(接口)。 这将运行模块中的全局代码, 但实际上不导入任何值。
import '/modules/my-module.js';
导入默认值
引入模块可能有一个default
export
(无论它是对象,函数,类等)可用。然后可以使用import
语句来导入这样的默认接口。
最简单的用法是直接导入默认值:
import myDefault from '/modules/my-module.js';
也可以同时将default
语法与上述用法(命名空间导入或命名导入)一起使用。在这种情况下,default
导入必须首先声明。 例如:
import myDefault, * as myModule from '/modules/my-module.js'; // myModule used as a namespace
或者
import myDefault, {foo, bar} from '/modules/my-module.js'; // specific, named imports
动态import
标准用法的import导入的模块是静态的,会使所有被导入的模块,在加载时就被编译(无法做到按需编译,降低首页加载速度)。有些场景中,你可能希望根据条件导入模块或者按需导入模块,这时你可以使用动态导入代替静态导入。下面的是你可能会需要动态导入的场景:
- 当静态导入的模块很明显的降低了代码的加载速度且被使用的可能性很低,或者并不需要马上使用它。
- 当静态导入的模块很明显的占用了大量系统内存且被使用的可能性很低。
- 当被导入的模块,在加载时并不存在,需要异步获取
- 当导入模块的说明符,需要动态构建。(静态导入只能使用静态说明符)
- 当被导入的模块有副作用(这里说的副作用,可以理解为模块中会直接运行的代码),这些副作用只有在触发了某些条件才被需要时。(原则上来说,模块不能有副作用,但是很多时候,你无法控制你所依赖的模块的内容)
请不要滥用动态导入(只有在必要情况下采用)。静态框架能更好的初始化依赖,而且更有利于静态分析工具和tree shaking发挥作用
关键字import可以像调用函数一样来动态的导入模块。以这种方式调用,将返回一个 promise
。
import('/modules/my-module.js') .then((module) => { // Do something with the module. });
这种使用方式也支持 await
关键字。
let module = await import('/modules/my-module.js');