js模块化的一些了解

312 阅读3分钟

什么是代码模块化?

将一个复杂的应用程序依据一定的规则(规范)封装成几个块(文件),并组合在一起;块的内部数据/实现是私有的,只是向外部暴露一些接口与其他模块进行通信。

为什么要有js模块化?

由于最早js应用功能简单,代码都是写在一个文件或者一个全局作用域内;但随着js应用愈来愈复杂,代码量越来越大,这时代码就变得难以维护,耦合度高,功能区划不清,易命名冲突而污染全局环境。所以就要有模块化。

js模块化前期发展的几个阶段:

第一阶段:全局function模式

此时函数和变量直接定义在全局作用域内,易产生全局污染。

image.png

第二阶段:namespace模式(命名空间)

此时函数和变量挂载在全局对象的属性上,不会污染全局环境,但也能通过修改对象的属性而被篡改。

image.png

第三阶段:IIFE模式(立即执行函数,闭包)

此时变量声明在函数的局部作用域内,是函数私有的,且不易被篡改。

image.png

第四阶段:IIFE模式增强:引入依赖

如下,引入并使用jQuery

image.png

第五阶段:load script

多个script标签,会导致发送多次请求,依赖关系模糊,难以维护。

image.png

js模块化现在常用的几个规范

一. commonJs

Commonjs规范主要实现在node应用中,模块是同步加载的。

基本语法

暴露模块:1. module.exports = value;  2. exports.xxx = value;
引入模块: var some_name = require(xxx);  其中,如是第三方模块’xxx’为模块名,如是自定义模块’xxx’为文件路径。

暴露模块的理解:导出的实际上是exports对象,module.exports是赋值给exports自身,exports.xxx是赋值给exports的一个属性

image.png

image.png

image.png

二.AMD(异步模块定义 Asynchronous Module Definition)

amd规范的一个实现是require.js库,专门用于浏览器端,模块加载是异步的。

基本语法

定义暴露模块:

  1. 没有依赖的模块
    define(function(){

       return 模块

})
2. 有依赖的模块
define(['module1', 'module2'], function(m1, m2){

       return 模块

})

引入使用模块
requirejs([“module1”, “module2”], function(m1, m2){

       使用m1/m2

})

requirejs的使用还需定义一个主文件,也是入口文件,主要是配置模块名与模块路径的映射:

image.png
只需要引入一个js文件
image.png
目录结构
image.png

三.CMD(通用模块定义 Common Module Definition)

cmd规范的一个实现是sea.js库,专门用于浏览器端,模块加载是异步的。

基本语法(结合了commonjs和amd)

定义没有依赖的模块:
define(function(require, exports, module){

       // 导出模块

       exports.xxx = value;

       module.exports = value;

})
定义有依赖的模块:
define(function(require, exports, module){

       // 同步引入模块

       var module2 = require(“./module2”);

       // 异步引入模块

       require.async(“./module3”, function(m3){

    })

})
引入使用模块:
define(function(require){

       var m1 = require(“./module1”);

       m1.show();

})

2个script标签
image.png

amd和cmd的区别:cmd是就近依赖,模块使用时才会加载执行;amd是前置依赖,模块提前加载执行。

四.ES6规范

es6模块导出和导入分别是export和import关键字。

(一). 模块导出

模块导出分为2种:命名导出默认导出

  1. 命名导出(理解:导出的模块实际上是一个容器对象,实际导出的值都存储在这个容器对象的属性上,导入时需要从这个容器对象取得对应的属性)
    命名导出可用2种方式:分别暴露和统一暴露,主要区别如下:
    image.png

image.png

  1. 默认导出
    使用default关键字,并且一个文件只能有一个默认导出
    image.png

(二). 模块导入

语法: import xxx from '路径'
当模块为命名导出时,xxx需为对象解构赋值的形式;当模块为默认导出时,xxx为任意变量名的形式。当为第三方模块时,‘路径’为模块名。

image.png

ts模块

在ts中,模块的语法还可以有如下形式:
导出模块:export = 模块名;
导入模块: import module = require(路径);

参考链接:www.bilibili.com/video/BV18s…