NodeJs学习一NodeJs初识

1、前言javascript

  按照惯例,先扯淡,就由于这货,如今才有了各大公司招聘的全栈工程师,正是由于它,让之前只会写前端的人也能写起后端服务器代码来了。因此呢,你招一个会NodeJs的前端,它都能把后端干了,一我的干了两我的的事,你说哪一个公司不想要。可是我仍是要同情一下前端的兄弟们,真是苦了大家了,之前大家只是写页面就完了,如今还得写后台,再加上各类前端框架,什么Vue,Angular,React啊,恭喜大家,如今微信又带了一波小程序的节奏,唉,可怜的娃啊。html

  

  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好的地方就是 :java

  1.用JavaScript做为服务器端语言,这东西火啊,谁都会,简直没有学习成本,只用背几个api就好了啊。node

  2.统一先后端啊,全栈开发只须要学习一门语言,老板高兴了,招几个前端啥都有了,你给我写写写写写(为前端同窗默哀3分钟)。web

  3.擅长处理高并发,作网站和文件读写相关的应用很不错。mongodb

  4.参看前三点。(暂时还想不起来,伪装有第四点)数据库

   I am very 皮。express

2、关于NodeJs的介绍npm

 咱们先来看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,是世界上最大的开源库生态系统。(厉害了,个人哥)

3、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中是容许的。可是在浏览器中就会报错。

  

    能够看出,在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);

4、传说中的四行代码开发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 你究竟干了什么。

5、加载和导出的使用规则

  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'
}

6、包加载的方式

  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还原包的时候还能锁定文件的版本,不至于还原的时候自动升级到最新版本。

7、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 包名 //卸载一个包,并删除配置文件里相关的依赖配置信息

 8、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、框架搭建

  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;

10、数据访问(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) {

})

 

10、总结

  总之,NodeJs开启了JavaScript的新的神秘之旅,目前正在探索中,不过前几天看到Node之父说NodeJs设计的出现了很大的失败,又出了个叫deno的东西,唉,前端兄弟们真是堪忧。。。。

  

相关文章
相关标签/搜索