1. Node.js中的模块化简介
- 为什么Node.js中需要模块化
在后台开发语言中,比如Java、C#。他们都是隐含模块化的,Node.js默认帮我们提供了模块化这种机制。 在服务器端,我们想要使用底层的一些功能需要导入一些“包”来对其操作,比如操作文件、网络需要导入对应的包。其它语言中都是基于类来实现的模块化的思想,使用类来组织文件和文件之间的关联。 而Node.js中使用的是JavaScript语言,ECMAScript仅仅规定了基本的语法的书写,并没有规定文件之间 关联,也就是说每个js文件之间是独立的,Node.js已经帮我们实现了js文件之间的关联(模块化) Node.js中的模块化是基于CommonJS规范的
- JavaScript的局限性
- 没有模块系统
- 系统提供的接口较少,比如:缺少操作文件、I/O流等常用的接口
- 没有标准接口,缺少如web服务器、数据库等统一接口
- 缺乏管理系统导师JavaScript应用中基本没有自动加载和安装依赖的能力
- CommonJS规范
- Node.js开发之初遵守了CommonJS规范
- 使JavaScript达到像Java、Python、PHP等语言一样有开发大型应用的基本能力
- CommonJS规范规定每一个模块都有一个单独的作用域
- CommonJS规范规定每个模块对外公布的成员使用module.exports或者exports
- 有了模块化系统之后,Node.js提供了许多系统模块:文件、Buffer、I/O流、Socket等
2. Node.js的核心模块
-
使用核心模块之前首先要导入模块
-
path模块
- 导入模块 var path = require("path");
-
basename() 获取文件名+后缀
path.basename("/foo/hello/world/123.html") //第二个参数,去掉获取的文件名中的相同部分 path.basename("c:/foo/hello/world/123.html",".html")
-
dirname() 获取目录
path.dirname("/foo/hello/world/123.html")
-
extname() 获取文件的扩展名
path.extname("/foo/hello/world/123.html")
-
join() 合并路径
var p1 = "c://abc/xyz"; var p2 = "/123/456"; console.log(path.join(p1,p2));
-
parse() 把路径转换为一个对象
path.parse("c:\\home\\hello\\world\\123.html") { root: 'c:/', dir: 'c://home/hello/world', base: '123.html', ext: '.html', name: '123' }
-
format() 把一个路径对象转换成一个路径字符串
var obj = { root: 'c:\\', dir: 'c:\\home\\hello\\world', base: '123.html', ext: '.html', name: '123' } console.log(path.format(obj));
-
delimiter 环境变量的分隔符,可以跨平台 windows下是; 其它平台 :
- path.sep 路径的分隔符 windows下是\ 其它下是/
- isAbsolute() 是否是绝对路径
-
url模块
- 导入模块 var url = require("url");
-
parse() 把字符串的路径转换成对象
var uri = "http://www.baidu.com:8080/images/1.jpg?version=1.0&time=1123#abcd"; console.log(url.parse(uri));
-
format() 把路径对象转换成字符串
var obj = { protocol: 'http:', slashes: true, auth: null, host: 'www.baidu.com:8080', port: '8080', hostname: 'www.baidu.com', hash: '#abcd', search: '?version=1.0&time=1123', query: 'version=1.0&time=1123', pathname: '/images/1.jpg', path: '/images/1.jpg?version=1.0&time=1123', href: 'http://www.baidu.com:8080/images/1.jpg?version=1.0&time=1123#abcd' }; var str = url.format(obj); console.log(str);
-
querystring模块
- 导入模块 var querystring = require("querystring");
-
parse() 把参数字符串解析成对象
var obj = querystring.parse("version=1.0&time=123"); console.log(obj);
- stringify() 把一个对象转换成一个字符串
- escape() url进行编码
- unescape() url进行解码
3. 核心模块存在哪里?
- 核心模块存储在node.exe中,当node.exe运行的时候,核心模块会被加载,require的时候会加载到内存
- 在github上可以找到源代码,lib文件夹下
- 核心模块的执行速度比较快
4. 文件模块(自定义模块)
-
定义文件模块 add.js
function add(a,b) { return a + b; } //导出成员 exports.add = add; //module.exports.add = add;
-
使用文件模块 main.js
var obj = require("./add.js"); console.log(obj.add(5,6));
- 注意引用js的方式和核心模块不同
//使用相对于main.js 的方式查找add.js var obj = require("./add.js"); var obj = require("./add"); //下面这种方式是引用核心模块或者包 //var obj = require("add");
- 注意引用js的方式和核心模块不同
5. 包
-
CommonJS的包规范给程序员提供了组织模块的标准,减少沟通成本
-
包的使用:
- 所有模块放在一个文件夹(包名)
- 包放在当前项目中的node_modules文件夹下
- 包中定义一个index.js(文件名不可以更改)导出所有模块
- 引用包(约定大于配置)
-
导入包的执行过程 require("calc")
- 将calc当做核心模块加载,加载不成功
- 自动去当前目录中的node_modules中找文件名为calc的包
- 自动去calc找index.js的出口模块(导出的模块)
- 如果找不到index.js报错,如果想要改出口模块,需要package.json配置文件
-
package.js
名称 | 功能 |
---|---|
name | 包名称 |
description | 包介绍,介绍包的功能 |
version | 版本号,用于版本控制 |
keywords | 关键词数组,用于在npm中搜索 |
main | require引入包时优先检查此字段 |
dependencies | 标记当前包所依赖的包列表,npm会自动加载依赖的包 |
Author | 包作者 |
License | 开源许可 |
{
"name": "calcpack",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": { //可以通过npm run来执行
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
-
创建包的标准方式
- npm init -y 自动创建package.json
-
一个标准包的结构
名称 |功能 |---|---| package.js |包描述文件 bin |存放可执行文件 lib |存放JavaScript代码 doc |存放文档 test |存放单元测试用例代码 README.md |说明文档,描述包的作用和用法
- 标准包执行过程
- 将calcpack当做核心模块加载,加载不成功
- 自动去当前目录中的node_modules中找文件名为calcpack的包
- 如果在calcpack中有package.json的话,并且指定了main属性的值,优先加载main指定的.js模块(出口模块)
- 如果没有package.json,或没有指定main属性,自动去calcpack找index.js的出口模块(导出的模块)
- 如果找不到index.js报错
6. 发布包
-
把包发布到NPM官网 https://www.npmjs.com/
- 建立一个包,设置package.json
- 在npmjs中注册账号
- 在包的根目录下执行
- npm adduser 添加发布包的用户信息,登录网站
- npm publish 发布或者更新包 package.json中一定要指定 maintainers:[{
}]"name":"nllcode", "email":"xxxxx@qq.com"
- npm cache clear 清除npm本地缓存,用于对使用相同版本号发布新版本
- npm unpublish @ 删除发布过的版本代码 npm unpublish haha@1.0.0
-
错误
- only admin can publish this module
- 解决:修改源 npm config set registry http://registry.npmjs.org
-
安装包
- 从网络安装
- 当前目录安装 npm install 包名
- 全局安装 npm install 包名 -g
- 本地安装 npm install 包的路径
- 卸载包 npm uninstall 包名
- 从网络安装
-
require()加载规则
- 优先从缓存加载模块或者包
- 加载文件模块要使用相对路径 ./ ../
- 文件模块的加载可以不写后缀名,如果不写后缀名按照 .js > .node > .json的顺序加载
- 加载json文件,推荐写上后缀.json
- 加载核心模块或包,不写路径和后缀
- module.paths 加载node_modules的时候,按此数组的顺序加载