浏览器对es modules 的一些解析

19042次浏览

前言

我们在用框架开发时,运用es modules对资源加载,已经再平常不过了。但是现在。浏览器端也已经慢慢开始支持es modules,支持的浏览器如下:

Safari 10.1.

Chrome 61.

Firefox 54 – 需要在about:config中设置才能激活

Edge 16.

基本用法

<script type="module">
  import {addTextToBody} from './utils.js';

  addTextToBody('Modules are pretty cool.');
</script>
// utils.js
export function addTextToBody(text) {
  const div = document.createElement('div');
  div.textContent = text;
  document.body.appendChild(div);
}

注意事项

一般导入时,需要特定符号开头,或者整个地址导入:

整个地址导入

以 /. 开头

以 ./. 开头

以 ../. 开头

例如:

//支持
import {foo} from 'https://jakearchibald.com/utils/bar.js';
import {foo} from '/utils/bar.js';
import {foo} from './bar.js';
import {foo} from '../bar.js';

// 不支持
import {foo} from 'bar.js';
import {foo} from 'utils/bar.js';

浏览器降级方案

<script type="module" src="module.js"></script>
<script nomodule src="fallback.js"></script>

浏览器不支持可以使用nomodule

默认会延迟执行

<!-- 这个会延迟… -->
<script type="module" src="1.js"></script>

<!-- …先执行这个… -->
<script src="2.js"></script>

<!-- …但是在这个之前. -->
<script defer src="3.js"></script>

上面代码执行循序是 2.js > 1.js > 3.js

行内的也会延迟,例如如下:

<!-- 这段代码会延迟… -->
<script type="module">
  addTextToBody("Inline module executed");
</script>

<!-- …先执行… -->
<script src="1.js"></script>

<!-- …在执行… -->
<script defer>
  addTextToBody("Inline script executed");
</script>

<!-- …在这段代码之前执行. -->
<script defer src="2.js"></script>

异步下的内联和外联模块

<!-- This executes as soon as its imports have fetched -->
<script async type="module">
  import {addTextToBody} from './utils.js';

  addTextToBody('Inline module executed.');
</script>

<!-- This executes as soon as it & its imports have fetched -->
<script async type="module" src="1.js"></script>

只引入一次

<!-- 1.js只引入一次 -->
<script type="module" src="1.js"></script>
<script type="module" src="1.js"></script>
<script type="module">
  import "./1.js";
</script>

<!--引入多次 -->
<script src="2.js"></script>
<script src="2.js"></script>

CORS

<!-- 进行cors验证,假如跨域,会失败 -->
<script type="module" src="https://….now.sh/no-cors"></script>

<!-- This will not execute, as one of its imports fails a CORS check -->
<script type="module">
  import 'https://….now.sh/no-cors';

  addTextToBody("This will not execute.");
</script>

<!-- This will execute as it passes CORS checks -->
<script type="module" src="https://….now.sh/cors"></script>

跨域的情况下,需要指定

Access-Control-Allow-Origin: *.

解决了script 允许跨域的bug。(jsonp通过script标签跨域原理,jsonp跨域原理传门:https://www.zhihu.com/question/19966531)

关于credentials

<!-- 默认是有 credentials (cookies etc) -->
<script src="1.js"></script>

<!-- 默认没有credentials -->
<script type="module" src="1.js"></script>

<!--增加 credentials 的写法-->
<script type="module" crossorigin src="1.js?"></script>

<!-- 不要 credentials 的写法-->
<script type="module" crossorigin src="https://other-origin/1.js"></script>

<!-- 要 credentials的写法-->
<script type="module" crossorigin="use-credentials" src="https://other-origin/1.js?"></script>

小结

关于浏览器对es modules 就写到这里,关于es6 modules,请看阮一峰的文章。或者可以看下这篇文章:https://ponyfoo.com/articles/es6-modules-in-depth

Tags: es modulesjs

相关文章: