天天看点

前端学习——NodeJs基础篇一. NodeJs简介二. 安装NodeJs三. NPM简介四. HelloWorld五. NodeJs模块

一. NodeJs简介

1.1 nodeJs的诞生

在Netscape设计出JavaScript后的短短几个月,JavaScript事实上已经是前端开发的唯一标准。后来,微软通过IE击败了Netscape后一统桌面,结果几年时间,浏览器毫无进步。

没有竞争就没有发展。微软认为IE6浏览器已经非常完善,几乎没有可改进之处,然后解散了IE6开发团队!而Google却认为支持现代Web应用的新一代浏览器才刚刚起步,尤其是浏览器负责运行JavaScript的引擎性能还可提升10倍。先是Mozilla借助已壮烈牺牲的Netscape遗产在2002年推出了Firefox浏览器,紧接着Apple于2003年在开源的KHTML浏览器的基础上推出了WebKit内核的Safari浏览器,不过仅限于Mac平台。随后,Google也开始创建自家的浏览器。他们也看中了WebKit内核,于是基于WebKit内核推出了Chrome浏览器。

Chrome浏览器是跨Windows和Mac平台的,并且,Google认为要运行现代Web应用,浏览器必须有一个性能非常强劲的JavaScript引擎,于是Google自己开发了一个高性能JavaScript引擎,名字叫V8引擎并且开源。

有个叫Ryan Dahl的歪果仁,他的工作是用C/C++写高性能Web服务。对于高性能,异步IO、事件驱动是基本原则,但是用C/C++写就太痛苦了。于是这位仁兄开始设想用高级语言开发Web服务。他评估了很多种高级语言,发现很多语言虽然同时提供了同步IO和异步IO,但是开发人员一旦用了同步IO,他们就再也懒得写异步IO了,所以,最终,Ryan瞄向了JavaScript。因为JavaScript是单线程执行,根本不能进行同步IO操作,所以,JavaScript的这一“缺陷”导致了它只能使用异步IO。选定了开发语言,还要有运行时引擎。这位仁兄曾考虑过自己写一个,不过明智地放弃了,因为V8就是开源的JavaScript引擎。让Google投资去优化V8,咱只负责改造一下拿来用,还不用付钱,这个买卖很划算。于是在2009年,Ryan正式推出了基于JavaScript语言和V8引擎的开源Web服务器项目,命名为Node.js。虽然名字很土,但是,Node第一次把JavaScript带入到后端服务器开发,加上世界上已经有无数的JavaScript开发人员,所以Node一下子就火了起来。

1.2 nodeJs的优势

优势是借助JavaScript天生的事件驱动机制加V8高性能引擎,使编写高性能Web服务轻而易举。其次,JavaScript语言本身是完善的函数式语言,在前端开发时,开发人员往往写得比较随意,让人感觉JavaScript就是个“玩具语言”。但是,在Node环境下,通过模块化的JavaScript代码,加上函数式编程,并且无需考虑浏览器兼容性问题,直接使用最新的ECMAScript 6标准,可以完全满足工程上的需求。

二. 安装NodeJs

2.1 nodeJs版本

  • 本课程中所用版本为node-v12.16.2的64位版本。
  • 在Windows上安装时务必选择全部组件,包括勾选Add to Path。

2.2 版本验证

  • 打开命令提示符,然后输入

    node -v

    ,如果安装正确,结果如图
前端学习——NodeJs基础篇一. NodeJs简介二. 安装NodeJs三. NPM简介四. HelloWorld五. NodeJs模块

2.3 node指令

  • 在命令提示符中输入node,此时进入nodejs的交互环境。在该环境下支持输入任意的JavaScript代码,例如输入200+200回车后得到输出结果为400。
  • 连按两次Ctrl+C退出nodeJs交互环境
前端学习——NodeJs基础篇一. NodeJs简介二. 安装NodeJs三. NPM简介四. HelloWorld五. NodeJs模块

三. NPM简介

3.1 什么是NPM

  • NPM(NodeJS Package Manager)就是nodejs的包(插件)管理工具。
  • NPM无需手动安装,在nodeJs环境安装成功后就已经自动安装成功了NPM。
  • 在命令提示符输入

    npm -v

    正确结果如图
前端学习——NodeJs基础篇一. NodeJs简介二. 安装NodeJs三. NPM简介四. HelloWorld五. NodeJs模块

3.2 为什么需要NPM

  • 我们在开发时,会用到很多别人写好的JavaScript代码,比如jQuery、bootstrap等。
  • 我们使用这些插件时,需要自己到官网去下载代码,解压代码然后再使用,非常繁琐。
  • NPM就是来解决这个问题的。开发人员把自己开发的代码模块打包后发布到NPM官网。
  • 使用时通过npm命令来进行安装即可直接使用,无需关心代码存在哪以及从哪去下载。
  • 再者,当我们使用A模块,而A模块又依赖于B模块的时候,NPM可以根据依赖关系,自动把需要的依赖包下载并管理。

3.3 更改NPM镜像

  • 由于npm的源在国外,所以国内用户使用起来各种不方便,所以一般会把NPM资源地址改为国内的镜像资源。目前最为主流的镜像是淘宝网提供的NPM镜像。
  • 淘宝镜像仓库地址:https://registry.npm.taobao.org/
  • 淘宝镜像搜索地址:https://npm.taobao.org/
  • 使用方式有两种:
    1. 安装cnpm后使用cnpm命令。

      该方式其实是安装一个cnpm插件,安装这个插件也是需要从国外地址来安装,有可能失败。安装成功后使用才没有后续问题。

    2. 更改npm配置信息

      从根本上解决下载包速度过慢的问题。推荐使用。

3.3.1 安装cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org
           

3.3.2 更改npm配置信息

  • 更改方式
npm config set registry https://registry.npm.taobao.org
           
  • 验证是否成功
npm config get registry
           

四. HelloWorld

  • 桌面开发
  1. 桌面新建文本文档,重命名为helloworld.js
  2. 鼠标右键选择编辑
  3. 输入

    console.log("hello world");

    并保存。
  4. 在桌面按住shift的情况下鼠标右键单击,选择

    在此处打开Powershell窗口

  5. 在powershell窗口中输入

    node helloworld.js

    回车(输入he之后按tab可以自动补全代码)
  6. 第四部如果无法正常执行,则在说明win+r运行窗输入cmd回车进入命令行编辑器。
  7. 输入

    cd C:\Users\计算机用户名\Desktop

    回车,表示进入桌面目录
  8. 在命令编辑行窗口中输入

    node helloworld.js

    回车(输入he之后按tab可以自动补全代码)

五. NodeJs模块

5.1 模块系统

5.1.1 什么是模块系统

在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Node环境中,一个.js文件就称之为一个模块(module)。

5.1.2 模块系统的优势

  1. 提高代码的可维护性
  2. 提高代码的可复用性
  3. 避免冲突

5.1.3 自定义模块

  • 声明自定义模块
/*自定义函数test*/
function test(name) {
    console.log(`hello${name}`);
}
/*模块输出*/
module.exports=test;
           
  • 使用自定义模块
/*require函数表示引入模块,参数为要引入模块的地址,可以是相对路径或绝对路径*/
// 注意,在nodejs中引入模块使用的是require函数,在浏览器中使用的import函数。
// 此处引入文件时同文件夹下也必须使用以./开头表示的相对路径,否则会报错。
// 如果require中直接写Hello,那么Node会依次从内置模块、全局模块和当前模块下寻找Hello.js
//模块与模块之间相互不干扰,其底层实现原理是闭包。
let show = require('./Hello');	
/*声明的变量show可以和require引入的模块中通过module.exports输出的函数名不同*/
show("张三");
/*当前模块中继续声明test函数,和Hello模块中的test是没有关系的,不会产生冲突*/
function test() {
    console.log("第二个test")
}
test();
           
  • module.exports可以通过封装对象来返回多个值
function hello() {
    console.log('Hello, world!');
}

function greet(name) {
    console.log('Hello, ' + name + '!');
}

module.exports = {
    hello: hello,
    greet: greet
};
           

5.2 全局对象模块

5.2.1 全局对象Global和Window对象

NodeJs 中有一个特殊的对象,称为全局对象(Global Object),它及其所有属性都可以在程序的任何地方访问,即全局变量。

在浏览器 JavaScript 中,window 是全局对象, 而 Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global 对象的属性。

5.2.2 常用全局对象

  • __filename 输出当前执行脚本的文件名,包含路径。
  • __dirname 输出当前执行脚本所在目录,包含路径。
  • setTimeout和clearTimeout
  • setInterval和clearInterval
  • console
    1. console.log([data][, …])向标准输出流打印字符并以换行符结束。该方法接收若干 个参数,如果只有一个参数,则输出这个参数的字符串形式。如果有多个参数,则 以类似于C 语言 printf() 命令的格式输出。
    2. console.info([data][, …])该命令的作用是返回信息性消息,这个命令与console.log差别并不大,除了在chrome中只会输出文字外,其余的会显示一个蓝色的惊叹号。
    3. console.error([data][, …])输出错误消息的。控制台在出现错误时会显示是红色的叉子。
    4. console.warn([data][, …])输出警告消息。控制台出现有黄色的惊叹号。
    5. console.dir(obj[, options])用来对一个对象进行检查(inspect),并以易于阅读和打印的格式显示。
    6. console.time(label)输出时间,表示计时开始。
    7. console.timeEnd(label)结束时间,表示计时结束。

5.3 网络模块

5.3.1 http请求示例

/*引入http模块*/
let http = require('http');
/**
 * 创建服务
 * request  请求传入内容
 * response 请求输出内容
 */
let server=http.createServer(function (request,response) {
    /*处理中文乱码*/
    request.setEncoding("utf-8");
    response.writeHead(200,{"Content-Type":"text/html;charset=utf-8"});
    /*处理多请求一次的bug*/
    if(request.url!=='/favicon.ico'){
        /*输出html内容到页面*/
        response.write("<h1>hello world</h1>");
        /*输出文本内容到页面*/
        response.write("你好世界");
    }
    /*关闭输出流,如果不调用end函数,则页面会一直处于刷新状态*/
    response.end();
});
/*设置监听端口*/
/*端口号范围:0-65535,1023以内的端口号尽量不要使用!!!*/
server.listen(8888);
console.log(`启动成功:http://localhost:8888`);
console.log(`常用默认端口号:https://blog.csdn.net/qiucheng_198806/article/details/87375505`);
           

5.3.2 get请求处理参数

const http = require('http');
const url = require('url');

http.createServer(function(request, response){
    request.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});
    // 解析 url 参数
    const params = url.parse(request.url, true).query;
    response.write("网站名:" + params.name);
    response.write("\n");
    response.write("网站 URL:" + params.url);
    response.end();
}).listen(8888);
console.log("http://localhost:8888/user?name=zhangsan&url=http://www.zhihu.com");
           

5.3.3 post请求处理参数

const http = require('http');
const querystring = require('querystring');
http.createServer(function(request, response){
	//设置允许跨域的域名,*代表允许任意域名跨域
    request.header("Access-Control-Allow-Origin","*");
    // 定义了一个post变量,用于暂存请求体的信息
    let post = '';
    // 通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中
    request.on('data', function(chunk){
        post += chunk;
    });
    // 在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。
    request.on('end', function(){
        post = querystring.parse(post);
        console.log(post);
        response.end();
    });
}).listen(8888);
           
  • 页面代码如下
<form action="http://localhost:8888" method="post">
    <div>
        <label for="username">用户名</label>
        <input type="text" name="username" id="username">
    </div>
    <div>
        <label for="password">密码</label>
        <input type="password" name="password" id="password">
    </div>
    <div>
        <button type="submit">提交</button>
    </div>
</form>
           

5.4 数据库模块

5.4.1 数据库模块为第三方模块,需要单独安装

  1. 在当前项目文件夹内打开命令行,输入

    npm install mysql

    回车,会生成package.json文件。
  2. 输入

    npm install

    回车,会生成package-lock.json文件。
  3. 此时可在当前项目内的js脚本文件中使用mysql库。

5.4.2 示例代码

/*引入mysql模块*/
const mysql=require('mysql');
/*配置数据库连接信息*/
const connection=mysql.createConnection({
    host:"localhost",   /*连接地址*/
    user:"root",        /*用户名*/
    password:"root",    /*密码*/
    database:"test"     /*被操作的数据库名*/
});
/*打开连接*/
connection.connect();
/*初始化SQL语句*/
let sql="select * from stu where id = ?";
/**
 * 执行SQL
 * 参数1:要执行的sql语句
 * 参数2:sql语句中占位符的内容数组
 * 参数3:回调函数
 * 回调参数1:是否异常,无异常返回null
 * 回调参数2:执行结果,查询操作返回结果集合数组,增删改返回受影响行数(affectedRows)
 * 回调参数3:数据库信息,一般不用
 */
connection.query(sql,[1],function (error,results,field) {
    if(error){
        throw error;
    }
    console.log(results[0].name);
    console.log(field);
});
/*关闭数据库连接*/
connection.end();
           

5.5 UUId模块

这个模块我感觉还是使用的比较多的,因为我的个人习惯是插入数据库的时候使用的id主键是一串随机数,所以这个模块我使用的也比较多,这个还是要看个人习惯,毕竟我现在所写的东西涉及的数据量过小,效率什么的还是和自增主键差不多,其实还有一个是介于自增主键和UUID之间的一个算法,叫雪花算法,这个我没有具体了解过,只知道有这么个东西,等以后有需要了解的时候会更新一篇博客给大家讲解

5.5.1 具体步骤

  1. 在当前项目文件夹内打开命令行,输入 `npm install node-uuid 回车,会生成package.json文件。
  2. 此时可在当前项目内的js脚本文件中使用uuid库。

5.5.2 代码实现

const uuid = require('node-uuid');

let createuuid1 = uuid.v1().replace(/-/g,"").toUpperCase();
let createuuid2 = uuid.v4().replace(/-/g,"").toUpperCase();
console.log(createuuid1);
console.log(createuuid2);
           

这样就可以生成一个随机的uuid值了

v1和v4的区别

  1. 两个都是根据时间戳获取
  2. 如果同样时间生成的话v1方法生成的UUID相似度会比较高
  3. v4方法生成的UUID更偏向于Java中的UUID工具类,每次生成的值都会有很大的差别,辨识度也比较高,但是会有重复的概率
v1方法生成的UUID截图
前端学习——NodeJs基础篇一. NodeJs简介二. 安装NodeJs三. NPM简介四. HelloWorld五. NodeJs模块
下面是v4方法生成的uuid截图
前端学习——NodeJs基础篇一. NodeJs简介二. 安装NodeJs三. NPM简介四. HelloWorld五. NodeJs模块

我个人是偏向于使用v4方法的,个人习惯原因,当然使用v1方法也是挺不错的选择

以上就是NodeJS的基础部分,这篇文章里面仅仅展现了一些基础的知识,一些比较深的知识没有涉及到,仅限于入门阶段,当然里面有些观点可能也有不对的地方,大家看后如果发现什么观点有疑问可以多多提出,大家一起学习,共同进步!!!

继续阅读