node.js 的一些基础
前端的工程化,模块化,框架,需要有一套工具去支撑系统运行起来.而这套工具就是需要nodejs这个环境去实现的,因此, 首先需要先学习node.js开始
node.js 的简单介绍
首先,什么是node.js?
- 是基于chrome V8 引擎的javascript运行环境(官网上这么写的)
- 听着有点抽象,下面举例demo来加强理解
node.js 的用处
- 开发网站的后台,之前的做的小demo里有用到,用来开启一个本地服务器https://github.com/gitgundam/server-mock
- 开发网站后台可以使用很多语言,但是如果只会js,那就很麻烦,还需要学习其他语言,现在有了node.js.直接使用js即可实现,学习成本更低
- 开发本地工具,应用
- 开发本地工具,应用,在node.js之前需要学习更多其他语言(例如 c语言).现在node.js即可实现,学习成本更低
node.js 的特点
- 事件驱动,非阻塞式I/O模型
- 强大的生态,第三方
提到node.js,就不得不抛出两个概念
计算密集型
- 大量的计算,消耗cpu资源,比如计算圆周率,对视频进行高清解码
- c语言
- 比如密码破解
I0密集型
- 网络/磁盘的读写
- node.js
- 比如网站展示,数据交互,对cpu运算要求不高
安装node.js
进入官网下载安装即可,安装会附带npm.
下面是简单的例子加深对node.js 的理解
例子1
用最简单的一个例子实现node.js 的功能
- 本地dmoe文件夹 创建test-1.js文件
let a = 1
let b = 2
console.log(a+b)
- 打开终端,在文件夹目录使用node.js 运行 test-1.js文件
- 结果如下图,输出3
例子2 使用node.js的内置模块来做些事
读取一个文件A,再将文件内容写入文件B中
- 首先,从node.js的官方API文档中可以看到,异步地读取文件的全部内容。
- 文档上写了这么用
- js这么写
const fs = require('fs') //加载node.js的fs模块
fs.readFile('./A.md','utf-8',(err, data) => {
if (err) throw err;
console.log(data);
})
使用node.js环境运行test-1.js,读取A.md文件的内容并打印出来,得到结果
- 使用
把A.md的内容转成大写并写入B.md
const fs = require('fs') //加载node.js的fs模块
fs.readFile('./A.md','utf-8',(err, data) => {
if (err) throw err;
text = data.toUpperCase()
fs.writeFile('./B.md',text,err=>{
console.log(err)
return
})
console.log('写入完成');
})
例子3 引入本地模块
很多情况下,我们需要自己写点东西来实现想要的功能,这时候就需要引入自己的模块
- 定义一个模块
//util.js
//定义一个模块util,里面是其功能
function sum(){
return [...arguments].reduce((v1,v2)=>v1+v2)
}
//把自定义的fact绑定到module.exports这个对象上
module.exports.sum = sum
//其他文件里就可以引入这个模块,通过require('文件路径')
- 调用这个模块
//text-2.js
const util = require('./util.js')//一定要写相对路径,否则node.js会先从内置模块中寻找
console.log(util.sum(1,2,3,4,5))
module.exports
module.exports
理解为就是一个空对象,上面那段代码中,将sum绑定到这个空对象中.
- 其实字面意思就是模块输出.需要调用时,先加载模块,然后调用这个空对象中的方法
例子4 使用npm第三方模块
npm的最大优势就是拥有一个强大的数据库,拥有全世界的开发者开发的模块供使用
https://www.npmjs.com/可以在这个网站搜索模块,然后根据文档使用.
- 例如实现一个将markdown格式文本转换为html格式文本
- 比如使用下面这个人写的模块
- 先根据文档写的来
const fs = require('fs')//使用fs模块
//根据文档的设置来
const MarkdownIt = require('markdown-it')
let md = new MarkdownIt()
//先读取内容
fs.readFile('./A.md', 'utf-8', (err, data) => {
if (err) throw err
let result = md.render(data)//文档中的api,转换成htmml的内容
//把内容输入B.md
fs.writeFile('./B.md', result, err => {
if (err) throw err
console.log('写入完成')
})
})
结果会发现: 直接报错.为啥呢? 因为模块还没下载到本地,因此需要先下载这个模块到本地
-
使用
npm install xxx
来下载模块
-
可以发现当前文件夹内出现了个新的文件夹
-
再次终端中执行
node test-3.js
-
这次内容写入成功,输出写入完成,查看B.md,可以发现内容确实转换完成
以上就是node.js模块化的使用方法
common js规范
下面说下common js规范,那么什么是common js规范呢?
一个文件是一个模块
- 变量/函数/类 都是私有的.
每个模块内部,module都是代表当前模块
刚才就用到了的module.exports
,意思就是自己的模块对外输出.这是一个对外接口,同时这是个空对象,在这个模块上(对象上)可以带上自己模块本身的函数.
module.exports
是一个对外接口.加载某个模块,其实就是在加载该模块的module.exports
- 注意
module.exports
和exports
的差异,默认module.exports = exports
(简写)
require()方法用于加载模块
- 需要注意加载模块路径写法的差
注意注意!! 默认module.exports = exports
,所以单独exports
是个对象,需要添加对象里的属性!!!然后再把模块里的函数添加到这个属性上!!! - 也可以
module.exports
直接等于 函数名称, 这样当require()
时,require()就是模块本身.模块就是个函数,可以直接使用
Node.js 在require第三方包时
- 先在当前项目的 node_modules里查找这个包
- 如果当前项目的 node_modules里找不到,再从上一级路径的node_modules里查找
- 最终会找到 /(根目录),如果还找找不到,会报 “找不到模块”的错误