zoukankan      html  css  js  c++  java
  • es6 module和commonJs对比

    es6 module

    es6 module import

    1.无法动态加载,import命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行

    // 报错
    if (x === 1) {
      import { foo } from 'module1';
    } else {
      import { foo } from 'module2';
    }
    

    es6 module export

    // export-default.js
    export default function () {
      console.log('foo');
    }
    

    commonJs

    commonJs特点:
    所有代码都运行在模块作用域,不会污染全局作用域。
    模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
    模块加载的顺序,按照其在代码中出现的顺序

    commonJs导入require

    1.require主要识别.js、 .json 或 .node等后缀,.js 文件会被解析为 JavaScript 文本文件, .json 文件会被解析为 JSON 文本文件。 .node 文件会被解析为通过 process.dlopen() 加载的编译后的插件模块,其他的后缀全部按js加载。
    2..以 '/' 为前缀的模块是文件的绝对路径。
    3.以 './' 为前缀的模块是相对于调用 require() 的文件的
    4.require加载node_module时,向上逐级递归,直到根目录下的node_modules目录
    新建index.js,内容如下

    console.log(module.paths);
    

    执行

    node index.js
    

    结果如下

    5.每次导入模块,都会module将其封装,好处变量这些是不会污染全局,并且传入快捷变量 __filename 和 __dirname

    (function(exports, require, module, __filename, __dirname) {
    // 模块的代码实际上在这里
    });
    

    6.优先从缓存加载

    function wrapper (script) {
        return '(function (exports, require, module, __filename, __dirname) {' + 
            script +
         '
    })'
    }
    
    function require(id) {
     var cachedModule = Module._cache[id];
      if(cachedModule){
        return cachedModule.exports;
      }
      
      const module = { exports: {} }
    
      // 这里先将引用加入缓存 后面循环引用会说到
      Module._cache[id] = module
    
      //当然不是eval这么简单
      eval(wrapper('module.exports = "123"'))(module.exports, require, module, 'filename', 'dirname')
      return module.exports
    }
    

    7.支持动态导入

    if(true){
     require("./a/b");
    }
    

    commonJs导出

    module.exports和export

    //一个一个 导出
    module.exports.age = 1
    module.exports.foo = function(){}
    exports.a = 'hello'
    
    //整体导出
    module.exports = { age: 1, a: 'hello', foo:function(){} }
    
    //整体导出不能用`exports` 用exports不能在导入的时候使用
    exports = { age: 1, a: 'hello', foo:function(){} }
    

    差异

    1.CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
    CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值
    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
    

    JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值

    // lib.js
    export let counter = 3;
    export function incCounter() {
      counter++;
    }
    
    // main.js
    import { counter, incCounter } from './lib';
    console.log(counter); // 3
    incCounter();
    console.log(counter); // 4
    

    2.CommonJS 模块是运行时加载,ES6 模块是编译时输出接口
    3.CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段

    类型 加载方式 同步或异步 输出
    CommonJS 动态导入 同步 输出值拷贝
    es6module 静态导入 异步 输出值引用,需要的时候去加载模块取值
  • 相关阅读:
    1269 匈牙利游戏 2012年CCC加拿大高中生信息学奥赛
    2577 医院设置
    2488 绿豆蛙的归宿
    3315 时空跳跃者的魔法
    1079 回家
    1365 浴火银河星际跳跃
    1074 食物链 2001年NOI全国竞赛
    2596 售货员的难题
    wetask.cn领度任务全新试用体验
    多线程--生产者消费者--简单例子
  • 原文地址:https://www.cnblogs.com/heihei-haha/p/14759697.html
Copyright © 2011-2022 走看看