V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
famanoder
V2EX  ›  程序员

前端各种模块化规范常回顾

  •  
  •   famanoder ·
    famanoder · 2016-12-08 21:06:58 +08:00 · 2070 次点击
    这是一个创建于 2941 天前的主题,其中的信息可能已经有所发展或是发生改变。

    记录一些要点,以便于常记起时有据可循!

    回首来时走过的-模块化之路 之前对于自个儿模块化之路的简单回顾,由于杂七杂八的内容太多,属于只可意会型,不便于对前端的模块化进行全面的理解;这几天面试了些前端,发现除了大神来秒杀我之外,大多人对模块化这块都比较陌生,甚至没听说过模块化是个什么玩意儿,那么就有些尴尬了;看看现在三分天下的流行框架: React 、 Angular(2)、 Vue ,他们的最大的共同点就是:模块化、组件化;还有由 Nodejs 衍生而来的各种前端构建工具: Webpack 、 Gulp 、 Systemjs ,使用它们的基础也是模块化、组件化,如果你非要说,你没有模块化、组件化,项目也跑的挺欢,也能用上这些构建工具,那么,只能呵呵了,何必呢?可见,模块化是必须的,无论项目大小,都得好好理解,从而应用到实践中去,一方面提高工作效率,另一方提高自己的前端水平;

    至于模块化的好处,网上各种论调就不多说了,除此之外,更重要的是:在模块化的基础上形成一种团队成员间的默契化规范,形成团队内的私有仓库,统一管理,达到像后端调用 package 一样自然而然的调用前端模块的目的;

    一切源自 CommonJS :

    不要怕这又是个什么框架要去花时间学习, CommonJS 是 JS 的模块化规范,由于 JS 的历史原因,起初并没有模块化之说,之后 JS 成为了浏览器端的事实标准,地位越来越重要, CommonJS 规范就是为了解决这个问题而提出的,并希望 JS 不仅仅运行于浏览器端,而是任何地方;感觉很牛逼的样子!然后, Nodejs 在服务端实现了 CommonJS 规范,从而将 JS 从浏览器的小环境拉到了前后端通行的大环境,丑小鸭终于变白天鹅了!

    按照 CommonJS 规范,文件即模块,使用 require 引用和加载模块, exports 定义和导出模块, module 标识模块,使用 require 时需要去读取并执行该文件,然后返回 exports 导出的内容,由于模块的读取执行是同步的文件操作,所以 CommonJS 只能在服务端由 Nodejs 发扬光大, Nodejs 的模块化可以看看这里:Browserify 让你的 Javascript 游走于前后端;但是在浏览器端,这种同步操作并不适用,至少会很耗时,阻塞后续代码的运行;从而在浏览器端由 CommonJS 衍生出两大分支: AMD (异步模块定义)和 CMD (通用模块定义);

    AMD (异步模块定义):

    AMD 的代表是 RequireJS ,通过 define(id?, dependencies?, factory)来定义模块, require([dependencies], function(){})来调用模块,使用提前异步加载依赖模块的方式,模块加载完毕后执行回调函数,这里要好好理解 JS 的异步机制,不可按同步顺序执行的思维去理解,多个文件异步并行加载,哪个先执行完不是你按照加载顺序可预料到的,而是等所有依赖执行完毕,最后一并回调结果;

    CMD (通用模块定义):

    CMD 的代表是 SeaJS ,与 RequireJS 定义和加载模块的方式略有不同,同样可以通过 define(id?, dependencies?, factory)定义模块,但是 SeaJS 是采用的就近依赖的方式来加载模块,一般不在 dependencies 里依赖模块,而是统一写法: define(function(require, exports, module){}),在 factory 里就近加载依赖模块,由 seajs.use([dependencies],function(mod,[mod]){})来使用模块;本质上也是异步的加载模块,只是和 RequireJS 相比加载和执行的时机不一样罢了;

    相比来说, Seajs 和 Requirejs 都是很不错的前端模块化组织方案,各有千秋; Requirejs 要等到所有前置依赖加载并执行完毕,再回调主要的代码逻辑,如果非要说有所欠缺,就得在前置依赖那里做优化了,但大致上是很流畅的; Seajs 只是将依赖模块预先加载并不执行,在需要时就近使用,这时就可能也许会出现延迟的现象;

    关于 Seajs 的简单理解:

    好好的 Seajs ,说不用就不用了

    好好的用好 seajs 吧!

    工具是非常重要的生产力:

    虽然浏览器端流行的模块化规范是 AMD 和 CMD ,但是借助工具的力量,我们依然可以在浏览器端模拟 CommonJS 规范,比如借助 Gulp 、 Webpack 之类的工具,我们在开发环境依然可以像写 Nodejs 一样写前端的 JS 代码,由工具打包成浏览器可运行的 JS ,同样,异步的调用代码块也是可行的;

    UMD (通用模块规范):

    现在 JS 已经可以通行前后端了,那么很大程度上一个 JS 模块是既可以在浏览器端运行,同时也能在服务端跑了, UMD 方案即是对 AMD 和 CommonJS 规范的整合,实现对 JS 模块化的跨平台;像下面这个鬼样子:

    (function(root, factory){
    if(typeof define ==='function'&& define.amd){
    // AMD
    define(['jquery'], factory);
    }elseif(typeof exports ==='object'){
    // Node, CommonJS 之类的
    module.exports = factory(require('jquery'));
    }else{
    // 浏览器全局变量(root 即 window)
    root.returnExports = factory(root.jQuery);
    }
    }(this,function($){
    // 方法
    function myFunc(){};
    // 暴露公共方法
    return myFunc;
    }));
    

    ES6 的模块化:

    ES6 作为 JavaScript 新的标准,自带了模块化的 buff ,通过 import 和 export 导入导出模块;基本思想与 CMD 、 AMD 差不多,只是多了更多语法糖式的东西,毕竟属于原生的支持,当然更加好用和易于理解;由于当前的浏览器环境,要想安心的使用,还是得借助工具的力量进行转换;

    总之,前端的模块化是必须的!不能安于现状,即便随便弄两下也能运行;很多时候静止也是一种后退,因为太多大神还比我们努力!

    原文来自:花满楼(http://famanoder.com

    2 条回复    2016-12-09 17:37:43 +08:00
    xiamx
        1
    xiamx  
       2016-12-09 09:26:07 +08:00
    很不错,希望能看到 OP 延申讨论至 ES6 的 import export 。以及 module bundler 的应用,例如 webpack 和 browserify
    famanoder
        2
    famanoder  
    OP
       2016-12-09 17:37:43 +08:00
    @xiamx 可以到我站点看看,有些简单的总结
    http://famanoder.com
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2716 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 12:39 · PVG 20:39 · LAX 04:39 · JFK 07:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.