node
node基础概念
什么是node
-
基于 Chrome V8 的 JS 运行时环境
- 不存在兼容问题
- 环境:配置在电脑里面的一个程序, 不存在桌面图标, 依靠命令行
和 前端 js 的区别
-
前端
-
DOM
- 文档对象模型
- 基于html
-
BOM
- 浏览器对象模型
- 基于浏览器
-
ECMAScript
- js 的语法
- 规定了代码怎么写
-
-
后端
-
ECMAScript
- js 的语法
- 规定了代码怎么写
-
操作电脑的能力
- 基于node
- js 文件是在命令行运行, 再电脑系统里面运行
-
为什么node要用模块化开发
-
前端
- js 文件是引入在 html 文件中使用的
- 多个 js 文件时引入在一个 html 文件中
- 共享一个 window
- 需要在其他文件里面使用的方法
- 直接挂载在 window 上, 或者就直接写在全局
-
node
- 每一个 js 文件都是相对独立的
- 互相之间没有任何关系, 我们没有一个统一调配的东西
- 综上,只能靠模块化开发
node 可以进行什么样的开发
-
- 数据服务器
- 专门书写接口
- 前后端分离式的开发
-
- 渲染服务器
- 除了书写接口,还要负责页面的返回和渲染
- 在 node 中把页面中需要的所有数据直接组装好
- 返回给前端一个组装好的页面
- 优点: 有利于 搜索引擎
- 缺点: 服务器压力太大
-
- 中间层渲染
- 作为一个中转服务器
- 提供页面
- 前端 <-> node 中间层 <-> 数据服务器
- 优点: 有利于 搜索引擎, 对于 node 服务器压力不大
- 缺点: 开发成本高
服务端渲染的node 开发文件夹分类
-
public
- 放静态资源
- 前端页面需要的静态资源(js, css, image, audio, …)
-
views / pages
- 放前端的显示的页面
-
db
- 放数据库操作
-
app.js
- 服务器启动文件
-
model
- 服务器需要用的各种独立封装模块
-
…
node基本操作
node 运行 js 文件
-
方法一: 打开命令行, 输入 node 回车
- 表示已经运行 node
- 再命令行输入 js 代码来执行
- 缺点: 代码留不下来
-
方法二:打开命令行, 输入 node 要执行的文件 回车
- 把 js 代码写在一个 .js 后缀的文件里面
- 通过命令行运行
模块化分类
什么是模块
- 一个 js 文件就是一个模块
- 把一类方法放在一个 js 文件里面, 这个 js 文件就变成了一个模块
- 再需要哪一类方法的时候, 引入这个 js 文件就可以使用了
什么是模块化
- 开发的过程中, 尽可能把开发方式趋近于模块的方式
- 把所有的内容都按照类别分好文件
- 按需引入
模块化的分类
-
自定义模块
- 自己按照模块化的语法, 开发的 js 文件
- 自己定义模块, 自己再需要的时候导入模块使用
- 自己决定模块内哪些内容向外暴露
-
内置模块
- node 这个环境天生自带的一些模块(“一个一个的 js 文件”)
- 需要使用的时候, 直接引入使用就好了
-
第三方模块
- 其他人把一些常用功能直接封装好
- 做了开源,使用时候,先下载下来,直接导入按照规则使用
自定义模块
定义模块
-
在每一个 js 文件里面,自带一个变量, 叫做 module, 表示模块,用来描述这个文件(模块)的
-
文件定义好以后, 想让别人使用的东西, 就放在 module.exports 里面导出
-
- 标准导出
module.exports.fn1 = fn1
module.exports.num = 100
此时module.exports = { fn1: function () {}, num: 100 }
-
- 两种其他方式
-
- 给 module.exports 从新赋值
module.exports = {
fn1: fn1,
num: 100
}
```
-
- 利用 exports 向外暴露内容
exports.fn1 = fn1
exports.num = 200
exports.str = 'hello world'
exports = {
fn1: fn1,
num: 100,
str: 'hello world'
}
- 思考:为什么从新赋值的时候, exports 不好使
- 使用 obj 模拟 module
var obj = {
exports: {}
}
- 使用 exp 模拟 exports
var exp = obj.exports
- 需求: 想 exports 里面添加一个 num 一个 str
- 1.
obj.exports.num = 100
obj.exports.str = 'hello'
- 2.
obj.exports = {
num: 100,
str: 'hello'
}
- 结论:
本身 exp 代表的是 obj.exports
现在 exp 代表一个新的对象, 不再代表 obj.exports
现在只是向一个对象里面添加内容
但是向外导出的还是 obj.exports
使用模块
-
就是把其他模块导入到自己的文件里面,使用另一个文件导出的内容
-
每一个 js 文件里面自带一个方法 require()
-
语法: require(‘要导入的 js 文件路径’)
- 如果后缀是 .js 可以省略不写
-
返回值: 被导入文件里面的 module.exports
-
-
导入以后, 就可以使用文件里面向外暴露的内容
内置模块
fs 模块
-
概述
-
file system 文件系统模块
-
这个模块里面封装的方法都是和操作 文件 和 文件夹 相关的内容
-
node 自带的一个模块
-
直接导入使用
- const fs = require(‘fs’)
-
-
方法
-
- readFile()
-
异步读取文件
-
语法: fs.readFile(路径, 读取格式, 回调函数)
- 路径: 你要读取的文件的路径, 如果路径不存在, 会出现错误(但不会报错)
- 读取格式: 选填, 默认是 buffer, 我们可以选填 ‘utf8’
- 回调函数: 读取成功以后会执行的函数
-
- readFileSync()
- 同步读取文件
- 语法: fs.readFileSync(路径, 读取格式)
- 返回值: 读取的文件内容
- 注意: 读取路径不存在, 或者没有权限的时候, 会报错, 打断程序的继续执行
-
- writeFile()
-
异步写入文件
-
语法: fs.writeFile(路径, 要写入的内容, 回调函数)
- 路径: 你要写入文件的路径, 如果路径文件不存在, 会创建一个这个文件再写入
- 写入的内容: 自己定义
- 回调函数: 写入成功以后执行的函数, 必填
-
注意: 完全覆盖式的写入
-
- writeFileSync()
- 同步写入文件
- 语法: fs.writeFileSync(路径, 要写入的内容)
- 注意: 完全覆盖式的写入
-
- appendFile()
-
异步追加内容
-
语法: fs.appendFile(路径, 追加的内容, 回调函数)
- 路径: 写入文件的路径, 没有该路径, 自己创建
- 追加的内容
- 回调函数: 必填
-
- appendFileSync()
- 同步追加内容
- 语法: fs.appendFileSync(路径, 追加的内容)
-
- readdir()
- 异步读取文件夹
- 语法: fs.readdir(路径, 回调函数)
-
- readdirSync()
- 同步读取文件夹
- 语法: fs.readdirSync(路径)
-
- mkdir()
- 异步创建文件夹
- 语法: fs.mkdir(路径, 回调函数)
-
- mkdirSync()
- 同步创建文件夹
- 语法: fs.mkdirSync(路径)
-
- rmdir()
- 异步删除文件夹
- 语法: fs.rmdir(路径, 回调函数)
-
- rmdirSync()
- 同步删除文件夹
- 语法: fs.rmdirSync(路径)
-
- unlink()
- 异步删除文件
- 语法: fs.unlink(路径, 回调函数)
-
- unlinSync()
- 同步删除文件
- 语法: fs.unlinkSync(路径)
-
- stat()
-
异步查看
-
语法: fs.stat(路径, 回调函数)
- 回调函数里面可以接收一个 data
- 表示查看的这个路径的内容
-
- statSync()
- 同步查看
- 语法: fs.statSync(路径)
- 返回值: 查看该路径的结果
-
- isFile()
-
注意: 只有 stats 可以调用
- stat 的 回调函数中的 data
- statSync 的返回值
-
语法: stats.isFile()
-
返回值: 一个布尔值
-
18: isDirectory()
-
注意: 只有 stats 可以调用
- stat 的 回调函数中的 data
- statSync 的返回值
-
语法: stats.isDirectory()
-
返回值: 一个布尔值
-
-
path 模块
-
概述
-
里面封装的是一些操作路径的或者和路径相关的方法
-
node 自带的一个模块
-
直接导入使用
- const path = require(‘path’)
-
-
方法
-
- join()
- 拼接相对路径
- 语法: path.join(路径1, 路径2, 路径3, …)
- 返回值: 拼接好的路径结果
- 注意:拼接规则是后一个参数是前一个参数的子级。除非写…/
-
- resolve()
-
拼接绝对路径
-
语法: path.resolve(路径1, 路径2, 路径3, …)
-
返回值: 拼接好的绝对路径
-
注意:拼接规则是每一个参数都是相对独立的一个参数
-
拓:路径表示
- xx 当前目录下
- ./xx 当前目录下
- …/xx 上一级目录
- /xx 根目录
-
-
- extname()
- 获取文件后缀名
- 语法: path.extname(文件名)
- 返回值: 该文件的后缀名
-
- isAbsolute()
-
判断路径是不是绝对路径
-
语法: path.isAbsolute(路径)
-
返回值: 一个布尔值
-
路径区分:
- 绝对路径: 从根目录开始的路径
- 相对路径: 不是从根目录开始的路径
-
拓:每一个 js 文件里面自带两个变量
-
- __dirname: 表示该文件所在的文件夹的绝对路径
-
- __filename: 表示该文件的绝对路径
-
-
- parse()
- 解析路径信息
- 语法: path.parse(路径)
- 返回值: 一个对象, 里面包含该路径的所有信息
-
url 模块
-
概述
-
里面封装的都是和 url 地址栏相关的方法
-
node 自带的一个模块
-
直接导入使用
- const url = require(‘url’)
-
-
方法
-
- parse()
-
解析 url 地址的方法
-
语法: url.parse(url 地址, 是否解析查询字符串)
-
地址: 要解析的地址
-
是否解析查询字符串: 默认是 false, 选填 true
- 会把地址里面的查询字符串解析成一个对象的形式
-
-
返回值: 是一个对象, 里面包含整个 url 地址的所有信息
-
http 模块
-
概述
-
主要是用来创建一个 http 服务的模块
-
node 自带的一个模块
-
直接导入使用
- const http = require(‘http’)
-
-
方法
-
- createServer()
-
创建服务的方法
-
语法: http.createServer(function () {})
- 每一个请求进来的时候, 都会触发函数
-
返回值: 一个服务
-
- listen()
-
注意: 需要使用 服务(createServer 的返回值) 来调用
-
语法: 服务.listen(端口号, 回调函数)
- 端口号: 0 ~ 65535, 尽量不使用 1024 以下
- 域名: 默认是本机 localhost || 127.0.0.1
-
当 listen 执行以后
- 命令行, 就会被变成了一个服务器,一个什么都没有的服务器
- ocalhost:xxxx(端口号) 的时候, createServer 后面的函数就会执行
-
第三方模块
第三方模块的使用
-
- 下载, 使用 npm 下载
- 确定好一个目录进行下载
- 在一个项目里面, 把所有的第三方包都放在一个目录下
- paths: [
] - 只要 node_module 文件夹在这些里面 他都可以找到
-
- 在需要的位置导入
- 直接 require(包名)
- 不需要 .js 后缀
-
- 第三方包的使用没有规则
- 要去官网看
第三方模块
-
moment
-
专门用来格式化时间
-
官网: https://momentjs.com/
-
使用
- const moment = require(‘moment’)
- moment(时间对象).format(格式化规则)
- 在导入包以后, 使用方法之前, 可以设置一下语言环境
-
-
nodemailer
-
专门用来发邮件
-
使用
-
const nodemailer = require(‘nodemailer’)
-
- 使用 nodemailer 创建一个 发送器(邮差)
-
语法: nodemailer.createTransporter(配置文件{})
- 参数位置: 需要一些内容
- 对邮件发送放的配置
- 直接在包里面找到 -> nodemailer -> lib -> well-known
- 例:
-
-
const transporter = nodemailer.createTransport({
"host": "XXXX",
"port": 465, //STMP端口号
"secure": true,
// 发送方用户名和密码验证
// 使用的 smtp 的用户名和密码
auth: {
user: 'XXXX',
pass: 'XXXXX'
}
})
- 返回值: 就是一个发送器
-
- 使用发送器去发送邮件
-
sendmail(邮件的配置{}, 回调函数) 方法
- from
- to
- subject: ‘标题’
- text: ‘’ 文本内容
- html: 超文本内容
- 例:
transporter.sendMail({
from: 'XXX',
to: 'XXXX',
subject: 'XXX',
text: '', // 文本内容
html: 'XXXXXX', // 超文本内容
}, function (err, info) {
if (err) return console.log(err)
console.log('发送成功')
console.log(info)
})
-
mysql
-
专门用来连接 mysql 数据库
-
使用
-
const mysql = require(‘mysql’)
- 导入 mysql
-
mysql 包提供了两个连接数据库的方式
-
- createConnection()
- 语义趋近于单次连接单次使用
- 连接, 执行 sql 语句, 关闭
- 最好是执行一次 数据库操作关闭一次
-
- cretaePool()
- 创建一个连接池
- 语义趋近于打开就不关了
-
-
-
使用 db 模块执行 sql 语句
-
- db.query(sql, 回调函数)
-
- db.query(sql, [], 回调函数)
- 在 sql 语句里面预埋好多 问号(?)
- 在数组里面依次传递参数
-
-
模板引擎
art-template
- 前端可以使用
- 后端可以单独使用
- 后端可以 express 框架结合使用
作用
- 快速渲染页面
前端使用模板引擎
-
- 下载
- npm i art-template
-
- 引入 template-web.js 文件
- const template = require(‘art-template’)
- 文件引入以后会向外暴露一个 template 方法
-
- 准备一个 script 标签, 书写模板
-
为什么使用script标签
- 因为 script 标签里面书写的内容不会显示在页面上
-
注:
- script 有一个属性叫做 type=“text/javascript”,如果直接书写会被当作js代码执行
- 解决:只要把 type 属性随便换成别的内容, 就不会当作 js 代码执行
- 推荐:写成 text/html 或者 text/template, 因为会有代码高亮
-
给这个模板 script 标签书写一个 id 属性
- 为了便于捕获元素
-
- 使用模板渲染页面
-
template 方法
-
语法: template(模板id, {})
- 模板 id , 就是模板标签的 id 属性(必须是 id)
- {}: 在模板里面使用的数据, 没有就传递一个空对象
-
模板语法
-
- 输出内容
-
原生 js
-
<%= 变量 %>
- 不认识 html 格式
-
<%- 变量 %>
- 认识 html 格式
-
-
模板语法
-
{{ 变量 }}
- 不认识 html 格式
-
{{@ 变量 }}
- 认识 html 格式
-
-
- 条件判断
-
原生 js
- <% if () { %>
根据 if 条件决定 这个位置的内容是不是渲染
<% } else { %>
根据 if条件决定 这个位置的内容是不是渲染
<% } %> - 布尔值为true 显示
- 布尔值为false 不显示
- <% if () { %>
-
模板语法
- {{ if 条件 }}
{{ /if }}
-
- 循环渲染
-
原生 js
- <% for () { %>
这个位置的结构会根据 for 循环渲染多少次
<% } %>
- <% for () { %>
-
模板语法
- {{ each 数组 }}
{{ /each }}
后端模板引擎( node使用art-template)
-
art-template
-
是一个专门用来帮助渲染页面的第三方
-
直接导入使用
- const template = require(‘art-template’)
-
-
方法:
-
- render()
-
语法: template.render(字符串, {})
- 字符串: 只要有模板语法就可以
- {}: 在模板语法里面使用的内容
-
返回值: 一段组装好的字符串
-
XMind: ZEN - Trial Version