JavaScript模板化

114 阅读4分钟

一、模块化概述

1.1. 什么是模块化?

  • 将程序文件依据一定规则拆分成多个文件,这种编码方式就是模块化的编码方式。
  • 拆分出来每个文件就是一个模块,模块中的数据都是私有的,模块之间互相隔离。
  • 同时也能通过一些手段,可以把模块内的指定数据“交出去”,供其他模块使用。

1.2. 为什么需要模块化?

随着应用的复杂度越来越高,其代码量和文件数量都会急剧增加,会逐渐引发以下问题:

1.全局污染问题

2.依赖混乱问题

3.数据安全问题

二、导入与导出的概念

模块化的核心思想就是:模块之间是隔离的,通过导入和导出进行数据和功能的共享。

导出(暴露):模块公开其内部的一部 (如变量, 函数等),使这些内容可以被其他模块使用。

导入(引入):模块引用和使用其他模块导出的内容,以重用代码和功能。

图片1.png

三、模块化实例

1.创建School.js 图片2.png 2.创建Student.js 图片3.png 3.创建index.js 图片4.png 4.导出数据 导出数据的方式有两种

  •  第一种方式:module.exports = value

  •  第二种方式:exports.name = value

5.导入数据 使用内置的request模块导入数据 图片5.png

四、规范

1.CommonJS

CommonJS是一种面向服务器端的模块化规范,它规定一个文件就是一个模块,使用require()导入模块,使用module.exports导出模块。

var moduleB = require('./moduleB');
module.exports = {
    stuff: moduleB.doStuff();
};

require()的返回值就是module.exports导出的对象。

  1. 缓存加载 首次require一个模块时,会加载并执行该模块文件,并返回模块的module.exports值,该值会被缓存。下次require该模块时,取的是缓存数据,不需要再加载执行模块了。

  2. 拷贝导出 require()返回的是模块导出对象的拷贝,也就是说,模块内部的变化不会影响已导出的对象。

  3. 同步加载 CommonJS使用同步加载,这并不适用浏览器端,因为网络延迟会阻塞页面渲染。

  4. 浏览器加载CommonJS npm模块是遵循CommonJS的,不能直接在浏览器运行,需要做格式转换。

小结

CommonJS规定每个文件是一个模块,使用require()导入模块,使用module.exports导出模块。其中,还使用了缓存加载和拷贝导出。

CommonJS使用同步加载,这不适用浏览器,因为网络延迟会阻塞页面渲染。

npm模块是遵循CommonJS的,不能直接在浏览器运行,需要做格式转换。

2.AMD

AMD是一种面向浏览器端的模块化规范,使用异步加载,并在依赖加载后再回调执行入口模块。

定义模块:

define('moduleA', ['moduleB', 'moduleC'], function factory(moduleB, moduleC){
    let nameB = moduleB.getName();
    let nameC = moduleC.getName();
    let name = nameB + nameC;
    return {
        getName: function(){
            return name;
        }
    }
})

define()的第一个参数是模块标识符。第二个参数是依赖。第三个参数是模块工厂函数,用来封装模块。

导入模块:

require( ['moduleB', 'moduleC'], function main(moduleB, moduleC){
    let nameB = moduleB.getName();
    let nameC = moduleC.getName();
    let name = nameB + nameC;
    console.log(name);
})

3.ES6 Module

ES6 Module是JavaScript语言标准的模块化方案,浏览器和node环境都是原生支持的,不需要格式转换。

 1.ES6 Module加载模块

在ES6 Module中使用import导入模块,使用export导出模块。

import moduleA from 'moduleA'
export default {
    name:'moduleB'
}

在编译阶段,根据import/export构建模块依赖关系,即模块地图sourceMap,每个节点保存了模块导出变量的内存地址和模块加载状态。
在运行阶段,执行模块时先更新节点的模块加载状态,遇到import时,则从模块地图中获取到对应模块导出变量的内存地址。

2.浏览器加载ES6 Module

<script type="module">
</script>
<script type="module" src="module path"></script>

在 script中设置type="module"属性,浏览器就会当作模块处理,而不是普通的脚本文件。

script type=“module”跟script defer一样使用异步加载,然后延迟到文档解析完成后再按顺序执行脚本。

五、总结

随着用户体验要求变高,前端承载的功能变多了,代码量也随着膨胀。

为了提高代码的可复用性,开发者采用了模块化思想并利用JavaScript语言特性进行模块化实践,包括命名空间,函数作用域,闭包等。

同时,诞生了CommonJS,AMD和ES6 Module等模块化规范。其中,前两者是社区版本的,分别是面向服务器端和浏览器端的规范。而ES6 Module是JavaScript语言标准,将会逐步成为统一的模块化规范。