感谢英文原做者 Jake Archibald 的技术分享javascript
各个浏览器对于ES6模块 import 、 export的支持状况java
script 里面要加 type="module", 这样浏览器才会把相关的代码看成ES6的module 来对待
<script type="module"> import {addTextToBody} from './utils.js'; addTextToBody('Modules are pretty cool.'); </script>
<script type="module"> import {addTextToBody} from 'utils.js'; // error addTextToBody('Modules are pretty cool.'); </script>
直接写 'utils.js' 会报错
你能够写绝对路径和相对路径, 可是不能直接写文件名,即便是同一层级下面的文件。也要加上 './name.js'
文件名后缀 .js 必需要有,否则浏览器没法识别路径。跨域
使用 "nomodule" 关键字来实现浏览器的向下兼容
<script type="module" src="module.js"></script> <script nomodule src="fallback.js"></script>
我是这样理解的,老的浏览器自己不会识别type="module" js,也就不会去有执行有type="module" 的js代码(可是仍是会下载的哈)。
也不识别 nomodule 关键字,因此它会忽略nomodule,即正常执行这个有nomodule标识的js。
而支持type=“module”的浏览器,它会自动不去执行有nomodule关键字的js。甚至连下都不去下载。
因此向下兼容的功能就走通了(这个你们用不一样的浏览器试试,马上能够明白)浏览器
惟一的问题,还有一类浏览器,它支持 type="module" 的 ES6特性,可是它不支持nomodule关键字。也就是说,即便有nomodule标识,它仍是会去下载而且执行这个js。即便它已经执行了 type=“module”的 js。
这些浏览器有服务器
type=“module”的加载方式默认使用 defer的加载方式。
关于defer 和 async :defer和async 都是异步加载代码。可是defer要等到整个页面在内存中正常渲染结束(DOM 结构彻底生成,以及其余脚本执行完成),才会执行。 async一旦下载完,渲染引擎就会中断渲染,执行这个脚本之后,再继续渲染。 一句话,defer是“渲染完再执行”,async是“下载完就执行”。另外,若是有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。dom
<!-- This script will execute after… --> <script type="module" src="1.js"></script> <!-- …this script… --> <script src="2.js"></script> <!-- …but before this script. --> <script defer src="3.js"></script>
内联的 <script> 也是采用的 defer加载模式
<!-- This script will execute after… --> <script type="module"> addTextToBody("Inline module executed"); </script> <!-- …this script… --> <script src="1.js"></script> <!-- …and this script… --> <script> //这里默认采用defer,避免歧义,建议手动加上 addTextToBody("Inline script executed"); </script> <!-- …but before this script. --> <script defer src="2.js"></script>
而若是是传统的script 内联js,调用的那个js文件在后面的话,会报错。异步
<!-- This script will throw error… --> <script defer> //这里就算采用defer也会报错 addTextToBody("Inline module executed"); </script> <script> addTextToBody("Inline script executed"); </script>
type="module" 也可使用 async 的方式进行加载(包括其内联的 import),等同普通 js 采用 async 进行加载的方式
<script type="module" async></script>
Browser issues
Firefox doesn't support async on inline module scripts (issue)async
<script type="module"> 只执行一次同ES6的加载机制,屡次import 只会被当成一次import处理
<!-- 1.js 只会被加载执行一次--> <script type="module" src="1.js"></script> <script type="module" src="1.js"></script> <script type="module"> import "./1.js"; </script> <!-- 普通JS 也只会被加载一次,可是会被执行屡次--> <script src="2.js"></script> <script src="2.js"></script>
Browser issues
Edge executes modules multiple times (issue). Fixed, but not yet shipped (expect Edge 17 to ship with the fix).this
type="module" 默认不支持跨域,这一点儿与传统js或图片彻底不同。传统js或图片默认就是支持跨域的。若是你想 type="module" 支持跨域。须要在从服务器返回的header上显示的给予有效的 CORS声明
Access-Control-Allow-Origin: *
spa
Browser issues
Firefox fails to load the demo page (issue).
Edge loads module scripts without CORS headers (issue). Fixed in Edge 16!
不一样于传统的 <scripts>, <script type="module"> 必须向浏览器提供有效的 javascript MIME types。
否则请求到的模块javascript不会执行
Browser issues
Edge executes scripts with invalid MIME types (issue).
没想到任何一个小功能,仔细去研究都有这么多的知识点。码文不易,各位给个赞可好。 转载请注明出处