好吧,其实就是个小问题,本文主要用途是第二部分记录import的详细用法~~
目录下存在三个js。
t1.js
console.log("test1");
t2.js
console.log("test2.0");
import t from "./t1.js"
console.log("test2.1");
t3.js
console.log("test3.0");
import t2_1 from "./t2.js"
console.log("test3.1");
执行t3.js
结果:
test1
test2.0
test2.1
test3.0
test3.1
现在t3中套娃式多次引用
t3.js
console.log("test3.0");
import t2_1 from "./t2.js"
import t1 from "./t1.js"
import t2_2 from "./t2.js"
console.log("test3.1");
执行t3.js
结果和未套娃前一致:
test1
test2.0
test2.1
test3.0
test3.1
通过案例证明多次引用同一个js不会导致重复引用,且优先执行最深层js文件中的代码
如果使用vue或uniapp等,同一个页面多次调用相同或不同组件,组件中又引用了重复js,结果也是一样:只引用一次相同js
静态的import 语句用于导入由另一个模块导出的绑定。无论是否声明了 strict mode ,导入的模块都运行在严格模式下。在浏览器中,import 语句只能在声明了 type=“module” 的 script 的标签中使用。
此外,还有一个类似函数的动态 import(),它不需要依赖 type=“module” 的script标签。
在 script 标签中使用 nomodule 属性,可以确保向后兼容。
在您希望按照一定的条件或者按需加载模块的时候,动态import() 是非常有用的。而静态型的 import 是初始化加载依赖项的最优选择,使用静态 import 更容易从代码静态分析工具和 tree shaking 中受益。
语法
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();
给定一个名为myExport
的对象或值,它已经从模块my-module
导出(因为整个模块被导出)或显式地导出(使用export语句),将myExport插入当前作用域。
import {myExport} from '/modules/my-module.js';
这将foo
和bar
插入当前作用域。
import {foo, bar} from '/modules/my-module.js';
你可以在导入时重命名接口。例如,将shortName
插入当前作用域。
import {reallyReallyLongModuleExportName as shortName}
from '/modules/my-module.js';
使用别名导入模块的多个接口。
import {
reallyReallyLongModuleMemberName as shortName,
anotherLongModuleName as short
} from '/modules/my-module.js';
整个模块仅为副作用(中性词,无贬义含义)而导入,而不导入模块中的任何内容(接口)。 这将运行模块中的全局代码, 但实际上不导入任何值。
import '/modules/my-module.js';
引入模块可能有一个defaultexport
(无论它是对象,函数,类等)可用。然后可以使用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
当用动态导入的方式导入默认导出时,其工作方式有所不同。你需要从返回的对象中解构并重命名 “default” 键。
(async () => {
if (somethingIsTrue) {
const { default: myDefault, foo, bar } = await import('/modules/my-module.js');
}
})();
标准用法的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');
下面的代码将会演示如何从辅助模块导入以协助处理AJAX JSON请求。
function getJSON(url, callback) {
let xhr = new XMLHttpRequest();
xhr.onload = function () {
callback(this.responseText)
};
xhr.open('GET', url, true);
xhr.send();
}
export function getUsefulContents(url, callback) {
getJSON(url, data => callback(JSON.parse(data)));
}
import { getUsefulContents } from '/modules/file.js';
getUsefulContents('http://www.example.com',
data => { doSomethingUseful(data); });
此示例展示了如何基于用户操作去加载功能模块到页面上,在例子中通过点击按钮,然后会调用模块内的函数。当然这不是能实现这个功能的唯一方式,import()函数也可以支持await。
const main = document.querySelector("main");
for (const link of document.querySelectorAll("nav > a")) {
link.addEventListener("click", e => {
e.preventDefault();
import('/modules/my-module.js')
.then(module => {
module.loadPageInto(main);
})
.catch(err => {
main.textContent = err.message;
});
});
}
Specification |
---|
“function-like” dynamic import() proposal |
ECMAScript (ECMA-262) Imports |