zoukankan      html  css  js  c++  java
  • JS模块化进程

    js的模块化进程

    现在前端技术日新月异,对于同一个问题痛点,各个时段有各自的解决方案,这就带来了很大差异。今天我就打算梳理js模块化的历史进程,讲一讲这些方案要做什么,怎么做。

    js模块化进程的起因

    现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。当一个项目开发的越来越复杂的时候,你会遇到一些问题:命名冲突(变量和函数命名可能相同),文件依赖(引入外部的文件数目、顺序问题)等。

    javascript发展的越来越快,超过了它产生时候的自我定位。这时候js模块化就出现了。

    什么是模块化

    模块化开发是一种管理方式,是一种生产方式,一种解决问题的方案。他按照功能将一个软件切分成许多部分单独开发,然后再组装起来,每一个部分即为模块。当使用模块化开发的时候可以避免刚刚的问题,并且让开发的效率变高,以及方便后期的维护。

    js模块化进程

    一、早期:script标签

    这是最原始的 JavaScript 文件加载方式,如果把每一个文件看做是一个模块,那么他们的接口通常是暴露在全局作用域下,也就是定义在 window 对象中。

    缺点: 
    1.污染全局作用域 
    2.只能按script标签书写顺序加载 
    3.文件依赖关系靠开发者主观解决

    二、发展一:CommonJS规范

    允许模块通过require方法来同步加载(同步意味阻塞)所要依赖的其他模块,然后通过module.exports来导出需要暴露的接口。

    // module add.js
    module.exports = function add (a, b) { return a + b; }
    
    // main.js
    var {add} = require('./math');
    console.log('1 + 2 = ' + add(1,2);

    CommonJS 是以在浏览器环境之外构建JavaScript 生态系统为目标而产生的项目,比如在服务器和桌面环境中。

    三、发展二:AMD/CMD

    (1)AMD

    AMD 是 RequireJS 在推广过程中对模块定义的规范化产出(异步模块定义)。

    AMD标准中定义了以下两个API:

    1. require([module], callback);
    2. define(id, [depends], callback);

    require接口用来加载一系列模块,define接口用来定义并暴露一个模块。

        define(['./a', './b'], function(a, b) {  
            // 依赖必须一开始就写好   
            a.add1()    
            ...  
            b.add2()    
            ...
        }) 

    优点: 
    1、适合在浏览器环境中异步加载模块 2、可以并行加载多个模块

    (2)CMD

    CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。(在CommomJS和AMD基础上提出)

    define(function (requie, exports, module) { 
        //依赖可以就近书写 
        var a = require('./a'); 
        a.add1(); 
        ... 
        if (status) { 
            var b = requie('./b'); 
            b.add2(); 
        } 
    }); 

    优点: 
    1、依赖就近,延迟执行 2、可以很容易在服务器中运行

    (3)AMD 和 CMD 的区别

    AMD和CMD起来很相似,但是还是有一些细微的差别:

    1、对于依赖的模块,AMD是提前执行,CMD是延迟执行。

    2、AMD推崇依赖前置;CMD推崇依赖就近,只有在用到某个模块的时候再去require。

    3、AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一

    四、发展三:ES6模块化

    EcmaScript6 标准增加了JavaScript语言层面的模块体系定义。

    在 ES6 中,我们使用export关键字来导出模块,使用import关键字引用模块。

    // module math.jsx
    export default class Math extends React.Component{}
    
    // main.js
    import Math from "./Math";

    目前很少JS引擎能直接支持 ES6 标准,因此 Babel 的做法实际上是将不被支持的import翻译成目前已被支持的require。

  • 相关阅读:
    Hibernate之二级缓存
    Hibernate之HQL
    Hibernate 一对多自关联 多对多
    hibernate关联关系(一对多)
    Hibernate之主键生成策略
    Hibernate01
    struts的图片上传
    HashMap和HashTable本质性的区别
    集合03
    集合
  • 原文地址:https://www.cnblogs.com/ZpandaZ/p/7397129.html
Copyright © 2011-2022 走看看