zoukankan      html  css  js  c++  java
  • 自研模块加载器(一) 模块系统概述与自定义模块规范书写规定

    模块系统概述

    CommonJs/AMD/CMD/ES6 Modules

    什么是模块化?

    模块化就是把系统分离成独立的功能的方法,需要什么功能,就加载什么功能

    当一个系统越来越复杂时候,我们会遇到这些问题

    1. 命名冲突

    2. 文件依赖

    使用模块化开发可以避免以上问题,并提升开发效率

    1. 可维护性

    2. 可复用性

    在生产角度,模块化是一种生产方式,这种生产方式效率高,维护成本低。

    模块化开发演变

    1. 全局函数

    早期开发中,将重复的代码封装成函数,将多个函数放在一个文件中。 缺点: 污染全局变量,看不出相互的直接关系

    2. 通过对象命名的方式

    通过对象命名的形式,从某种程度上减少了变量命名冲突,但是不能从根本上解决。 缺点:内部变量可被外部改写,命名空间越来越长

    3. 私有共有成员分离

    利用此方式将函数包装成了独立的作用域,私有空间变量函数不会影响全局。 缺点:解决的变量冲突的问题,但是没有解决降低开发复杂度的问题。

    CommonJS

    CommonJS加载是同步的,也就是说加载完成才能执行后面的操作。

    Node.js主要用于服务器编程,模块都是存储在本地硬盘中,加载速度快,所以Node.js 采用CommonJS规范。

    CommonJS规范为三部分: Module(模块标识)、Require(模块引入)、Exports(模块定义)

    Module变量在每个模块内部,就代表当前模块

    Exports属性是对外接口,用于导出模块的变量和方法

    Require()用来加载外部依赖,读取并执行JS, 返回该模块的Exports对象

    AMD (RequireJS)

    AMD也就是异步模块定义。它采用异步的方式加载模块,通过Define的方式定义模块,require方法加载模块。

    定义模块:

    define([tools], function(){})

    如果该模块还依赖其他模块,则第一个参数以数组的形式传入依赖模块,第二个参数为自定义模块

    AMD模块加载

    require(['modules'],callback);

    第一个参数 'modules' 为要加载的成员,因为是AMD异步的,所以第二个参数为模块加载完成后的回调

    CMD (sea.js)

    CMD即通用模块定义。CMD是国内发展出来的规范,Sea.js实现来这个规范。

    在CMD规范中,一个模块就是一个文件,代码书写如下:

    define(function(require, exports, module ) {
    })

    CMD推崇依赖就近,延迟执行,文件是提前加载好,只有在require的时候才去执行。

    define(function(require, exports, module ) {
        var math = require('./math');
        math.add();
    })

    ES6模块化

    语法简介,支持异步加载,未来可以成为浏览器和服务器通过的模块化解决方案。

    ES6模块的定义:

    新增 'import' 和 'export' 两个关键字

    export用于暴露模块功能, import 用于引入模块提供的功能

    import { foo, obj } from './lib'; // 引入模块功能
    foo();//  使用方法
    
    
    
    const foo1 = function() {}
    //  导出默认 export default foo1;
    export { foo1 }

    ES6模块运行机制:

    ES6 模块是动态引用,如果使用import 从一个模块加载变量(import foo from 'lib'),变量不会被缓存,而是成为一个指向被加载模块的一个引用。 等到脚本执行时,根据只读引用,到那个被加载的模块中取值。

    自定义模块规范(书写约定)

    自定义加载器

    模块的定义:

    1. 约定:所有的Javascript文件都应该用模块的形式来书写,并且一个文件只能包含一个模块;

    2. 使用全局函数define来定义模块 define(factory[require,exports,module]));

    3. factory函数在调用时,会始终传递三个参数: require,exports和module, 这三个参数在所有的模块代码里可以用

    define(function(require, exports, module)) {
      // 模块代码  
    })

    模块加载器会从factory.tostring()中解析出来当前模块依赖的模块, 它是一个由模块标识组成的数组。

    exports用来向外提供模块的api || 使用return直接向外提供api

    require 函数用来访问其他模块提供的api

    module 参数存储模块的元信息(id是模块的唯一标识, deps依赖泪奔 exports对外提供的接口对象)

    注意:

    1. 在模块代码中, 第一个参数必须命名为 require

    2. 不要重命名require函数,或在任何作用域中给require重新赋值

    3. require的参数值必须是字符串直接量,不能是表达式。

  • 相关阅读:
    如何探索汽车后市场B2B和B2C商业模式?
    当下汽车后市场现状是什么的样?
    怎样解释汽车后市场是什么?
    全球第一开源ERP Odoo操作手册 数据库简介 增加预读提升Odoo文件读取性能
    全球第一开源ERP Odoo操作手册 数据库自动备份
    全球第一开源ERP Odoo操作手册 启用多核来提升Odoo性能
    全球第一开源ERP Odoo操作手册 使用Nginx Upstream来优化Odoo的网络传输性能
    全球第一开源ERP Odoo操作手册 安装ssh服务和ssh客户端
    DES对称加密
    linux下安装python3.7
  • 原文地址:https://www.cnblogs.com/zzd0916/p/12232913.html
Copyright © 2011-2022 走看看