深入基础(一)模块化
简介
学习基础,JQuery 原生JS有一定基础,有自己一定技术认知(ps:原型链依然迷糊中.闭包6不起来!哎!)
当然最好有语言基础,C#,java,PHP等等..
最初学习这个东西的原因很简单,在园子里面看到一篇关于node编写的小爬虫 的文章,没想到这个可以做一些服务自己的东西而不是公司那些服务用户啊什么什么的.总之不牵扯到公司的技术都很感兴趣,后来发现angluar.js里面也有node.js一点身影,好吧,好吧逼我呗..so 学吧!说实话并不想靠掌握这个如果升职加薪如何如何的,我只想做自己喜欢的事儿写服从于我自己的程序,就是这么简单.
这里要说明一下文中很多地方都是各出引用过来,对于很多不明白的地方会针对某个对象,方法等作出补充说明,争取学习不留死角,一般一片学习很少很少的内容却需要大量的补充来填补知识空白这也许就是最难的地方.
安装
言归正传,node.js简介:
简单的说 Node.js 就是运行在服务端的 JavaScript。
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
模块化(module),JS的致命伤一直计划引进据说ES6中已经引入了模块化概念了并没有实际实现(知识薄浅,书到用时方恨少),通过实现CommonJS中的Modules1.0概念来完善自己的模块化
如题谷歌V8引擎,听起来吊吊的 实际上也是很吊的,前端开发的同学对于谷歌浏览器并不陌生或多或少接触过或者使用过我就不多介绍啦,主要是多了我也不知道哈哈.但是最显而易见的效果在于node处理高并发问题上有突出效果!
安装环境 windows啊,linux啊,os啊,自己去看 网址在这里:https://nodejs.org/en/download/。
安装过程就不多说了,哦,有一点对于DOS命令不熟的童鞋们还是老老实实安装C盘吧 ,或多或少会用到一点点 .教程:http://jingyan.baidu.com/article/656db9189b826ce381249ce8.html
搞完了之后看看系统PATH环境里面有没有配置node.js:
检测PATH环境变量是否配置了Node.js,点击开始=》运行=》输入"cmd" => 输入命令"path",输出如下结果:
PATH=C:\oraclexe\app\oracle\product\10.2.0\server\bin;C:\Windows\system32; C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\; c:\python32\python;C:\MinGW\bin;C:\ProgramFiles\GTK2-Runtime\lib; C:\Program Files\MySQL\MySQL Server 5.5\bin;C:\Program Files\nodejs\; C:\Users\rg\AppData\Roaming\npm
似乎就是你所安装的node.js的地址不过这东西没有的话node是运行不起来的!找到它 没有的话就添加上!
当然可以手动修改一下Path地址右键我的电脑-属性-高级系统设置-环境变量-找到path 关于nodejs那段文字 修改去吧~只要吧你的文件地址搞上面去就行了,别的别轻易动,虽然我也不知道会发生什么但是我还是鼓励喜欢动手的小伙伴修改一下试试看!
搞完了之后基本工作就完成了!当然安装的不仅仅是node.js安装同时也会默认安装台的包管理工具npm! 个人认为比较强大的包管理工具,有点像git工具一样可以直接用命令从服务器更新啊,下模块啊,上传自己的包啊等等,反正很好用可以搞很多事儿理解有限以后我再详细研究一下子
输入npm-v直接显示当前npm的版本.
模块化
关于nodejs里面的模块化知识点(module),nodejs模块化大致分为两类一类是原生模块(跟JS一样原生什么的都是重中之重),另外一类是文件模块.
文件模块
文件模块,我首先想到的是类似与C#里面文件数据交互相关的IO数据流,其实不然nodejs中文件模块引用了三种文件识别方式:
1. .js 既然是模块化 当然自己得有个专门处理文件的模块了 -- fs模块(那笔记下来好不容易找到的--)
FS模块刚刚被我言中了,采用的是标准的POSIX文件 I/O操作集(不明白的童鞋自己去百度吧,不能再深入了!),可以通过nodejs中的require("fs")来唤起该模块并且该模块有同步/异步两种传输方式:
1)两种方式不同点在于 同步传递文件时候会出现程序异常,当然可以trycatch捕获到,而异步传递时候会直接返回null或者undefined
2)读取文件时一定要设置文件编码,默认编码是'buffer'如果你在下面的例子中文件里面输入的是中文就能明显的看出来了!
下面介绍两个例子,这是下面具体实例:
//文件读取操作 var fs = require("fs") ; fs.readFile("bb.txt","utf8",function (error,data){ if(error) throw error ; console.log(data) ; }) ; //文件写入操作 var fs = require("fs") ; var txt = "大家要好好学习NodeJS啊!!!" ; //写入文件 fs.writeFile("bb.txt",txt,function (err) { if (err) throw err ; console.log("File Saved !"); //文件被保存 }) ;
2.".node" Addon这个是C/C++编写的操作原理未知...通过其中的dlopen方法来进行加载(想更深入的童鞋请自行百度,这块我大致看了一下太深入了真心不好懂)
3.".Json" 这个大家都不会陌生 尤其做前端的小伙伴们 这个是调取JSON.parse 方式来解析json数据的
原生模块
关于原生模块,也就是nodejs自带模块还是参考一下官方文档吧,毕竟那个东西是最最基础的最最可信的,后续也会陆续介绍一些常用的原生模块.
NodeJS模块查询策略
node提供了两个对象,exports和require两个对象,其中exports是模块公开的接口,require是从外部获取一个模块接口,即所获取模块的exports对象.(这句话有点难以理解稍后有解释)
原生模块在nodejs编译进了二进制执行文件,加载速度最快,另外就是文件模块速度肯定比不上原生模块,但是由于加载机制,已经加载过的原生模块和文件模块不会再次被重新加载,如图:
这就很明朗了,这么吊的图肯定不是我画的呀 大神传送门-->https://liuzhichao.com/p/1669.html
刚才提到有两个对象exports和require,这个图很详细说明了这哥俩之间的关系,我是这样理解的:
require对象就像JQuery中的$选择器,这个大家肯定不陌生,当然有区别的,只是个比喻 如果把页面元素都划分为模块的话$("<div></div>"),很简单吧.我选择的就是div这个模块,好比require("fs")选择的是原生模块fs, 有一点不知大家感觉到没有,nodejs缓存机制特别到位,优先缓存查找有点像radis缓存一样一些已经执行过方法不会被再次执行大大缩减了重复调取的性能损耗,但是这里不得不提及缓存问题,机制固然好毕竟这东西是一 把双刃剑性能上去了,缓存溢出咋办?有没有专业的缓存清理机制,目前还不几道,不过我肯定他绝对有.
其次require接收的参数是啥? 1.原生模块 2.相对,绝对路径文件模块 3.非原生模块的文件模块. require的查找线路是当年文件目录的node_modules开始找,找不到就找父级目录node_module以此类推直到根目录下的 node_module文件为止,第二条的时候大家肯定注意到绝对路径! 没错性能就在一瞬间了 如果你给文件模块地址是绝对地址,必然相当快省去反复遍历时间而且require的查找机制不是遍历全局这种机制 so好好利用这一点:
- 从module path数组中取出第一个目录作为查找基准。
- 直接从目录中查找该文件,如果存在,则结束查找。如果不存在,则进行下一条查找。
- 尝试添加.js、.json、.node后缀后查找,如果存在文件,则结束查找。如果不存在,则进行下一条。
- 尝试将require的参数作为一个包来进行查找,读取目录下的package.json文件,取得main参数指定的文件。
- 尝试查找该文件,如果存在,则结束查找。如果不存在,则进行第3条查找。
- 如果继续失败,则取出module path数组中的下一个目录作为基准查找,循环第1至5个步骤。
- 如果继续失败,循环第1至6个步骤,直到module path中的最后一个值。
- 如果仍然失败,则抛出异常。
这里的异常是有区别的下文提及调用类型有同步异步两种 同步调用肯定就是异常了,这个可以trycatch截取到 另外就是异步调用啦 返回null或者undefined..很简单的说 .
Exports or module.exports
首先必须理解了上面哪个图,自然而然就会产生一个疑问exports干毛用的?为毛都返回的是exports,难道就是简单的对象返回问题?
带着问题,这里有三个例子:创建两个文件,server.js和test.js
server.js中代码:
var add=function(a,b){ return a+b; }; var minus=function(a,b){ return a-b; };
test.js中的代码:
var test=require("./server"); console.log(test.add(4,2));
然后执行test.js文件 神奇的效果出现了!! 异常报错!
修改一下server.js代码
var add=function(a,b){ return a+b; }; var minus=function(a,b){ return a-b; }; exports.add=add; exports.minus=minus;
结果为 6! 简单说明一下子 首先是require选择执行文件server.js 结合上面哪个图,之后nodejs 就去找了..哎~找到了 但是返回的是啥 他本身不认识 而是通过对象返回才认识的! 这个传递的快递小哥就是exports!很明朗了吧!
呐是不是就可以认为返回的东西都可以往exports里面放呢?真的只是他自己返回的嘛?别忘了之前为啥叫module模块化!当然module.exports,这里我就懒一下子 不举例给大家啦 当然原文地址不能少:https://liuzhichao.com/p/1669.html
关于exports和module.exports 我个人是这样理解的,因为node中没有类的概念而某些特定情况下需要返回一个特定"对象"这种情景下module.exports就排上用场了 指定的对象情况,而exports并非指定的对象,也就是位置对象类型,这个有点类似C#中的泛型和非泛型...只是说类似,纯属个人理解.
1. .js 既然是模块化 当然自己得有个专门处理文件的模块了 -- fs模块(那笔记下来好不容易找到的--)
FS模块刚刚被我言中了,采用的是标准的POSIX文件 I/O操作集(不明白的童鞋自己去百度吧,不能再深入了!),可以通过nodejs中的require("fs")来唤起该模块并且该模块有同步/异步两种传输方式:
1)两种方式不同点在于 同步传递文件时候会出现程序异常,当然可以trycatch捕获到,而异步传递时候会直接返回null或者undefined
2)读取文件时一定要设置文件编码,默认编码是'buffer'如果你在下面的例子中文件里面输入的是中文就能明显的看出来了!
下面介绍两个例子,这是下面具体实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//文件读取操作 var fs = require( "fs" ) ; fs.readFile( "bb.txt" , "utf8" , function (error,data){ if (error) throw error ; console.log(data) ; }) ; //文件写入操作 var fs = require( "fs" ) ; var txt = "大家要好好学习NodeJS啊!!!" ; //写入文件 fs.writeFile( "bb.txt" ,txt, function (err) { if (err) throw err ; console.log( "File Saved !" ); //文件被保存 }) ; |
2.".node" Addon这个是C/C++编写的操作原理未知...通过其中的dlopen方法来进行加载(想更深入的童鞋请自行百度)
3.".Json" 这个大家都不会陌生 尤其做前端的小伙伴们 这个是调取JSON.parse 方式来解析json数据的