Node.js

修改软件安装的路径: 

此电脑右击 → 属性 → 高级系统设置 → 环境变量 → 选中path → 编辑 → 修改路径 → 确定

定义区别:

一、浏览器中的JS

1、浏览器中的JS组成

JS核心语法(ECMAScript) 和 WebAPI(浏览器内置的API)

2、为什么JavaScript 可以在浏览器中被执行?

代码通过 浏览器内核中的 CSS引擎和JS解析引擎 转换成最终的效果;

因为不同的浏览器有不同的解析引擎,所以最终效果都不一样;

3、JS运行环境

运行环境是指代码能正常运行所需的必要条件;

JS运行环境组成
ECMAScript + 浏览器浏览器 = 内置API+解析引擎+控制台+显示界面
ECMAScript + Node.jsNode.js = 内置模块 + 内置API

区别:

  • Node.js后端语言;
  • 浏览器是 JavaScript 的前端运行环境。(浏览器是客户端安装的软件);

  • Node.js 是 JavaScript 的后端运行环境。(正常情况下,Nodejs要安装到服务器上);

二、Node.js基础

官网:Node.js

学习文档:API 文档 | Node.js 中文网

1、Node.js的用处

Node.js一个基于 Chrome V8 引擎的JavaScript运行环境。

2、终端窗口

终端窗口:可以执行命令的窗口;(git的 “Git Bash Here” 窗口也属于终端窗口)

系统内置终端窗口打开方法
cmd(最优)  在JS文件夹地址栏的位置,输入cmd,回车
window+R → 输入'cmd' → 回车
powershell在JS文件夹空白处shift+右击 → 选择"在此处打开 PowerShell 窗口"
VScode中的终端窗口ctrl+~        (用的还是系统的终端)
美化终端窗口教程网址
Windowsoh-my-posh: windows终端配置
Macohmyzsh: 打不开GitHub的用户,如何安装ohmyzsh
软件(hyper)

3、基础系统命令

1. 返回node版本号(说明安装成功了)
    node -v
2. 切换终端路径(change directort 切换目录)
    cd 路径  切换到下层
    cd ..    切换到上层
    cd /     切换到根目录
3. 清屏
    cls  (cmd中用cls清屏,其它终端用clear清屏)
4. tab键 自动补全命令

4、怎么在Node.js环境下执行js代码

在JS文件夹中打开终端窗口,输入     node  要执行的js文件(xxx.js)

注意:打开终端窗口的路径和node后面写的js路径(可以是code\01.js);

      Node.js不止执行.js后缀的文件,而是执行文件里的js代码(也可执行.txt文件里的js代码);

三、模块化

1、模块化的优点

  • 更利于维护;
  • 有更好的复用性;

2、导入、导出JS文件

1. 共享的JS文件  (module是Node中的一个全局对象)
    module.exports = 共享的内容

    module.exports = shy                 共享一个内容(可以是数字、字符串、数组、对象等)
    module.exports = {one:shy,two:bj}    共享多个内容要以对象的形式
    module.exports = {shy,bj}            当变量名=属性值时,可以按ES6的写法
2. (导入) 使用共享的文件
    const 变量 = require('模块路径')
    const obj = require('./03-one')
相当于 const obj = shy 或 {one:shy,two:bj} 或 {shy,bj} 
使用时             obj     obj.one()           obj.shy()

注意:(1) 导入模块的时候,路径必须写全, ./ 也不能省略(即写相对路径)
      (2) 可以省略 .js 后缀

3、json文件的写法

  • json文件中只能有一类(组)数据;

  • json文件中可以是数组、对象、字符串、数字、布尔、null,不能有undefined、函数、注释;

  • 属性名和属性值都要加双引号;

4、模块的分类

模块本质上是 对象,学的是这些对象的方法.

(1)自定义模块

自己创建的JS文件都是自定义模块

(2)内置模块,加载得到的是对象

内置模块是Node.js 平台自带的一套基本的 API(功能模块),也叫做核心模块。

文档:API 文档 | Node.js 中文网

1)path模块

加载path模块
const/let 变量 = require('path')
const { 方法名 } = require('path')  解构赋值
const { join } = require('path')

    const path = require('path')       // 导入,path 是对象  
1. path.join 拼接路径(把给出的几部分路径拼接到一起,返回一个完整的路径)
    path.join('a','b','c')                  // 结果:a/b/c
    path.join('a','b','../c','index.js')    // 结果:a/c/index.js

2. __dirname    当前js文件的绝对路径(不包含文件名,只包括路径部分) D:/aa/bb/cc
   __filename   当前js文件的绝对路径(包含文件名)                  D:/aa/bb/cc/01.js

3. path.join 和 __dirname 结合得到文件的绝对路径 (重点)
    path.join 或 join(__dirname, 'js文件名')
    path.join(__dirname, '01.js')      得到了01.js在电脑中的绝对路径

path里的方法作用
path.basename('文件名')返回 path 的最后一部分(文件名)
path.dirname(path)返回目录名
path.extname(path)返回路径中文件的扩展名(包含.)
path.format(pathObject)将一个对象格式化为一个路径字符串
path.join([...paths])拼接路径
path.parse(path)把路径字符串解析成对象的格式
path.resolve([...paths])基于当前工作目录拼接路径

2)fs文件系统

fs(file system)可以实现对 文件、文件夹的操作;

导入fs模块
    const fs =  require('fs')
    const { readFile } =  require('fs')
    const { writeFile } =  require('fs')
    const {readFile,writeFile}=require('fs')   同时获取readFile和writeFile方法

1. 读取文件
fs.readFile 或 readFile  = ('要读取的文件名','utf-8',(err,data)=>{
    // err 表示这次读取文件是否有错误发生;没有错误err=null,有错误err={}
    // data 表示读取的结果

    if(err) return console.log(err) 
 或 if(err) throw err     // 抛出错误,遇到throw也会终止代码执行
    console.log(data)    // 如果有错输出错误,没有错输出数据
})

2. 写入文件
    fs.writeFile 或 writeFile = ('要添加内容的文件名','内容',err=>{ })
注意:1.如果写入的文件不存在,会自动创建文件(但是不会递归层级创建);
     2.如果文件存在并且里面有内容,写入的内容会覆盖之前的内容;
fs模块的方法作用备注
fs.access(path, callback)判断路径是否存在
fs.appendFile(file, data, callback)向文件中追加内容
fs.copyFile(src, callback)复制文件
fs.mkdir(path, callback)创建目录
fs.readDir(path, callback)读取目录列表
fs.rename(oldPath, newPath, callback)重命名文件/目录
fs.rmdir(path, callback)删除目录只能删除空目录
fs.stat(path, callback)获取文件/目录信息
fs.unlink(path, callback)删除文件
fs.watch(filename[, options][, listener])监视文件/目录
fs.watchFile(filename[, options], listener)监视文件

3)node中的全局变量

global、module、__dirname、__filename、console        跟document一样可以直接用

1、 __dirname    当前文件的绝对路径(不包含文件名,只包括路径部分) D:/aa/bb/cc
2、 __filename   当前文件的绝对路径(包含文件名)                  D:/aa/bb/cc/01.js

(3)第三方模块

npm网站:npm

npm更多的命令:npm 中文文档 | npm 中文网

npm(node package manage )node包管理器,即管理(下载、卸载、发布、删除)第三方模块的工具。

注意:npm这个工具不用再安装了,因为在安装 node 的时候,就已经安装到你的计算机中了。

全局安装的模块在任何文件夹都能用。

第三方模块分为本地模块 和 全局模块。

(3.1)本地模块

下载的模块的使用范围:能在本文件夹及后代文件夹中使用;

上课演示的是 jquery、mysql、moment、cors、express、echarts

a)初始化之后,会在项目目录中生成 package.json 的文件

1. 返回版本,说明npm安装成功
    npm -v
2. 初始化
    npm init      注意包名,回车
    npm init -y   直接初始化完毕

注意:该项目文件的名字不能有中文、特殊符号,不能和需要安装的第三方模块同名。

b)切换到npm的国内镜像网站taobao

3. 切换到国内地址的镜像网站
    下面的命令只需要执行一次即可(不管以后重启vscode还是重启电脑,都不需要执行第二次)
    npm config set registry https://registry.npm.taobao.org

c)下载安装第三方模块

下载的模块存放在当前文件夹的node_modules文件夹中,同时还会生成一个记录下载的文件 .package-lock.json (锁定版本的详细信息的文件) 。

4. 安装第三方包,默认安装最新版本
    npm install 模块名1 模块名2
    npm i 模块名1 模块名2
    npm i 模块 -S 或 --save    老版本,已弃用
5. 指定版本进行安装
    npm i 模块名@版本号
    npm i echarts@4.5.0
6. 开发时依赖,但开发完运行时就不需要了的模块(D为开发development)
    npm i 模块 -D
    npm i 模块 --save-dev
7. 一次性,将package.json中记录的包全都安装好
    npm i

d)卸载模块

8. 卸载
    npm uninstall 模块名1 模块名2
    npm un 模块名1 模块名2

(3.1.1)怎样使用第三方模块(例,dayjs)

  • 先下载安装第三模块,再加载模块 require('模块名');
  • 使用—调用模块提供的方法;
  • 不会使用的话,去找第三方模块的官网或文档,或者去百度;
dayjs的中文文档:https://dayjs.fenxianglu.cn/
dayjs 和 moment 都是时间日期处理模块,但dayjs 体积更小

使用dayjs将日期格式化:
var dayjs = require('dayjs')     // 加载dayjs模块
let timer = dayjs().format('YYYY-MM-DD HH:mm:ss')                // 将当前时间格式化
let timer = dayjs(1235562266322).format('YYYY-MM-DD HH:mm:ss')   // 将某一时间格式化
console.log(timer);

(3.1.2)package.json文件

在初始化之后,会生成 package.json(项目的配置文件)

(3.1.3)require的加载机制

(3.2)使用nrm管理全局模块

全局安装的模块,一般都是命令或者工具,不能通过 require() 加载使用;

全局模块装一次即可,不用用一次装一次;

1. 安装命令
    npm i 模块名 -g    或    npm i -g 模块名
2. 卸载命令
    npm un 模块名 -g
3. 返回全局安装的路径(全局安装的模块,在系统盘(C盘))
    npm root -g
4. 更新全局模块
    npm update -g 模块名
nrm的作用:切换镜像源(对npm网站做了备份的网站)

1. 全局安装 nrm
    npm i -g nrm
    
2. 查看所有可用的镜像源
    nrm ls  
3. 切换下载地址(镜像源)
    nrm use 下载地址
    nrm use taobao     国内镜像源taobao
    nrm use npm        npm主站

 全局下载nrm可能出现的错误及解决方法:

(1)

(2)如果报错如下“无法将 nrm 识别为 cmdlet、函数、脚本文件或可运行程序的名称。xxxxxxxxxxx”

解决办法,重启vscode,win7可能要重启电脑。

四、开发属于自己的包

1、包结构必须有的三部分

2、将包发布到npm主站

注意点:

  • 正常编写代码包,记得要共享导出;
  • 自己的包中也可使用其他人的包;
  • README 文件中要写明包的作用、用法、注意事项;
  • 自己的模块包名不能和已存在的(其他人发布的)模块名同名。(可以先去npm网站搜索是否同名)

3、更新包

  • 版本要修改,需要修改的比原来的版本号大一点;
  • 再次发布,即执行 npm publish

找以往的版本:versions

4、删除包

npm unpublish 包名 --force

注意:

  • npm unpublish 命令只能删除 72 小时以内发布的包
  • npm unpublish 删除的包,在 24 小时内不允许重复发布

五、ES6模块化

在 ES6 模块化规范诞生之前,JavaScript 社区已经尝试并提出了ADM、CMD、CommonJS等模块化规范。

模块化规范适用于
ADM适用于浏览器端的 Javascript 模块化
CMD
CommonJS

适用于服务器端的 Javascript 模块化

导出:module.export = 导出的内容

导入:require('模块')

ES6

ES6模块化规范是浏览器端与服务器端通用的模块化开发规范

导出(共享)关键字:export

导入关键字:import

1、在nodejs中使用ES6模块化的前置条件

  • node.js的版本要13+
  • 在 package.json 的根节点中添加 "type": "module" 节点   

type注意:

  • type,默认是commonjs,表示项目代码 只能 使用 CommonJS 语法(只能使用 module.exports 导出,使用require导入);
  • type 配置为 "module" 之后,表示项目代码 只能 使用 ES6模块化语法,在node环境下需要这样配置,浏览器下不需要;
  • 所以commonjs和ES6的语法不能混用;

2、三种导出/导入方式

(1)默认导出/导入

1. export default 导出内容   注:一个文件最多只能有一个默认导出
    export default [1,2,3]
    export default {id:12}

2. import 变量 from '模块路径(不能省略后缀)'
    import obj from './01默认导出.js'

(2)按需导出/导入

1. 谁要导出,就在前面加上export
    export let a = 123
    let b = [1, 2, 3]
    export function c() { console.log('shyone') }

2. 导入
    (1)一个一个导入 
        (变量名要和导出的名字一样; 当变量名有冲突时可定义别名—as ; 当只有一个变量时也要用{}包起来)
        import {变量,变量,变量,...} from '模块路径(不能省略后缀)'
      如: 
        import { a as aa, c } from './03按需导出.js'  // 变量名有冲突时定义别名
        console.log(aa)

    (2)一次性把全部的按需导出的内容,全部导入
        import * as 变量 from '模块路径(不能省略后缀)'
            注意:将所有的内容存入这个变量,这个变量是对象
      如:
        import * as das from './03按需导出.js'
        console.log(das.a);
        das.c()  // 用导出的方法

(3)无导出,只有导入

导入  常用于导入(css、less)资源文件
    import '模块路径'

总结

六、Promise

js是单线程的,不是多线程(异步)的,因为异步操作什么时候返回结果是不可控的,比如返回的顺序;

回调地狱(横向金字塔):让几个异步请求按照顺序来执行,那么就需要将这些异步操作嵌套起来,嵌套的层数特别多,形成回调地域。

promise是ES6新增的对象,用于解决回调地狱的问题(异步变同步)。

1、Promise的基本使用步骤

成熟写法见  六-5-(3)

不管怎么写,都是实现这两步
(1)得到promise对象
    (1.1)实例化new得到promise对象
    let 变量 = new Promise((resolve, reject) => { 这里放异步任务 }) })
    (1.2)通过第三方模块实现,比如 then-fs(调用readFile直接得到Promise对象)、比如axio(axios.post()直接得到Promise对象)
    (1.3)通过asyan函数的返回值得到Promise对象

(2)获取异步任务的结果
    (1.1)Promise对象.then(函数1,函数2)     函数1必写, 函数2可选
                相当于  resolve  reject
    (1.2)async和await

如:
// 1. 实例化promise对象
let p = new Promise((resolve, reject) => {
    // 这里放异步任务
    readFile('./a.js', 'utf-8', (err, data) => {
        // 这个异步任务成功将结果传递给resolve;失败将结果传递给reject
        err?reject(err):resolve(data.length)
    })
})

// 2. 获取异步任务的结果
p.then(
    res => { console.log(res) },    // 异步
    err => {console.log(err)}
)

2、Promise的特点

  • 调用resolve或者调用reject,表示promise达到了最终状态(结束了);
  • 一旦达到最终状态,则结果就固定了,不能再改变了;
  • 面试题:
    let p = new Promise((resolve, reject) => {
      resolve(123)                              // 调用它,表示承诺结束了,结果也固定了
      resolve(456)                              // 无效
      reject(789)                               // 无效
      setTimeout(() => { resolve(000) }, 1000)  // 无效
    })
    
    p.then(
      res => { console.log(res) },     // 结果:123
      err => { console.log(err) }
    )

3、同步或异步

  • new Promise是同步执行的;
  • 获取结果时(调用 resolve 触发 then方法时)是异步的;
  • console.log(1)
    let p = new Promise((resolve, reject) => {
      console.log(2)
      resolve(3)
      console.log(4)
    })
    console.log(5)
    
    p.then(res => {    // 这里的代码可以理解为是异步的,因为这里的代码会在所有的同步任务执行完毕才会执行
      console.log(res)
      console.log(7)
      console.log(8)
    })
    console.log(6)          输出结果为:1 2 4 5 6 3 7 8

4、链式调用

Promise实例化对象.then().then().then().........
前一个then返回一个Promise对象;这个Promise对象(resolve)的结果会被下一个then得到;
前一个then里面返回的Promise对象,并且调用resolve的时候传递给下一个then;若前一个then里面如果没有调用resolve,则后续的then不会接收到任何值;

如:
p1.then(res => { console.log(res); return p2 })    // 13    return p2 为return Promise对象
    .then(res => { console.log(res); return p3 })  // 16126
    .then(res => { console.log(res) })             // 23

可用于Promisde获取多个异步任务的结果

5、then-fs(第三模块)和async / await

(1)then-fs(第三模块)

  • then-fs是第三方模块(本地模块),更方便的读取、写入文件;
  • then-fs把内置的 fs模块中的大部分方法重新封装了,封装后的每个方法都返回的是Promise对象;
  • let { readFile } = require('then-fs')
    let p1 = readFile(filename, 'utf-8')     // p1是promise对象

(2)async / await

  • 作用:为了简化Promise的使用;
  • async 修饰的函数,总是返回一个 Promise 对象;
  • await操作符用于等待一个Promise对象。它只能在异步函数 async function 中使用。
async异步函数:获取异步任务的结果
    async function 函数名() {
        let r1 = await Promise对象      通过赋值的方式获取Promise对象的结果
    }

(3) Promise的最终写法(重点)

需求:按顺序异步读取文件

加载then-fs模块的方法
    let { readFile } = require('then-fs')

1. 获取实例化对象
    let p1 = raedFlie('./js/a.js','utf-8')   // 得到的是实例化Promise对象
    let p2 = raedFlie('./js/b.js','utf-8')
    let p3 = raedFlie('./js/c.js','utf-8')

2. 获取结果   async异步函数
    async function result() {
        let r1 = await p1     // 得到的是resolve的返回值
        let r2 = await p2
        let r3 = await p3
        console.log(r1, r2, r3)   // 输出的是各文件的字符length
    }
    result()

6、捕获异常

(1)catch

使用then获取,在链式的尾端加入catch来进行错误处理;

p1.then(res => { console.log(res.length); return p2;})
  .then(res => { console.log(res.length); return p3;})
  .then(res => { console.log(res.length)})
  .catch(err => {console.log(err)})

(2)try-catch

使用 async和await 获取结果,使用 try...catch... 来处理错误;

try{要做的事(到哪儿出错,就到哪儿结束)} catch (err){捕获到的异常}

七、事件循环

事件循环讨论的是 各种任务的运行时机、代码的执行顺序问题。

1、宏任务及微任务

2、事件循环过程

 举例

2.
setTimeout(() => {
  console.log(1)
}, 0)
new Promise((resolve, reject) => {
  console.log(2)
  resolve('p1')

  new Promise((resolve, reject) => {
    console.log(3)
    setTimeout(() => {
      resolve('setTimeout2')   // 无效,resolve一确定就不能更改了
      console.log(4)
    }, 0)
    resolve('p2')
  }).then(data => {
    console.log(data)
  })

  setTimeout(() => {
    resolve('setTimeout1')
    console.log(5)
  }, 0)
}).then(data => {
  console.log(data)
})
console.log(6)


输出顺序:2 3 6 p2 p1 1 4 5
2.
<script>
    console.log(1);
    async function fnOne() {
      console.log(2);
      await fnTwo(); // 右结合先执行右侧的代码, 然后等待
      console.log(3);
    }
    async function fnTwo() {
      console.log(4);
    }
    fnOne();
    setTimeout(() => {
      console.log(5);
    }, 2000);
    let p = new Promise((resolve, reject) => { // new Promise()里的函数体会马上执行所有代码
      console.log(6);
      resolve();
      console.log(7);
    })
    setTimeout(() => {
      console.log(8)
    }, 0)
    p.then(() => {
      console.log(9);
    })
    console.log(10);
  </script>
 <script>
    console.log(11);
    setTimeout(() => {
      console.log(12);
      let p = new Promise((resolve) => {
        resolve(13);
      })
      p.then(res => {
        console.log(res);
      })
      console.log(15);
    }, 0)
    console.log(14);
  </script>

输出顺序:1 2 4 6 7 10 11 14 3 9 8 12 15 13 5

八、搭建服务器

1、网络基础

Ajax 一_4  及  JavaScript 七_1_(4)

协议://主机地址:端口号/路径?参数#锚点

(1)URL地址

URL用于定位网络当中的资源,每个资源都对应着一个独一无二的URL地址。

(2)协议

协议类型说明默认端口号
HTTP

超文本传输协议,是一个基于请求与响应,无状态的,应用层的协议,常基于TCP/IP协议传输数据,互联网上应用最为广泛的一种网络协议,所有的WWW文件都必须遵守这个标准。

规定浏览器和服务器之间的语法和格式。

80
HTTPSHTTPS 是身披 SSL外壳的 HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性443

(3)主机地址

IP地址IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
域名域名需要单独购买
注意:域名和服务器的IP地址需要绑定,这样才可以通过域名找到主机电脑

(4)DNS服务器

DNS服务器用于记录 IP地址和域名的对应关系;

通过DNS服务器可以解析出 一个域名对应的IP地址;

本机缓存域名对应的IP地址的文件:C:\Windows\System32\drivers\etc

(5)端口号

  • 服务器端是有很多应用程序的,每个应用程序对应一个端口号;
  • 端口号的范围是 0 ~ 65535 ;(6000、6666是谷歌浏览器的保留端口,不可用)
  • 如果一个应用程序使用了3006端口号,其他的应用程序就不能再使用3006端口号 (一一对应,不可重复使用)。

(6)客户端请求服务器的步骤

  1. 先通过IP地址找到服务器

    1. 检测浏览器缓存有没有缓存该域名对应的IP地址。有则通过IP地址去找服务器

    2. 检测本地的hosts文件,是否有记录该域名对应的IP地址,有则通过IP地址去找服务器

    3. 如果是域名,要通过DNS服务器解析,找到该域名对应的IP地址,然后通过IP地址去找服务器

  2. 进行三次握手(确保双方发送和接收数据的能力,建立连接)

    1. 第一次握手是在建立连接,客户端发送连接请求报文段,把标有SYN的数据包发给服务器端即为接收端。

    2. 第二次握手是服务器端即接收端收到客户端的SYN的报文段,同时发送标有SYN/ACK的数据包。

    3. 第三次握手是客户端收到服务器端的SYN/ACK的数据包后,向服务器端发送标有ACK的数据包。

  3. 发送请求,传输数据。。。

  4. 服务器处理,并做出响应

  5. 浏览器接收响应结果。

  6. 四次挥手(作用是断开连接)

2、搭建服务器

自己的电脑IP地址和主机名:127.0.0.1    localhost

(1)使用内置模块http搭建服务器

1. 加载http内置模块
    const http = require('http')
2. 处理客服端的请求
    const server = http.createServer((req, res) => {
        // 服务器针对浏览器的请求做出的响应
        res.setHeader('Content-Type', 'text/html;charset=utf-8')
        // res.end()的两个问题:
             // 响应中文会乱码,必须自己加响应头;
             // 只能响应字符串或者buffer类型;
        res.end('你好!我是服务器')
    })
3. 指定端口号
    server.listen(3000, () => console.log('服务器搭建完毕!'))

在终端中使用node执行以上js代码,即服务器搭建完毕(自己的电脑就可做为服务器)。

(2)使用第三方模块Express搭建服务器

Express 是一个基于 Node.js 平台,快速、开放、极简的 web 开发框架。同类型产品 Koa

Express的用途:用于快速搭建服务器 (Express内部对核心模块http进行了封装);

Express官网:Express - Node.js web application framework

中文文档:Express - 基于 Node.js 平台的 web 应用开发框架 - Express 中文文档

Express GitHub仓库:https://github.com/expressjs/express

腾讯云开发者手册:Express 中文开发手册 - 开发者手册 - 云+社区 - 腾讯云

(2.1)搭建步骤:

  • npm init  初始化
  • npm i express   安装express
  • 中文网 --> 快速入门 --> Hello World ,复制里面的代码(见以下代码段)
  • 使用node运行js代码(表示你的服务器搭建好了,并且启动了)
  • 打开浏览器,输入localhost:3000 访问一下试试
步骤3复制的代码:
1. 加载express模块
    const express = require('express')
2. 创建APP对象
    const app = express()
4.1 设置端口号
    const port = 3000

3. 写接口(可改)
app.请求方式('/接口地址(名称自定义,/不可省略)', '接口的处理函数, 当客服端发来请求的时候,处理函数会自动执行')
req(request 请求):通过req可以获取到请求相关的信息,比如:请求方式、请求的url、请求头、请求参数、请求体
res(response 响应):和响应相关的所有操作都通过res实现,比如:设置响应头、响应状态码、响应体(做出响应)

    app.get('/', (req, res) => {
        res.setHeader('Author', 'shy')  // 设置响应头,但不能用中文
        res.status(200)                 // 设置响应状态码
        res.send('Hello World!')        // 做出响应,放在最后,send封装了默认的响应头,也可自己设置
    })
    app.get('/shy', (req, res) => {
      res.send('宋海燕')
    })

4. 指定端口,启动服务器
    app.listen(port, () => {
        // 服务器启动的提示
      console.log(`Example app listening on port ${port}`)
    })

res.send()方法注意点:

  • res.send() 用于做出响应;
  • 响应的内容同样不能为数字;?
  • 如果响应的是JS对象,那么方法内部会自动将对象转成JSON格式;
  • 而且会自动加Content-Type响应头;

(2.2)搭建服务器易出现的问题

a)终端窗口冻结问题

鼠标左键(小白方块)—冻结        鼠标右键—解冻

b)ctrl+c  停掉此服务器;

c)服务器只能启动一次,不然端口会冲突(被占用);

d)只要修改了 用来搭建服务器的JS代码 就要重启服务器 (此后用了nodemon模块就不用代码修改一次,服务器就启动一次);

3、测试接口工具

作用:模拟客户端向服务端发送请求,检测接口是否创建成功。

(1)Postman

见 Ajax 四_接口测试工具(Postman)

汉化:PostmanCn: Postman中文版

(2)ApiPost

Postman不需要注册,ApiPost需要注册;

4、nodemon全局模块

安装:npm i -g nodemon

作用:可以检测文件的变化,nodemon会自动重启服务(就不用ctrl+c再重启服务了)

命令使用:nodemon ./01.js    // 使用nodemon运行01.js用来搭建服务器的文件

5、案例

 Node.js阶段的 04-尝试写接口  写图书管理的接口

九、webpack

1、前端工程化

(1)概念:以模块化、组件化、规范化、自动化为基础,进项前端项目开发的方式,叫做前端工程化;

(2)四个现代化:

  • 模块化(js 的模块化、css 的模块化、资源的模块化)
  • 组件化(复用现有的 UI 结构、样式、行为)
  • 规范化(目录结构的划分、编码规范化、接口规范化、文档规范化、 Git 分支管理)
  • 自动化(自动化构建、自动部署、自动化测试)

(3)工程化的作用:工程化提供了一套标准的开发方案和流程,让前端开发自成体系;(注:企业中的 Vue 和 React 项目,都是基于工程化的方式进行开发的 前端工程化)

(4)前端工程化的解决方案

早期的前端工程化解决方案grunt(Grunt 中文网
gulp(gulp.js - 基于流(stream)的自动化构建工具
目前主流的前端工程化解决方案webpack(webpack 中文文档 | webpack 中文网
parcel(Parcel 中文网

2、webpack的基本使用

(1)作用及打包

用webpack处理,可以把项目中使用到的所有js文件融合到一起,形成一个js文件(main.js),而且可以解决浏览器端JavaScript的兼容性问题,这个融合的过程,就是打包

(2)webpack使用步骤

项目使用前要先初始化(npm init),package.json中的name不能和安装包的名字一样。

a)安装所需的包

先切换镜像源    nrm use taobao

安装项目开发依赖包
npm install webpack@5.58.2 webpack-cli@4.9.0 
            clean-webpack-plugin@4.0.0 webpack-dev-server@4.3.1 
            html-webpack-plugin@5.3.2 style-loader@3.3.0 
            css-loader@6.4.0 less-loader@10.1.0 less@4.1.2 
            url-loader@4.1.1 file-loader@6.2.0 babel-loader@8.2.2 
            @babel/core@7.15.8 @babel/plugin-proposal-decorators@7.15.8 -D

b)在package.json

在scripts节点中添加
"dev": "webpack"

c)在终端中运行命令,进行打包

npm run dev

d)打包后生成main.js文件,并将此文件引入到对应的html文件中

3、配置文件

(1)打包模式、打包入口、打包出口(记得html中引入)

4、webpack中的插件

这些插件就是让使用的时候方便一点;

在使用这些插件前都要安装这些包(可在package.json中查看是否安装好);

(1)clean-webpack-plugin(自动清理插件)

作用:每次打包时,自动清理 dist 目录,只留下打包后的出口文件;

在 webpack.config.js 中增加配置(配置自动清理插件):

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const cleanPlugin = new CleanWebpackPlugin();

module.exports = {
  mode: 'development',
  // 插件配置(和其他配置并列同级)
  plugins: [ cleanPlugin ]
}

(2)webpack-dev-server(自动打包插件)

配置 webpack-dev-server 步骤:

1. 修改 package.json -> scripts 中的 dev 命令如下:
    "scripts": {
          "dev": "webpack serve" // 注意这里是 serve,不是 server, 运行命令开启服务
    },
2. (可选)在 webpack.config.js 配置文件中对该插件进行配置
    devServer: {
      port: 9000,     实时打包所用的端口号,不配置默认的是8080
      open: true      初次打包完成后,自动打开浏览器,默认为false
    }
3. 这个插件自动打包生成的文件会存放到了内存中(速度:内存>磁盘)
   即,存到内存中的文件,默认放到了项目的根目录中,而且是虚拟的、不可见的
   如何访问生成到内存中的文件? 可以直接用 / 表示项目根目录,后面跟上要访问的文件名称,即可访问内存中的文件
    解决方法:index.html中应该这样引入js   <script src="/bundle.js"></script>

(3)html-webpack-plugin(HTML插件 )

作用:自动把生成好的 bundle.js 注入到 HTML 页面中;

在webpack.config.js中配置该插件:

const HtmlPlugin = require('html-webpack-plugin');
const htmlPlugin = new HtmlPlugin({
  template: join(__dirname, 'public', 'index.html'), // public中,你的html叫什么
  filename: 'index.html' // 打包后的html叫什么(这个文件会生成到dist文件夹)
});

module.exports = {
  mode: 'development',
  // 该插件配置(和其他项并列同级)
  plugins: [ cleanPlugin, htmlPlugin ]
             第一个插件的配置,两个之间用逗号隔开
}

5、loader

处理非js文件或高级js文件

15:03

(1)打包处理 css 文件

a)需要安装包 style-loader@3.3.0 和 css-loader@6.4.0 (前面已经统一安装过)

b)在 webpack.config.js 的 module -> rules 数组中,添加 loader 规则如下:

module.exports = {
  mode: 'development',
  // 其他项省略......
  module: {
    rules: [
      // 处理css文件
      { test: /\.css$/, use: ['style-loader', 'css-loader'] },
    ]
  }
}

注意:

  •  test 表示匹配的文件类型, use 表示对应要调用的 loader;
  • use 数组中指定的 loader 顺序是固定的;
  • 多个 loader 的调用顺序是:从后往前调用;

(2)打包处理 less 文件

(3)打包处理与 url 路径相关的文件

base64 也可表示图片

和源图片的区别

小图片适合用base64格式(头像,logo)

(4)打包处理 js 文件中的高级语法

bable  降级语法   5:22

@bable  前缀

内存关机存在?

6、打包

5:37

7、

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值