NodeJs学习一NodeJs初识
一、前言
按照惯例,先扯淡,就因为这货,现在才有了各大公司招聘的全栈工程师,正是因为它,让以前只会写前端的人也能写起后端服务器代码来了。所以呢,你招一个会NodeJs的前端,它都能把后端干了,一个人干了两个人的事,你说哪个公司不想要。但是我还是要同情一下前端的兄弟们,真是苦了你们了,以前你们只是写页面就完了,现在还得写后台,再加上各种前端框架,什么Vue,Angular,React啊,恭喜你们,现在微信又带了一波小程序的节奏,唉,可怜的娃啊。
NodeJs看着也带Js后缀,但是它和VueJs,Angular,ReactJs可不一样,后三个都是框架,而NodeJs是平台,运行时环境。怎么说呢,就是NodeJs之于JavaScript,就好比jvm之于Java,就好比CLR之于c#,而Vue,Angular,React之于JavaScript就好比于 SpringMVC 之于Java,Asp.Net MVC,这个栗子举得应该是十分清楚了吧。也就是说一般的js都是在浏览器上执行,能力也有限,只能操作浏览器上边的东西,不可以读写你操作系统的文件什么的,而配上node环境的js是在你电脑上执行,可以读写你操作系统的文件啥的,一不小心还能把你的操作系统中的东西都给你删除了,多可怕。
但凡一个东西火了,我们要用它,所以它必有过人之处,也必有好的地方。所以呢,NodeJs好的地方就是 :
1.用JavaScript作为服务器端语言,这东西火啊,谁都会,简直没有学习成本,只用背几个api就行了啊。
2.统一前后端啊,全栈开发只需要学习一门语言,老板高兴了,招几个前端啥都有了,你给我写写写写写(为前端同学默哀3分钟)。
3.擅长处理高并发,做网站和文件读写相关的应用很不错。
4.参看前三点。(暂时还想不起来,假装有第四点)
I am very 皮。
二、关于NodeJs的介绍
我们先来看NodeJs官方给的介绍
2.1 第一句话
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. 说NodeJs是一个基于谷歌V8JavaScript解析引擎的一个JavaScript 运行时。(据说V8是目前最快的js 解析引擎,毕竟大厂出品,值得信赖)。
2.2 第二句话
Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. 说NodeJs采用了事件驱动,非阻塞的IO模型,所以很轻,效率也很高。(所以处理并发很给力)
2.3 第三句话
Node.js' package ecosystem, npm, is the largest ecosystem of open source libraries in the world. 说NodeJs的包生态系统,npm,是世界上最大的开源库生态系统。(厉害了,我的哥)
三、Node中的JavaScript
3.1 没有BOM和DOM
众所周知,as we know,浏览器中的JavaScript是有dom和bom的,因为这样才可以操作html和浏览器相关的东西,比如document对象,window对象的,但是在Node中的js是没有这些对象的,因为很显然,不需要操作html和浏览器,因为压根在服务器端就没有这些东西。
如图所示,在node中没有window和document对象,输出时就会报错。
3.2 提供了一些服务器级别的API
除了没有dom和bom一说,在语法上是一样的,都是基于ECMAScript的,另外的是Node提供了一些服务器级别的api,比如操作文件、网络请求,http什么的,这些在浏览器端的js是没有这些功能的。
3.3 Node中的模块系统
Node中没有全局作用于的概念,在 Node 中,只能通过 require 方法来加载执行多个 JavaScript 脚本文件,默认每个文件就是一个模块,两个模块中的变量不会有污染问题,也就是说两个文件中可以有相同的变量,但是在浏览器中的js是不允许这样做的。如果你同时在a.js 和b.js中声明 var foo = 'bar' ;这在Node中是允许的。但是在浏览器中就会报错。
注意:前端模块化有这么几种规范CommonJs,AMD,CMD,ES6,在每种标准中,模块化的写法不一样,实际上node中使用的模块化功能是CommomJS的规范,最新的官方标准模块化规范是在ES6中,也渐渐的被大家和主流的浏览器所支持。
可以看出,在a.js中输出foo,是a的值,在b.js中调用add方法,结果是b中的add函数在起作用,由此可以看出,模块之间不存在变量污染问题,每个模块都是独立的作用域。
Node中通过require加载并执行其中的代码,文件与文件之间由于是模块作用域,所以不会有全局污染的问题,模块是完全封闭的,外部无法访问内部,内部也无法访问外部。
但是模块之间是需要通讯的,Node为每个文件(也就是模块)提供了一个exports对象,默认情况下,该对象是一个空对象,你要做的就是把需要外部访问使用的成员手动挂载到exports接口对象中,然后谁来require这个模块,返回值就是模块内部的exports对象。
//a.js
var b = require('./b.js');
console.log(b); //b.js
var foo = 'b foo';
function add(x, y) {
return x - y;
} //运行后输出
{}
可以看出require的返回值是一个空对象,也就是b.js中的exports对象,接下来我们对exports对象进行操作,看看会有什么结果。
//a.js
var b = require('./b.js');
console.log(b); //b.js
var foo = 'b foo';
function add(x, y) {
return x - y;
}
exports.foo = foo;
exports.add = add; //运行后输出
{
foo:'b foo',
add:[Function:add]
}
可以看出返回的对象里边已经有了我们赋值的属性。这样,我们就可以使用这些属性和功能,就可以进行模块之间的通讯。
3.4 Node中的核心模块
核心模块是由Node提供的一个个具有名字的模块,它们都有自己特殊的名称标识,例如: fs 文件操作模块、http 网络服务构建模块、os 操作系统信息模块、path 路径处理模块等等。所有核心模块在使用的过程中必须手动的用require方法来加载,例如使用文件系统模块,var fs = require('fs');
var http = require('http');
var fs = require('fs');
var os = require('os');
var path = require('path');
console.log(http,fs,os,path);
四、传说中的四行代码开发Web服务器
var http = require('http'); //加载http模块 var server = http.createServer(); //创建服务器 server.on('request', function (request, response) { //注册request请求事件
response.end('hello,nodejs')
}); server.listen('4396', function () { //监听4396端口
console.log('服务器已经启动成功了');
});
浏览器访问:http://localhost:4396/ 响应如下
刚看到,感觉是真的厉害,就想问问Node 你究竟干了什么。
五、加载和导出的使用规则
1.require 加载方式
//加载方式有以下几种
// 1. 直接写模块名字 //系统核心模块,直接写名字就行,不需要路径。
var module = require('fs'); //第三方模块,也是直接写名字,但是名字绝对不可能与系统核心模块一样。你懂的。
var module = require('art-template'); // ./ 相对路径形式,用于自己写的模块,路径前必须加.,不然路径找的是当前文件的根目录路径
// 作过web开发的同学应该都知道,一般项目中从来都是禁止写绝对路径的
var module = require('../a.js');
var module = require('./b.js');
2.导出的规则
//每个页面(模块)默认有一个exports对象,想要导出什么就按照以下方式
exports.add = function (x, y) {
return x + y;
}
exports.foo = 'foo'; //但是这种方式是错误的,并不能导出
exports = {
add: function (x, y) {
return x + y;
},
foo: 'foo'
};
//内部原理module.exports,因为node内部默认是
exports = module.exports;
// 最终导出的还是module.exports;所以如果想导出一个整体,应该如下:
//体会以下引用的含义就明白为什么了。
module.exports = {
add: function (x, y) {
return x + y;
},
foo: 'foo'
}
六、包加载的方式
1.有路径的包
有路径的话是按照相对当前文件的路径找到对应的文件 直接执行就行了。
2.第三方的包(不带路径符号的)
2.1 找到当前文件中的node_modules,找到相应的模块名字,找到下面的package.json,里边有main,找到main的值,一般是index.js(这里就可以指定),然后node就去加载index.js文件 获得返回的exports对象,接着就想我们上边用模块一样了。
以art-template为例,第一步,找到package.json
第二步,找到里边的main.js的值,为index.js
第三步,node去加载index.js,下边是index.js里边的代码,可以看出是标准的node中的模块导出写法。
const template = require('./lib/index');
const extension = require('./lib/extension'); template.extension = extension;
require.extensions[template.defaults.extname] = extension; module.exports = template;
3.关于package-lock.json
npm 版本 5.0以上会自动添加一个package-lock.json的文件,在该文件中保存了所有的包的依赖和下载地址,这样的话还原包的时候就不用一个个解析依赖,直接下载就行了,大大提高了效率。而且,有了这个文件,当你用npm还原包的时候还能锁定文件的版本,不至于还原的时候自动升级到最新版本。
七、npm常用命令
基本上就用到一下几个非常简单的命令
npm init //初始化一个基于node的app,这会让你一步一步输入你的app的配置 npm init -y //初始化一个基于node的app,使用默认生成配置 npm install 包名 // 安装一个包 npm install --save 包名 //安装一个包,并添加依赖信息到配置文件里边 npm install //根据依赖还原你所有依赖的包,万一不小心把node_modules文件夹删除了,那就用这个非常方便 npm remove 包名 //卸载一个包 npm remove --save 包名 //卸载一个包,并删除配置文件里相关的依赖配置信息
八、Express框架
var express = require('express'); //加载express模块 var app = express(); //启动服务器,相当于http.createServer() app.use('/public/', express.static('./public/')); //设置静态文件目录 app.get('/', function (req, res) { //处理/的请求
res.end('hello,express');
}) app.listen(3000, function () { //开启监听3000端口
console.log('starting...');
})
九、框架搭建
9.1 app.js
var express = require('express');
var router = require('./router');
var bodyParser = require('body-parser');
var app = express(); app.engine('html', require('express-art-template')); //设置art-template的解析方式,为解析带html后缀的文件 app.use('/node_modules/', express.static('./node_modules/'));
app.use('/public/', express.static('./public/')); app.use(bodyParser.urlencoded({ extended: false })); //使用body解析post数据库
app.use(bodyParser.json()); app.use(router); //使用路由 app.listen(3000, function () {
console.log('running...');
})
9.2 router.js
var express = require('express');
var student = require('./student');
var router = express.Router(); router.get('/add', function (req, res) {
res.render('add.html'); //默认去找views文件下的同名文件
}); router.post('/add', function (req, res) {
student.add(req.body, function (error, data) {
if (error) {
res.end('error');
} else {
res.redirect('/');
}
})
}) router.get('/', function (req, res) {
student.list(function (error, data) {
if (error) {
res.end('error');
} else {
res.render('index.html', {
students: data
});
}
})
}) router.get('/student', function (req, res) {
res.render('index.html')
}) router.post('/post', function (req, res) { });
module.exports = router;
9.3 student.js
var fs = require('fs');
var student = {}; student.list = function (fn) {
fs.readFile('./student.json', function (error, data) {
if (error) {
fn(error);
} else {
fn(null, JSON.parse(data.toString()));
}
})
} student.add = function (student, fn) {
fs.readFile('./student.json', function (error, data) { if (error) {
fn(error);
} else {
var students = JSON.parse(data.toString());
students.push(student);
fs.writeFile('./student.json', JSON.stringify(students), function (error, data) {
if (error) {
fn(error);
} else {
fn(null, data);
}
});
}
})
}
module.exports = student;
十、数据访问(mongodb)
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test'); var catSchema = mongoose.Schema({
name: String
}); const cat = mongoose.model('Cat', catSchema);
const kitty = new Cat({ name: 'cat' }); kitty.save().then(() => console.log('meow')); cat.find({ name: 'cat' }, function (error, cat) { })
十、总结
总之,NodeJs开启了JavaScript的新的神秘之旅,目前正在探索中,不过前几天看到Node之父说NodeJs设计的出现了很大的失败,又出了个叫deno的东西,唉,前端兄弟们真是堪忧。。。。
NodeJs学习一NodeJs初识的更多相关文章
- Nodejs学习笔记(二)——Eclipse中运行调试Nodejs
前篇<Nodejs学习笔记(一)——初识Nodejs>主要介绍了在搭建node环境过程中遇到的小问题以及搭建Eclipse开发Node环境的前提步骤.本篇主要介绍如何在Eclipse中运行 ...
- Nodejs学习路线图
前言 用Nodejs已经1年有余,陆陆续续写了48篇关于Nodejs的博客文章,用过的包有上百个.和所有人一样,我也从Web开发开始,然后到包管 理,再到应用系统的开发,最后开源自己的Nodejs项目 ...
- Nodejs学习笔记(四)——支持Mongodb
前言:回顾前面零零碎碎写的三篇挂着Nodejs学习笔记的文章,着实有点名不副实,当然,这篇可能还是要继续走着离主线越走越远的路子,从简短的介绍什么是Nodejs,到如何寻找一个可以调试的Nodejs ...
- Nodejs学习笔记(三)——一张图看懂Nodejs建站
前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...
- 【NodeJS 学习笔记03】先运行起来再说
前言 最近同事推荐了一个不错的网址:https://github.com/nswbmw/N-blog/wiki/_pages 里面的教程很是详细,我们现在跟着他的节奏学习下NodeJS,一个简单的博客 ...
- nodejs学习资料
官方文档 阿里nodejs7天快速教程 从零开始nodejs系列文章 一个周末掌握IT前沿技术之node.js篇 nodejs中文api文档 nodejs中文api文档(0.12.2) node ...
- NodeJS学习笔记之Connect中间件模块(一)
NodeJS学习笔记之Connect中间件模块(一) http://www.jb51.net/article/60430.htm NodeJS学习笔记之Connect中间件模块(二) http://w ...
- Nodejs学习笔记(一)--- 简介及安装Node.js开发环境
目录 学习资料 简介 安装Node.js npm简介 开发工具 Sublime Node.js开发环境配置 扩展:安装多版本管理器 学习资料 1.深入浅出Node.js http://www.info ...
- Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识
目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...
随机推荐
- 结合 Redis 实现同步锁
1.技术方案 1.1.redis的基本命令 1)SETNX命令(SET if Not eXists) 语法:SETNX key value 功能:当且仅当 key 不存在,将 key 的值设为 val ...
- Can't locate Data/Dumper.pm in perl5的处理
Can't locate Data/Dumper.pm in perl5的处理 wget http://www.cpan.org/modules/by-module/Data/Data-Dumper- ...
- AD账号解锁
Get-ADUser -Filter * -Properties * -SearchBase "dc=uxin,dc=youxinpai,dc=com"| ? {$_.locke ...
- gnome-shell 使用 notify-send 发送桌面消息
什么是notify-send? notify-send - a program to send desktop notifications 怎么使用? NAME notify-send - a pro ...
- 【待补充】[Python_1] Python 安装
0. 说明 安装教程网上有很多,等下次安装再补充笔记 Python 下载地址
- 使用 jekyll + github pages 搭建个人博客
1. 新建 github.io 项目 其实 github pages 有两个用途,大家可以在官方网页看到.其中一个是作为个人/组织的主页(每个账号只能有一个),另一个是作为 github 项目的项目主 ...
- vue+axios自己踩过的坑
axios的介绍就不用了吧,api有具体的介绍axios或者是axios中文: 主要讲的就是我自己在第一次使用axios中遇到的问题,及二次封装 先来说说二次封装,之前自己也是网上找了很多同学的封装, ...
- Nodejs学习资源汇总
Node.js v6.3.1 Documentation https://nodejs.org/dist/latest-v6.x/docs/api/ npm官网 https://www.npmjs ...
- leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions
两种方式处理已经访问过的节点:一种是用visited存储已经访问过的1:另一种是通过改变原始数值的值,比如将1改成-1,这样小于等于0的都会停止. Number of Islands 用了第一种方式, ...
- table border
table的CSS为{border-collapse:collapse;border:none;},再设置td的CSS为{border:solid#000 1px;}是一个非常不错的方法. 示例: & ...