文章目录
Node.js
介绍
为什么要学Node.js
- 废话,你学前端得知道这个,招聘信息里xx没写么(具有服务端开发经验,拥有基本的网站开发能力,服务端,前端,运维部署),愣着干嘛学啊?
- 帮助打开服务端。
- 更好配合服务端开发人员进行协同开发。
Node.js是什么
Node.js® 是一个基于 Chrome V8 引擎 的 JavaScript 运行时。
-
不是一门语言,不是库,不是框架
-
是一个JavaScript运行时的环境
-
可以做服务端的语言,假如后台服务器是个黑盒子,那么Node就是帮你打开这个黑盒子的工具。当然,不仅仅是Node可以,以下的也可以
- Java
- PHP
- Python
- Ruby (GitHub网站)
- .Net (C#)
- Node.js (采用JavaScript,作为一个前端,不需要为了学后台而去学习新的语言了)
-
凡是能用JavaScript来实现的,最终都能用JavaScript来实现。
-
https://nodejs.org/zh-cn/ 这个Node的中文网站
浏览器的JavaScript | Node.js中的JavaScript |
---|---|
ECMAScript | ECMAScript |
BOM | - |
Dom | - |
- | 提供服务器级别API |
- 开源生产库
npm
,他是世界上最大的开源库生态系统,你可以用它来安装各种包。 - 构建在Chrome的V8引擎上
- 我们写的代码就是字符串而已,然而浏览器引擎可以帮你去解析和执行,目前Chrome V8是公认最快的引擎
- Node.js 的作者把V8引擎移植出来,开发了独立的运行环境。
Node.js能做什么
- Web 服务器后台
- 游戏/结果服务器
- 命令行工具
- npm(node)
- git(c语言)
- Hexo(node)
要学会的
- B/S 编程模型
- Browser-Server
- Node 只是我们学习BS 编程模型的工具
- 模块化编程
- CSS
@import('文件路径')
- 在Node 中可以像
@import()
一样来引用加载 JavaScript
- CSS
- Node的常用API
- 异步编程
- 回调函数
- Express 开发框架
- EcmaSctipt6 语法
起步
安装Node
- 确认Node 环境是否安装成功
- 打开命令行,输入
node -v
,如果有版本号显示,就说明成功了。
- 打开命令行,输入
Hello World
- 创建并编写JavaScript脚本文件
- 打开终端,定位脚本文件所在目录
- 输入
node 文件名
,执行脚本(注意不要把文件名字起成node.js)
NPM
- node package manager 是包管理工具
安装命令
-
npm install 包名 [–save]
-
–save 会将安装的包记录到package.json的dependencies中
-
npm i 包名 -D //-d是–save-dev缩写
-
将包安装记录到devDependencies中,执行 npm install 时,可以指定安装哪些包
-
package.json用于记录项目中用了那些包,方便管理
语义化版本
^version
:中版本
^1.0.1 -> 1.x.x
~version
:小版本
~1.0.1 -> 1.0.x
- version:指定版本
命令行工具
- npm网站(http://www.npmjs.com/)
npm常用命令
-
npm --version
npm版本号 -
npm install --global npm
升级npm -
npm init
构建项目
package name:包的名字,默认为当前目录名称 (名字不能有大写)
version:版本,默认从 1.0.0 开始
description:自述文件的信息或空字符串 ""
entry point: 入口文件
test command: 可以为空,npm test 为测试模块的命令
git repository:git 仓库
keywords:关键词
author:作者
license: 许可证 ISC
-
npm init -y
跳过向导快速生成 -
npm install
根据 package.json 自动下载所需的包,也可以简写成npm i
-
npm install 包名 --save
npm i -S
根据包名下载,并保存依赖在项目中的 package.json
文件中
npm uninstall 包名 --save
npm un -S
根据包名删除,并且删除依赖项
-
npm help
查看帮助 -
npm 命令 --help
查看命令帮助
npm镜像
-
npm服务器在国外,网速慢,淘宝镜像:http://npm.taobao.org
-
使用方式1:安装淘宝镜像
npm install --global cnpm
,将npm替换成cnpm -
使用方式2:npm install jquery --registry=https://registry.npm.taobao.org
-
使用方式3:npm config set registry https://registry.npm.taobao.org,配置后每次npm都是从配置的路径下载
自定义工具包
- 你可以自己写一个工具,然后再你的项目中导入,你的工具不要放在
node-module
里,不然别人会以为你的是第三方包
API
核心模块
Node为JavaScript提供了很多服务器级别的 API ,这些 API 绝大多数都被包装到了一个具名的核心模块中了。例如文件操作的fs
核心模块,http 服务构建的 http
模块,path
路径操作模块,os
操作系统模块等。
读取文件
-
浏览器中的JavaScript 是没有文件操作的能力的,但是Node中的JavaScript具有文件操作的能力
-
fs是 Filesystem 的简写,就是文件系统的意思
在 Node 中如果想要进行文件操作,就必须引入 fs 这个核心模块
在 fs 这个核心模块中,就提供了所有的文件操作相关的 API
// 1. 加载使用 require 方法加载 fs 核心模块
var fs = require('fs')
// 2. 读取文件
/*
第一个参数:文件路径
第二个参数:回调函数(err,data)
如果成功读取文件:data=数据, err=null
失败:data=null,err=错误对象
相对路径必须加./
如果想要返回上层目录用 ../
*/
fs.readFile('./a.txt', function (error, data) {
console.log(error)
console.log(data)
//<Buffer 6e 69 68 61 6f>
// 文件中存储的其实都是二进制数据 0 1
// 这里为什么看到的不是 0 和 1 呢?原因时二进制转为 16 进制
// 我们可以通过toString()转化
console.log(data.toString())
})
写文件
-
fs.writeFile('文件路径', '写入内容', '回调函数')
-
写文件的文件名中不能有特殊字符,比方说
?
,<
,’>'之类的。
// 写文件
var fs = require('fs')
fs.writeFile('../data/nihao.md', '你好,我叫Node', function (error) {
if(error === null){
return
}else{
console.log('文件写入成功')
}
});
创建个简单的服务器
// 非常轻松的构建一个 Web 服务器
// 1. 加载 http 核心模块
var http = require('http')
// 2. 创建服务
// 返回一个 Server 实例
var server = http.createServer()
// 3. 服务器能干吗
// 提供服务:对数据的服务
// 注册 request 请求事件
server.on('request', function (request, response) {
var url = request.url
response.write(url)
response.end()
// console.log('收到客户端的请求了')
// response 对象有一个方法:write 可以用来给客户端发送相应程序
// write 可以使用多次,但是最后一定要使用 end 来结束响应
})
// 凡是需要网路通信的都需要端口号
server.listen(3000, function () {
console.log('服务器启动成功了!')
})
设置编码
- 我们需要告诉浏览器我是中文操作系统,你得给我翻译成中文,不然我看不懂啊
Content-Type
告诉对方我给你发送的数据类型是什么类型text/plain
https://tool.oschina.net/commons- https://tool.oschina.net/ 在这里可以对应查找一些有用的
server.on('request', function (req, res) {
// 服务器默认发送的数据,其实是 utf8 编码的内容
// 但是浏览器不知道你是 utf8 编码的内容
// 世界上所有的语言韩文日文等,都是 utf8
// 中文操作系统默认是 gbk
// 所以我们要告诉浏览器,我给你发送的内容是什么
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('hello 世界')
})
读取目录
fs.readdir('D:\\study\\前端\\Node重学', function (err, files) {
if (err) {
return '目录不存在'
}
console.log(files)
})
回调地域
问题描述:
解决的方案可以这样
var fs = require('fs')
fs.readFile('./text1.txt',function(err, data){
setTimeout(()=>{
console.log(data.toString())
fs.readFile('./text2.txt',function(err, data){
console.log(data.toString());
fs.readFile('./text3.txt',function(err, data){
console.log(data.toString());
})
})
},2000)
})
但是这样一层层的嵌套,多了的话会出现如下情况,非常的不美观
如何解决呢,用promise
var fs = require('fs')
// resolve 承诺成功,reject承诺失败
new Promise((resolve, reject) => {
setTimeout(() => {
fs.readFile('./text1.txt',function(err, data){
resolve(data)
})
}, 1000)
}).then(function(data){
console.log(data.toString())
return new Promise(function(resolve, reject){
fs.readFile('./text2.txt',function(err, data){
resolve(data)
})
})
}).then(function(data){
console.log(data.toString());
return new Promise(function(resolve, reject){
fs.readFile('./text3.txt',function(err, data){
resolve(data);
})
})
}).then(function(data){
console.log(data.toString());
})
模块化
简单的模块化
require
这个方法专门用来引入模块
我有三个文件a.js
、b.js
、 c.js
// a.js
// require 是一个方法
// 他的作用就是用来加载模块
// 在Node 中,模块有三种:
// 1.核心 2.用户自己编写的 3.
// 相对路径必须加./
console.log('开始执行a')
require('./b.js')
console.log('结束执行a')
//开始执行a
// b.js文件被执行
// 结束执行a
// b.js
console.log('b.js start')
require('./c.js')
console.log('b.js end')
// c.js
console.log('ccccc')
# 开始执行a
# b.js start
# ccccc
# b.js end
# 结束执行a
模块作用域
- 简单的说,外部访问不到内部,内部也访问不到外部,就在这个文件里面。
- 同名的变量名字,在不同的模块里,也不会相互污染
模块间的通信
我现在又有两个a.js
,b.js
,分别是
// a.js
var app = require('./b.js')
// require 方法有两个最哦用
// 1.加载文件模块并执行里面的代码
// 2. 拿到被加载文件模块导出的接口对象
// 在每一个文件模块中都提供一个对象:expore
console.log('app:', app)
console.log('app:', app.foo)
// b.js
var foo = 'bbb'
exports.foo = foo
// 导出的是一个对象,不论是变量还是方法,都需要a文件里点出来使用
console.log('exports:', exports)
运行之后的结果是
exports: {}
app: {}
# 他俩是等价的
如果你想引用的话,就要在b中把想要暴露的变量挂载到exports
上
Express 模块
- 就是http原生的封装,为了便于开发
响应头
- 如果访问的网站,之后下载了,这是响应头的问题
res.set('Content-Type, 'text/html')
指定公开路径
app.use('/public',express.static('./public/'));
访问路径:http://localhost:8000/public/test.html
app.use(express.static('./public/'));
访问路径:http://localhost:8000/test.html
模板引擎
npm install --save art-template
npm install --save express-art-template
- 默认是在
views
这个文件夹名称下寻找页面 - 使用的方法如下
var express = require('express');
var app = express();
//配置模板引擎 以.art结尾时使用模板引擎
app.engine('art', require('express-art-template'));
app.set('view options', {
debug: process.env.NODE_ENV !== 'production' // 配置生产模式
});
app.get('/', function (req, res) {
//express为response提供了一个方法:render,此方法默认不可以使用,配置了模板引擎才可以使用
//res.render('模板名',{模板数据})
//第一个参数, 默认去项目的views目录中查找,如果想修改默认路径:app.set("views",'路径')
res.render('index.art', {
user: {
name: 'aui',
tags: ['art', 'template', 'nodejs']
}
});
});
中间件
中间件(Middleware
) 是一个函数,它可以访问请求对象(request obj ect (req)), 响应对象(response object (res)), 和 web 应用中处于请求-响应循环流程中的中间件,一般被命名为 next 的变量。
- 新版本中的
express
内置集成了中间件 express
中没有内置获取表单psot
请求体的Api
:使用中间件- 应用级中间件绑定到 app 对象 使用
app.use()
热启动
-
改代码的时候就不需要在启动一次服务器了
-
安装
npm i --global nodemon
使用
nodemon app.js
端口号
- 所有联网的程序都需要进行网络通信
- 计算机中只有一个物理网卡,同一个局域网中,网卡的地址必须唯一的。网卡是通过唯一的IP地址来进行定位的。
- 每一个联网的应用对应一个端口号
- IP地址用来定位计算机,端口号用来定位具体的联网应用程序
- 获取访问我的另一条电脑的IP地址和端口号
req.socket.remoteAddress
,req.socket.remotePort
- 端口号的范围从 0~65536 之间
- 网站上线部署的时候默认是80端口,所以80的话尽量不要用
跨域以及同源策略
- 只有当协议(http,https),域名,和端口号三者都一直的时候,才是同源
- 同源安全是浏览器行为,请求到后台的话后台也会处理,但是返回到前台浏览器不允许展示
- 如何解决跨域:第一种方法是后台设置响应头
res.header('Access-Control-Allow-Origin', '*')
,其中的*
可以写成同意跨域的IP地址,第二种方法是前台设置JsonP。
其他
- GFM Markdown的语法标准
- 代码风格
- JavaScript Standard Style
- 爱彼迎
-
代码风格
- 当你采用了无分号的代码风格的时候,只需要注意一下情况就不会有上面的问题
say()
//当一行代码是以( [ ` 开头的时候,则在前面补上一个分号用以鼊一些语法解析错误
;(function(){
console.log('hello')
})()