Import maps
Posted kitebear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Import maps相关的知识,希望对你有一定的参考价值。
当 ES Module
最开始作为一种新的 JavaScript
模块化方案在 ES6
中被引入的候,其实是通过在 import
语句中强制指定相对路径或绝对路径来实现的。
import dayjs from "https://cdn.skypack.dev/dayjs@1.10.7"; // ES modules console.log(dayjs("2022-08-12").format("YYYY-MM-DD"));
这和其他常见的模块化系统(例如 CommonJS
)的工作方式略有不同,并且在使用像 webpack
这样的模块打包工具的时候会使用更简单的语法:
const dayjs = require(\'dayjs\') // CommonJS import dayjs from \'dayjs\'; // webpack
在这些系统里,模块导入语句通过 Node.js
运行时或相关构建工具映射到特定(版本)的文件。用户只需要在 import
语句中直接编写模块说明符(通常是包名),模块就可以自动处理。
由于开发人员已经熟悉了这种从 npm
导入包的方式,因此必须要先经过一个的构建步骤才能确保以这种方式编写的代码可以在浏览器中运行。
Import maps
就可以解决这个问题,它可以将模块说明符(包名)自动映射到它的相对或绝对路径。从而让我们不使用构建工具也能使用简洁的模块导入语法。
如何使用 Import maps
我们可以通过 HTML
中的 <script type="importmap">
标签来指定一个 Import maps
。
<script type="importmap"> "imports": "dayjs": "https://cdn.skypack.dev/dayjs@1.10.7", </script>
为了成功的在模块解析之前对其进行解析。这个 script
标签必须放在文档中第一个 <script type="module">
标签之前(最好放在 <head>
中),另外,目前每个 HTML
只允许编写一个 Import maps
。
<script type="module"> import dayjs from \'dayjs\'; console.log(dayjs("2022-08-12").format("YYYY-MM-DD"));</script>
在 script
标签内,我们可以通过一个 JSON
对象来为文档中的脚本所需导入的模块指定所有必要的映射。一个典型的 importmap
结构如下所示:
<script type="importmap"> "imports": "react": "https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js", "react-dom": "https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js" "square": "./modules/square.js", "lodash": "/node_modules/lodash-es/lodash.js" </script>
在上面的 import
对象中,每个属性对应一个映射。映射的左侧是导入说明符的名称(一般是包名),而右侧是说明符需要映射到的相对或绝对路径。在映射中指定相对路径时,必须要确保它们始终以 /、../或 ./
开头。
另外,importmap
中声明的包并不一定意味着它一定会被浏览器加载。页面上的脚本没有使用到的任何模块都不会被浏览器加载,即便你在 importmap
中声明了它。
编写好 importmap
之后,你就可以在后面的脚本中直接使用 ES Module
语法了。
<script type="module"> import cloneDeep from \'lodash\'; const objects = [ a: 1 , b: 2 ]; const deep = cloneDeep(objects); console.log(deep[0] === objects[0]);</script>
外部映射
你还可以在外部文件中指定你的映射,然后使用 script
的 src
属性链接到这个文件(Content-Type Header
必须要设置为 application/importmap+json
才能正常加载)。
<script type="importmap" src="importmap.json"></script>
不过尽量不要使用这种方式,因为它的性能比直接内联编写要差。
映射整个包
除了将一个说明符映射到模块之外,你还可以将一个说明符映射到包含多个模块的包:
<script type="importmap"> "imports": "lodash/": "/node_modules/lodash-es/" </script>
这种编写方式可以让你直接导入指定路径中的任何模块,相应的,浏览器也会把所有组件模块下载下来。
<script type="module"> import toUpper from \'lodash/toUpper.js\'; import toLower from \'lodash/toLower.js\'; console.log(toUpper(\'ConardLi\')); console.log(toLower(\'ConardLi\'));</script>
动态映射
你也可以基于一些条件在 script 中添加一个动态映射,比如,在下面的示例中我们通过判断是否存在 IntersectionObserver API
来导入不同文件:
<script> const importMap = imports: lazyload: \'IntersectionObserver\' in window ? \'./lazyload.js\' : \'./lazyload-fallback.js\', , ; const im = document.createElement(\'script\'); im.type = \'importmap\'; im.textContent = JSON.stringify(importMap); document.currentScript.after(im);</script>
使用同一模块的不同版本
使用 importmap
我们可以将不同的版本的模块映射到不同的包名中:
<script type="importmap"> "imports": "lodash@3/": "https://unpkg.com/lodash-es@3.10.1/", "lodash@4/": "https://unpkg.com/lodash-es@4.17.21/" </script>
另外你还可以通过 scopes
来实现同一个包不同模块的更细粒度的版本控制:
<script type="importmap"> "imports": "lodash/": "https://unpkg.com/lodash-es@4.17.21/" , "scopes": "/static/js": "lodash/": "https://unpkg.com/lodash-es@3.10.1/" </script>
/static/js
下的模块会使用 3.10.1
版本,而其他模块会使用 4.17.21
版本。
兼容性
这项技术目前在 Chrome
和 Edge
浏览器 89
及更高版本提供了全面支持,但 Firefox、Safari
和一些移动浏览器还没有支持。我们可以通过下面的代码来判断浏览器的支持情况:
if (HTMLScriptElement.supports && HTMLScriptElement.supports(\'importmap\')) // import maps is supported
对于没有提供支持的浏览器,我们可以使用下面这个 polyfill
:https://github.com/guybedford/es-module-shims
另外官方也推荐了一些其他 importmap
相关的 polyfill
和工具:
https://github.com/WICG/import-maps#community-polyfills-and-tooling
参考
集合MapHashMap
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class Main { /** * Map * 1.java.util包 * 2.接口 Map<K,V> * 3.映射顺序 * 某些映射实现可明确保证其顺序,如 TreeMap 类 * 另一些映射实现则不保证顺序 ,如 HashMap 类 * 4.key不能重复,但是只允许key有一个空值 * */ public static void main(String[] args) { // 1.生成一个HashMap Map<String,String> map1=new HashMap<String,String>(); // 2.添加元素,这个是无顺序的 map1.put("吕布", "奉先"); map1.put("赵云", "子龙"); map1.put("典韦", "无字"); map1.put("马超", "孟起"); map1.put("关羽", "云长"); map1.put("关羽", "二爷"); // 同名key,value会覆盖前面的值 map1.put(null, "孔明"); // 可以有一个null值 map1.put(null, "卧龙"); map1.put("", "庞统"); map1.put("", "凤雏"); System.out.println(map1); // {关羽=二爷, null=卧龙, =凤雏, 吕布=奉先, 典韦=无字, 马超=孟起, 赵云=子龙} // 3.定义另一个map2,放到map1里面 Map<String,String> map2=new HashMap<String,String>(); map2.put("孙尚香","枭姬"); map2.put("貂蝉", "闭月"); map1.putAll(map2); System.out.println(map1); // {关羽=二爷, null=卧龙, =凤雏, 吕布=奉先, 典韦=无字, 貂蝉=闭月, 马超=孟起, 孙尚香=枭姬, 赵云=子龙} // 4.通过key获取value的值,get不到这个key就会返回空 String str41=map2.get("貂蝉"); System.out.println("str41 : "+str41); // 闭月 String str42=map2.get("西施"); System.out.println("str42 : "+str42); // null // 5.移除key String str5=map2.remove("貂蝉"); System.out.println("str5 : "+str5); // 闭月 String str5_1=map2.get("貂蝉"); System.out.println("str5_1 : "+str5_1); // null System.out.println(map2); // {孙尚香=枭姬} System.out.println(map1); // {关羽=二爷, null=卧龙, =凤雏, 吕布=奉先, 典韦=无字, 貂蝉=闭月, 马超=孟起, 孙尚香=枭姬, 赵云=子龙} // 6.拿到map1中的所有key的集合 // 循环通过key获取value Set<String> set=map1.keySet(); System.out.println(set); // [关羽, null, , 吕布, 典韦, 貂蝉, 马超, 孙尚香, 赵云] for(String str:set) { String str6=map1.get(str); System.out.println("str6 : "+str6); // str6 : 二爷 // str6 : 卧龙 // str6 : 凤雏 // str6 : 奉先 // str6 : 无字 // str6 : 闭月 // str6 : 孟起 // str6 : 枭姬 // str6 : 子龙 } // 7.map1是否包含指定key,指定value,map是否是空的 boolean b1=map1.containsKey("吕布"); boolean b2=map1.containsValue("翼德"); boolean b3=map1.isEmpty(); System.out.println(b1); // true System.out.println(b2); // false System.out.println(b3); // false // 8.另一种循环获取key value的方法 // set8相当于Person类的对象,可以使用Person类的方法 // en 相当于String类的对象,可以使用String类的方法 Set<Entry<String, String>> set8=map1.entrySet(); for(Entry<String, String> en:set8) { String key =en.getKey(); String value=en.getValue(); System.out.println("key : "+key+", value : "+value); // key : 关羽, value : 二爷 // key : null, value : 卧龙 // key : , value : 凤雏 // key : 吕布, value : 奉先 // key : 典韦, value : 无字 // key : 貂蝉, value : 闭月 // key : 马超, value : 孟起 // key : 孙尚香, value : 枭姬 // key : 赵云, value : 子龙 } } }以上是关于Import maps的主要内容,如果未能解决你的问题,请参考以下文章