修改软件安装的路径:
此电脑右击 → 属性 → 高级系统设置 → 环境变量 → 选中path → 编辑 → 修改路径 → 确定
定义区别:
一、浏览器中的JS
1、浏览器中的JS组成
JS核心语法(ECMAScript) 和 WebAPI(浏览器内置的API)
2、为什么JavaScript 可以在浏览器中被执行?
代码通过 浏览器内核中的 CSS引擎和JS解析引擎 转换成最终的效果;
因为不同的浏览器有不同的解析引擎,所以最终效果都不一样;
3、JS运行环境
运行环境是指代码能正常运行所需的必要条件;
JS运行环境 | 组成 |
---|---|
ECMAScript + 浏览器 | 浏览器 = 内置API+解析引擎+控制台+显示界面 |
ECMAScript + Node.js | Node.js = 内置模块 + 内置API |
区别:
- Node.js后端语言;
-
浏览器是 JavaScript 的前端运行环境。(浏览器是客户端安装的软件);
-
Node.js 是 JavaScript 的后端运行环境。(正常情况下,Nodejs要安装到服务器上);
二、Node.js基础
官网:Node.js
学习文档:API 文档 | Node.js 中文网
1、Node.js的用处
Node.js是
一个基于 Chrome V8 引擎的JavaScript运行环境。
- 基于 Express/Koa 框架(Express - 基于 Node.js 平台的 web 应用开发框架 - Express 中文文档 | Express 中文网),可以快速构建 Web 应用(网站);
- 基于 Electron 框架(Electron | Build cross-platform desktop apps with JavaScript, HTML, and CSS.),可以构建跨平台的桌面应用(软件,如,VScode);
- 基于 restify 框架(Restify),可以快速构建 API 接口项目;
- 读写和操作数据库、创建实用的命令行工具辅助前端开发;
2、终端窗口
终端窗口:可以执行命令的窗口;(git的 “Git Bash Here” 窗口也属于终端窗口)
系统内置终端窗口 | 打开方法 |
---|---|
cmd | (最优) 在JS文件夹地址栏的位置,输入cmd,回车 |
window+R → 输入'cmd' → 回车 | |
powershell | 在JS文件夹空白处shift+右击 → 选择"在此处打开 PowerShell 窗口" |
VScode中的终端窗口 | ctrl+~ (用的还是系统的终端) |
美化终端窗口教程 | 网址 |
---|---|
Windows | oh-my-posh: windows终端配置 |
Mac | ohmyzsh: 打不开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(功能模块),也叫做核心模块。
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 |
HTTPS | HTTPS 是身披 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)客户端请求服务器的步骤
-
先通过IP地址找到服务器
-
检测浏览器缓存有没有缓存该域名对应的IP地址。有则通过IP地址去找服务器
-
检测本地的hosts文件,是否有记录该域名对应的IP地址,有则通过IP地址去找服务器
-
如果是域名,要通过DNS服务器解析,找到该域名对应的IP地址,然后通过IP地址去找服务器
-
-
进行三次握手(确保双方发送和接收数据的能力,建立连接)
-
第一次握手是在建立连接,客户端发送连接请求报文段,把标有SYN的数据包发给服务器端即为接收端。
-
第二次握手是服务器端即接收端收到客户端的SYN的报文段,同时发送标有SYN/ACK的数据包。
-
第三次握手是客户端收到服务器端的SYN/ACK的数据包后,向服务器端发送标有ACK的数据包。
-
-
发送请求,传输数据。。。
-
服务器处理,并做出响应
-
浏览器接收响应结果。
-
四次挥手(作用是断开连接)
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)
(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、