JavaScript模块化

参考探索js的模块化

什么是JavaScript模块化?

模块化在我看来,就是把一些公共的函数封装起来给其他地方调用,而不用重复去写一些冗余的函数代码。

JavaScript模块化大致发展过程

CommonJS(服务端) => AMD (浏览器端) => CMD / UMD => ES Module

CommonJS

CommonJS主要用于服务器端。 这个规范是同步的

特点:
  • 模块可以多次加载,首次加载的结果将会被缓存,想让模块重新运行需要清除缓存。

  • 模块的加载是一项阻塞操作,也就是同步加载。

      // a.js
      module.exports = {
        moduleFunc: function() {
          return true;
        };
      }
      // 或
      exports.moduleFunc = function() {
        return true;
      };
    
      // 在 b.js 中引用
      var moduleA = require('a.js');
      // 或
      var moduleFunc = require('a.js').moduleFunc;
    
      console.log(moduleA.moduleFunc());
      console.log(moduleFunc())
    

AMD规范

在commonJS中, 模块的加载过程是一个同步的过程, 很明显地,如果在浏览器端, 肯定就会引起浏览器页面的阻塞,因此,这时候对模块异步加载的需求就出现了。从而出现AMD规范

异步模块定义规范(AMD)制定了定义模块的规则,这样模块和模块的依赖可以被异步加载。这和浏览器的异步加载模块的环境刚好适应(浏览器同步加载模块会导致性能、可用性、调试和跨域访问等问题)

这时候RequireJS应运而生

RequireJS

特点:
  • 前置依赖,异步加载

  • 便于管理模块之间的依赖性,有利于代码的编写和维护。

      // a.js
      define(function (require, exports, module) {
        console.log('a.js');
        exports.name = 'Jack';
      });
    
      // b.js
      define(function (require, exports, module) {
        console.log('b.js');
        exports.desc = 'Hello World';
      });
    
      // main.js
      require(['a', 'b'], function (moduleA, moduleB) {
        console.log('main.js');
        console.log(moduleA.name + ', ' + moduleB.desc);
      });
    
      // 执行顺序:
      // a.js
      // b.js
      // main.js
    

然而, 他也有他的不足之处
按照 AMD 的规范,在定义模块的时候需要把所有依赖模块都罗列一遍(前置依赖),而且在使用时还需要在 factory 中作为形参传进去。

define(['a', 'b', 'c', 'd', 'e', 'f', 'g'], function(a, b, c, d, e, f, g){ ..... });

是不是看起来又丑又复杂。。

RequireJS 模块化的顺序是这样的:模块预加载 => 全部模块预执行 => 主逻辑中调用模块,所以实质是依赖加载完成后还会预先一一将模块执行一遍,这种方式会使得程序效率有点低。

这个时候就出现了CMD规范,典型的就是seajs模块化

SeaJS

SeaJS 模块化的顺序是这样的:模块预加载 => 主逻辑调用模块前才执行模块中的代码,通过依赖的延迟执行,很好解决了 RequireJS 被诟病的缺点。

    // a.js
    define(function (require, exports, module) {
      console.log('a.js');
      exports.name = 'Jack';
    });

    // main.js
    define(function (require, exports, module) {
      console.log('main.js');
      var moduleA = require('a');
      console.log(moduleA.name);
    });

    // 执行顺序
    // main.js
    // a.js

ES6的module

ES Module 的思想是尽量的静态化,即在编译时就确定所有模块的依赖关系,以及输入和输出的变量,和 CommonJS 和 AMD/CMD 这些标准不同的是,它们都是在运行时才能确定需要依赖哪一些模块并且执行它。ES Module 使得静态分析成为可能

  • 模块功能主要由两个命令构成:export 和 import。export 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能。

  • 通过 export 命令定义了模块的对外接口,其他 JS 文件就可以通过 import 命令加载这个模块。

      模块的定义
      /**
       * export 只支持对象形式导出,不支持值的导出,export default 命令用于指定模块的默认输出,
       * 只支持值导出,但是只能指定一个,本质上它就是输出一个叫做default 的变量或方法
       */
      // 写法 1
      export var m = 1;
      // 写法 2
      var m = 1;
      export { m };
      // 写法 3
      var n = 1;
      export { n as m };
      // 写法 4
      var n = 1;
      export default n;
    
     模块的引入
      // 解构引入
      import { firstName, lastName, year } from 'a-module';
      // 为输入的变量重新命名
      import { lastName as surname } from 'a-module';
      // 引出模块对象(引入所有)
      import * as ModuleA from 'a-module';
    

在使用 ES Module 值得注意的是:import 和 export 命令只能在模块的顶层,在代码块中将会报错
这是因为 ES Module 需要在编译时期进行模块静态优化,import 和 export 命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行,这种设计有利于编译器提高效率,但也导致无法在运行时加载模块(动态加载)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容