什么是模块化?

发布于 24 天前  87 次阅读 本文共2353个字


模块化, 就是把一个复杂的系统分解到多个模块以方便编码。

命名空间

开发网页呢,要通过命名空间的方式来组织代码

<script src="vue.js">
  • 命名空间冲突,两个库可能会使用同一个名称
  • 无法合理地管理项目的依赖和版本;
  • 无法方便地控制依赖的加载顺序。

模块分类

1、原生模块

http path fs util events 编译成二进制,加载速度最快,原来模块通过名称来加载

2、文件模块

在硬盘的某个位置,加载速度非常慢,文件模块通过名称或路径来加载 文件模块的后缀有三种

  • 后缀名为.js的JavaScript脚本文件,需要先读入内存再运行
  • 后缀名为.json的JSON文件,fs 读入内存 转化成JSON对象
  • 后缀名为.node的经过编译后的二进制C/C++扩展模块文件,可以直接使用一般自己写的通过路径来加载,别人写的通过名称去当前目录或全局的node_modules下面去找

3、第三方模块

  • 如果require函数只指定名称则视为从node_modules下面加载文件,这样的话你可以移动模块而不需要修改引用的模块路径
  • 第三方模块的查询路径包括module.paths和全局目录

3.1、全局目录

window如果在环境变量中设置了NODE_PATH变量,并将变量设置为一个有效的磁盘目录,require在本地找不到此模块时向在此目录下找这个模块。 UNIX操作系统中会从 $HOME/.node_modules $HOME/.node_libraries目录下寻找。

4、模块的加载策略 

5、文件模块查找规则


下边我们来说几种常见模块化

1、CommonJS

CommonJS 是一种使用广泛的JavaScript模块化规范,核心思想是通过require方法来同步地加载依赖的其他模块,通过 module.exports 导出需要暴露的接口,具体规范特点如下:

  • 封装功能
  • 封闭作用域
  • 可能解决依赖问题
  • 工作效率更高,重构方便

Node中的CommonJS:

  • 在node.js 里,模块划分所有的功能,每个JS都是一个模块
  • 实现require方法,NPM实现了模块的自动加载和安装依赖

用法 :

// 导入 
const someFun= require('./moduleA'); 
someFun(); 

// 导出 
module.exports = someFunc;

原理:

举例说明:

// A.js
let fs = require('fs');
let path = require('path');
let b = req('./B.js');
function req(mod) {
    let filename = path.join(__dirname, mod);
    let content = fs.readFileSync(filename, 'utf8');
    let fn = new Function('exports', 'require', 'module', '__filename', '__dirname', content + '\n return module.exports;');
    let module = {
        exports: {}
    };

    return fn(module.exports, req, module, __filename, __dirname);
}
// B.js
console.log('hello world');
exports.name = 'kris';

2、AMD

AMD 也是一种 JavaScript 模块化规范,与 CommonJS 最大的不同在于它采用异步的方式去加载依赖的模块。 AMD 规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是 requirejs。

AMD 的优点

  • 可在不转换代码的情况下直接在浏览器中运行
  • 可加载多个依赖
  • 代码可运行在浏览器环境和 Node.js 环境下

AMD 的缺点

  • JavaScript 运行环境没有原生支持 AMD,需要先导入实现了 AMD 的库后才能正常使用。

用法:

// 定义一个模块
define('a', [], function () {
    return 'a';
});
define('b', ['a'], function (a) {
    return a + 'b';
});
// 导入和使用
require(['b'], function (b) {
    console.log(b);
});

原理:

let factories = {};
function define(modName, dependencies, factory) {
    factory.dependencies = dependencies;
    factories[modName] = factory;
}
function require(modNames, callback) {
    let loadedModNames = modNames.map(function (modName) {
        let factory = factories[modName];
        let dependencies = factory.dependencies;
        let exports;
        require(dependencies, function (...dependencyMods) {
            exports = factory.apply(null, dependencyMods);
        });
        return exports;
    })
    callback.apply(null, loadedModNames);
}

3、ES6 模块化

ES6 模块化是ECMA提出的JavaScript模块化规范,它在语言的层面上实现了模块化。浏览器厂商和Node.j都宣布要原生支持该规范。它将逐渐取代CommonJSAMD`规范,成为浏览器和服务器通用的模块解决方案。 采用 ES6 模块化导入及导出时的代码如下

用法:

// A 导入
import { name } from './B.js';

// B 导出
export const name = 'kris';

努力,只为遇见更好的自己!