html中引入ES6模块

2,435 阅读2分钟

昨天写一个demo测试某个库,看了库的介绍,有node版本和ES6版本,心血来潮干脆用原生html写测试demo了。 使用 <script type="module"></script>这种模块的方式,可以导入ES6模块。

<body>
  <button id="del-btn">删除 </button><br><br>

  <script type="module">
    import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
    document.querySelector('#del-btn').addEventListener('click', handleDeleteRepo, false);
    function handleDeleteRepo(){
      // ...
    }
  </script>
</body>
</html>

坑点:

  1. 不要在<button id="del-btn">删除 </button>按钮上绑定onclick事件,如:onclick=“handleDeleteRepo”, 事件代码不会被执行。
  2. 这是因为type=module内的代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。说白了就是按钮上的handleDeleteRepo事件是无法被访问的。
  3. 解决方案: 在模块内的js中,添加事件监听事件,如
document.querySelector('#del-btn').addEventListener('click', handleDeleteRepo, false);

知识点:

  • 浏览器加载 ES6 模块,使用

    <script type="module"> 
      // your code ... 
    </script>
    
    // 或者 
    <script type="module" src="./jquery.js"></script>
    
  • 浏览器对于带有type="module"<script>,都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,等同于打开了<script>标签的defer属性。

  • module 内的代码是在模块作用域之中运行,而不是在全局作用域运行。模块内部的顶层变量,外部不可见。

  • 同一个模块如果加载多次,将只执行一次。

  • 模块之中,顶层的this关键字返回undefined,而不是指向window

  • deferasync属性的区别是:

    1. defer要等到整个页面渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;
    2. async一旦js下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。
    3. 一句话,defer是“页面渲染完再执行”,async是“js下载完就执行”。
    4. 另外,如果有多个defer脚本,会按照它们在页面出现的顺序加载,而多个async脚本是不能保证加载顺序的。