工程化模式-进阶

幼年期:无模块化

成长期: IIFE立即执行函数表 IIFE其实也就是匿名函数,归根结底都是函数

一种是申明式,一种是表达式。但是两种其实存在着不同,其中第二种中存在着变量提升

function fn1()
var fn  = function ()

var b = 1 ;
(function () {
    var b = 2
    console.log('b的值',b);
 })()
console.log(b);

成熟期

CJS- commonj =>node.js 制定

特征:通过module+export去对外暴露接口,一个js文件就是一个模块

引入自定义模块

     使用require('模块的路径')函数来引入模块

     引入自定义模块时

             模块名要以 ./或../开头

             扩展名可以省略

  •      在CommonJS中,如果省略的js文件的扩展名,node会自动补全扩展名
    • 如果没有改js文件,会找名字相同的文件进行引入
  • 引入核心模块时

    • 直接写核心模块的名字即可
    • 也可以在核心模块前添加node:可以加快查询效率
//引入自定义模块
const m1 = require("./m1")
//按需引入
const name = require('./m1').name
const {name,age,gender} = require('./m1')
//引入核心模块
 const path = require("path")
 const path = require("node:path")

通过require进行其他模块的调用

const depModele1 =require('./dependecncyModules1')
const depModule2 =require('./dependecncyModuse2')
let count =0
const obj ={
  increase:()=>++count;
  reset()=>{
   count=0
  }
}
exports.increase= increase;
exports.insert=reset
module.export={
  increase,
  reset
}
> * 优点:
CJS率先在服务实现了从框架层面解决依赖、模块化的问题

* 缺憾
针对的是服务端,对于异步依赖没有很友好地处理解决

AMD 规则

它采用异步方式加载模块 。实现了AMD规范的主要的两个JavaScript的两个库:require.js和curl.js

AMD跟CommonJS一样也是通过require来导入,但是区别在于多了一个回调参数。用于导入后执行函数。

> 通过异步加载 + 允许定制回调函数
经典框架:require.js
新增定义方式:
```js
    define(id, [depModule], callback);
    require([module], callback);

    // 栗子 提前声明要依赖的模块
    define('amdModule', [depModule1, depModule2], (depModule1, depModule2) => {
        let count = 0;
        const obj = {
            increase: () => ++count;
            reset: () => {
                count = 0;
                // fn(depModule1);
                // depModule1, depModule2
            }
        }
        // ....
    })

    // 使用
    require(['amdModule'], amdModule => {
        amdModule.increase();
    })
```

UMD规则

  1. factory 可以是一个函数或者字符串或者对象。
  2. 如果 factory 是一个函数,回调函数中会指定三个参数 require,exports,module,表示的是该模块的构造函数。执行构造函数,可以得到模块向外提供的接口。
** 面试:一个代码去兼容AMD和CJS **
```js
    (function(){
        // UMD的出现
    })(
    // 目标:一次性去区分CJS和AMD
        // 1. CJS factory
        // 2. module & module exportsx
        // 3. define
        typeof module === "Object"
            && module.exports
            && typeof define !== "function"
                ? // 是CJS
                    factory => module.export = factory(require, exports, module);
                : // 是CMD
                    define
    )
```
> * 优点:解决了浏览器中异步加载模块,可以并行加载多个模块
* 缺点:会有引入成本,缺少考虑按需加载
```js
    (function (root, factory) {
        if (typeof define === 'function' && define.amd) {
            // AMD
            define(['jquery', 'underscore'], factory);
        } else if (typeof exports === 'object') {
            // Node, CommonJS之类的
            module.exports = factory(require('jquery'), require('underscore'));
        } else {
            // 浏览器全局变量(root 即 window)
            root.returnExports = factory(root.jQuery, root._);
        }
    }(this, function ($, _) {
        // 属性
        var PI = Math.PI;
        
        // 方法
        function a() { };                   // 私有方法,因为它没被返回
        function b() { return a() };        // 公共方法,因为被返回了
        function c(x, y) { return x + y };  // 公共方法,因为被返回了
    
        // 暴露公共方法
        return {
            ip: PI,
            b: b,
            c: c
        }
    }));

```

CMD规范 - sea.js

> 按需加载
```js
    define('module', (require, exports, module) => {
        let $ = require('jquery');
        let depModule1 = require('./dependencyModule1');
        // ……
    })
```

新时期:ESM

import : 引入 ,export :导出

```js
    import depModule1 from './dependecncyModule1';
    import depModule2 from './dependecncyModule2';

    let count = 0;
    const obj = {
        increase: () => ++count;
        reset: () => {
            count = 0;
            // fn(depModule1);
            // depModule1, depModule2
        }
    }


    export default {
        increase,
        reset
    }

    // 异步加载
    import('xxx').then(a => {
        // ../
    })
```

目标:
1. 隔离每个模块的逻辑和作用域
2. 扩展共同协作的方便程度

=> 可以将无数模块进行随意组装 => 万物皆模块
=> 前端工程化

你可能感兴趣的:(前端,javascript,开发语言)