首页 > 代码库 > node.js的模块化介绍
node.js的模块化介绍
1. 模块化介绍
1.1. 由于JavaScript不是一个模块化语言,存在两大缺陷:
a、文件中的代码会造成全局污染;
b、 依赖的加载顺序无法完全保证,例如jquery插件要在引入jquery后引入。
1.2. Node中的模块化:
a、 文件天生就是一个私有的作用域
b、 文件与文件之间通过特定的规则进行交互(导入导出)
c、 程序最终由n个文件组成整个应用程序
d、 在每个模块内部,module代表当前模块,这个对象有一个属性exports,通过require函数加载这个模块,其实就是在加载某个模块,也就是该模块的module.exports接口。
2. Node中的模块分类
2.1. 核心模块https://nodejs.org/en/docs/
就是node中的内置模块,例如fs,http等,其加载速度最快,因为已经被编译到node程序中了,每个模块都提供了一个唯一的核心标识名称,所以加载规则都一样
Var 变量名=require(‘核心模块名’)
1.2. 第三方模块
第三方模块就是由社区提供的模块(通常是npm),有将近35万个之多,通过在使用的时候都遵循以下三步:
a、 通过 npm 下载到项目中;
b、 通过 require 函数加载下载的第三方模块;
c、 查阅第三方模块的文档;
以marked为例(提供将markdown格式字符串转为HTML格式字符串的功能)
a、npm install marked
b、var marked = require(‘marked’)
c、console.log(marked(‘# hello world’))
d、输出结果为:<h1>hello world</h1>
1.3. 用户自定义模块
用户模块就是用户自己编写的文件模块,通常是一个文件或者多个文件组成。
例如以下简单的加减功能
在cal.js文件中
function add(x,y){ return x+y; }; function minus(x,y){ return x-y; } module.exports.add=add; module.exports.minus=minus;
在app.js文件中
var cal = require(‘./cal)
2.4.模块化特点总结
a、所有代码都运行在模块作用域,不会污染全局作用域
b、模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存起来了,以后再加载,就直接读取缓存结果
c、模块加载的顺序,按照其在代码中出现的顺序
d、 module.exports 是模块的对外导出接口,其它文件加载该模块,实际上就是读取 module.exports
通过 require 函数加载别的模块,加载模块的过程实际上就是执行被加载模块中的代码,得到被加载模块的 module.exports 接口对象
3. exports和module.exports
为了方便,Node为每个模块提供了一个 exports 属性,指向 module.exports ,也就是说可以通过修改 exports 从而修改 module.exports
3.1. 如果需要向外只导出一个变量、例如一个函数、字符串、数字等,则必须通过为 module.exports 赋值才可以。
注意:为 exports 赋值是不管用的,因为每个模块最终对外到处的接口是 module.exports,而 exports 只是 module.exports 的一个引用,所以一旦给 exports 赋值,就切断了两者之间的引用关系,赋的值也就不管用了。
总结:如果希望向往导出多个接口成员,则可以使用 exports 添加属性成员方便的对外导出。
但是如果想要向外部提供一个单一的字符串、函数、数组等接口数据,则必须通过为 module.exports 赋值。(给 exports 赋值是不管用的)。
4. require 函数加载模块规则流程
require 函数接收的值被称作模块标识符,可能是一个核心模块标识名,也可能是一个第三方模块,也可能是一个相对路径形式的文件路径。在指定文件模块的时候,可以省略文件名后缀,当省略了文档名后缀之后,node 会以 .js、.node、.json 依次尝试补足。
下面是详细的加载规则:
4.1. 优先从缓存加载
4.2. 标识符分析
a、如果是核心模块,直接加载
b、如果是用户模块,即以 ./ 或者 ../ 开始的标识符或者绝对路径形式的模块,则直接加载
c、如果是第三方模块,则相对于当前模块找 node_modules 目录
d、找到 node_modules 目录之后,找与被加载模块同名的目录
e、如果找到,则找 package.json 文件,如果找到 package.json 文件,则找文件的 main 属性,如果找到 main 属性,则直接加载
f、如果没有 package.json 文件或者没有 main 属性或者 main 属性指定的文件模块不存在,则默认加载该目录中的 index.js、index.node、index.json
g、以上条件任何一个不成立,则直接进入上一级目录找 node_modules 目录,规则同上,直到找到当前文件模块所属磁盘根目录如果还找不到,则直接报错:can not find module xxx
node.js的模块化介绍