模块化编程
1.什么是模块
在node.js中,所谓的模块,就是一个文件,通常是js文件或json文件。
换言之,一个js文件就是一个模块。
模块是Node.js应用程序的基本组成部分。
2.为什么需要模块机制?
回顾一下,在浏览器为何需要模块化?
主要是解决两大问题:
全局变量污染
繁琐的文件依赖
到了服务端,情况是有些不同的。
在服务端,只有js代码,没有html。所以在服务端不可能借助script标签来引入js文件。
如何在一个js文件中,引入其他的js文件,需要一种机制来完成,这种机制就是模块机制。
为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统。
可以稍微回顾一下,模块化的发展简史:
萌芽时代,使用的编程技巧
09年Node.js在出现,实现了commonjs规范
三大派系之保守派,遵循了commonjs规范,提出了browserify工具
三大派系之革新派,提出了AMD规范,推出了require.js
三大派系之中立派,提出了CMD规范,推出了sea.js
es6,自己实现了export和import的模块化
而且,在node.js也会支持es6的模块化。
什么是CommonJs?
官方:
CommonJs规范主要弥补当前JavaScript没有标准的缺陷,它的终极目标是提供一个类似Python,Ruby和Java标准库。
- CommonJs 是 JavaScript 语言的模块化规范
- CommonJs 是模块化的标准,nodejs是CommonJs(模块化)的实现
CommonJs 是一种 JavaScript 语言的模块化规范,它通常会在服务端的 Nodejs 上使用。项目是由多个模块组成的,模块和模块之间的调用,需要各个模块有相同规范的 API,这样一来在使用的过程中不会有那么多的学习成本,并且对于单个模块来说是类聚的。
CommonJS模块的特点。
- 代码在模块作用域,不会污染全局作用域。
- 第一次加载某个模块时,Node会缓存该模块。以后再加载该模块,就直接从缓存取出该模块的module.exports属性。
- 模块加载的顺序,按照其在代码中出现的顺序。
模块化规范给项目带来极大的好处,在业务复杂,模块众多的大型项目中,开发者都遵循相同的规则来开发各自的模块,通过模块规范来约束,大家不需要太多的沟通或者大量的文档来说明自己的模块使用规则,成千上万的模块就这样生产,并能够容易的使用。它的意义不仅是让模块看起来很规范,在合作开发、社区中传播中也起到了重大的作用
模块规范
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
CommonJS规范规定,每个模块内部,module变量代表当前模块。
这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。
加载某个模块,其实是加载该模块的module.exports属性。
CommonJS模块规范主要分为三部分:模块引用、模块标识、模块定义。
模块引用
require命令的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。如果没有发现指定模块,会报错。(说白了就是将另一个文件中暴露的值,引用到本文件中。)
var math = require("math");
require命令用于加载文件,后缀名默认为.js。
模块标识
模块引入没有带路径,引用的是当前所在目录下的node_modules目录。
var math = require("math");
模块引入的有其他路径,就需要使用到相对路径或绝对路径。
var add = require('./add.js')
模块定义
- module对象:在每个模块中,module对象代表该模块本身。
- export 属性:module对象的一个属性,他向外提供接口。
require 规则
- / 表示绝对路径,./ 表示相对于当前文件的。
- 支持js、json、node扩展名,不写后缀则依次尝试。
- 不写路径则认为是模块或者各级node_modules内的第三方模块。
require 特性
- module 被加载的时候执行,加载后缓存。
- 一旦出现某个模块被循环加载,只输出已经执行的部分,还未执行的部分不会输出。(避免这种写法)
例子:
//comon.js代码
const text = "非凡主力";
function add(num1, num2){
return console.log(num1+num2);
}
module.exports.add = add;
module.exports.text = text;
//或
module.exports = {add,text}
引用
// index.js
var com = require('./comon.js'); //引入
com.add(2,3); //调用
let txt = com.text;
console.log(txt);
common.js 总结
- 每个文件是一个模块,有自己的作用域。
- 在模块内部 module 变量代表模块本身。
- module.exports 属性代表模块对外接口。
ES6 的 导入导出
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
导出:export
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export { firstName, lastName, year };
导入:import … from
// main.js
import { firstName, lastName, year } from './profile.js';
function setName(element) {
element.textContent = firstName + ' ' + lastName;
}
需要使用babel转换
结束语:
台下人走过,不见旧颜色,台上人唱着心碎离别歌。