美文网首页
2.js模块化进阶

2.js模块化进阶

作者: zwj2024 | 来源:发表于2018-03-05 16:08 被阅读17次

    如何在浏览器和 Node 之中加载 ES6 模块
    实际开发中经常遇到的一些问题(比如循环加载)

    1.1.ES6 模块与 CommonJS 模块的差异
    CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
    CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

    1.1.1.第一个差异解释
    CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。

    // lib.js
    var counter = 3;
    function incCounter() {
      counter++;
    }
    module.exports = {
      counter: counter,
      incCounter: incCounter,
    };
    
    // main.js
    var mod = require('./lib');
    
    console.log(mod.counter);  // 3
    mod.incCounter();
    console.log(mod.counter); // 3
    

    遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。因此,ES6 模块是动态引用,并且不会缓存值。

    1.1.2.第二个差异解释
    因为 CommonJS 加载的是一个对象(即module.exports属性),该对象只有在脚本运行完才会生成。
    而 ES6 模块不是对象,它的对外接口只是一种静态定义。

    1.1.3.export通过构造函数实例化对象,输出的是同一个值。不同的脚本加载这个接口,得到的都是同样的实例。

    // mod.js
    function C() {
      this.sum = 0;
      this.add = function () {
        this.sum += 1;
      };
      this.show = function () {
        console.log(this.sum);
      };
    }
    
    export let c = new C();
    //上面的脚本mod.js,输出的是一个C的实例。
    
    //不同的脚本加载这个模块,得到的都是同一个实例。
    // x.js
    import {c} from './mod';
    c.add();
    
    // y.js
    import {c} from './mod';
    c.show();
    
    // main.js
    import './x';
    import './y';
    //现在执行main.js,输出的是1。
    

    1.2.浏览器加载
    默认情况下,浏览器是同步加载 JavaScript 脚本,即渲染引擎遇到<script>标签就会停下来,等到执行完脚本,再继续向下渲染。如果是外部脚本,还必须加入脚本下载的时间。

    <script>标签打开defer或async属性,脚本就会异步加载。defer是“渲染完再执行”:defer要等到整个页面在内存中正常渲染结束(DOM 结构完全生成,以及其他脚本执行完成),才会执行;async是“下载完就执行”:async一旦下载完,渲染引擎就会中断渲染,执行这个脚本以后,再继续渲染。

    浏览器加载 ES6 模块,也使用<script>标签,但是要加入type="module"属性。

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

    如果网页有多个<script type="module">,它们会按照在页面出现的顺序依次执行。

    一旦使用了async属性,<script type="module">就不会按照在页面出现的顺序执行,而是只要该模块加载完成,就执行该模块。

    1.3.Node加载

    Node 加载
    详解

    1.4.循环加载

    Node 加载
    详解

    相关文章

      网友评论

          本文标题:2.js模块化进阶

          本文链接:https://www.haomeiwen.com/subject/mhrhfftx.html