本文作者:IMWeb zzbozheng 原文出处:IMWeb社区 未经同意,禁止转载
原文:https://jakearchibald.com/2017/es-modules-in-browsers/
各浏览器开始支持ES模块,我们可以使用以下浏览器版来体验:
// utils.js
export function addTextToBody(text) {
const div = document.createElement('div');
div.textContent = text;
document.body.appendChild(div);
}
<script type="module">
import {addTextToBody} from './utils.js';
addTextToBody('Modules are pretty cool.');
</script>
你只需要给script
标签加上type=module属性,浏览器会把内联脚本或外联脚本当作ECMAScript模块来处理。 尽管已经有一些不错的文章来介绍JS模块,但我想分享一些关于浏览器端的模块功能:
// Supported:
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';
// Not supported:
import {foo} from 'bar.js';
import {foo} from 'utils/bar.js';
合法的模块路径必须满足以下其中一项条件:
<script type="module" src="module.js"></script>
<script nomodule src="fallback.js"></script>
如果浏览器支持type=module,那么将会忽略带有nomodule的script标签,这意味着你可以对不支持ECMA模块的浏览器做降级处理。
<!-- 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>
加载顺序是2.js
, 1.js
, 3.js
通常脚本在加载的过程中会阻塞页面的渲染,对于普通脚本你可以使用defer去避免页面的渲染阻塞,但这也会推迟脚本的执行直到文档完成解析,并且与其他延迟脚本保持执行顺序。但模块脚本默认是defer的,这意味着不会对HTML的解析造成阻塞。
<!-- 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>
执行顺序将会是:1.js
, 内联脚本, 内联模块, 2.js
常规内联脚本会忽略延迟,而内联模块脚本总是被推迟,不管它们是否导入任何东西。