npm

npm

npm

npm官网

官方英文文档

中文文档

包:node.js 中的第三方模块

由第三方个人或团队开发的开源代码集

包类型:

  • 项目包
    • 开发依赖包 被记录到devDependencies节点的包,仅开发中使用
    • 核心依赖包 被记录到dependencies节点的包,开发发布后均使用
  • 全局包

命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
npm -v
查看npm版本


npm help
查看npm帮助


npm init
初始化包环境
创建package.json包配置文件
* -yes -y 使用默认设置初始化包环境


npm install <package_name>
npm i <package_name>
下载npm包
在当前目录中创建node_modules目录(如果尚不存在)并将包下载到该目录
同时在该目录下添加package-lock.json文件,记录下载的包的信息,如包的版本号、下载url等
<package_name>@<tag> <package_name>@<edition> 方式下载指定版本和标签的包
未指定package_name参数时会根据package.json的dependencies属性下载包
* -global -g 全局安装包
* --save-dev -D 把包配置到devDependencies内


npm list
npm ls
列出所有已安装的包
* -global -g 显示全局安装的包
* -all -a 显示所有包及其所有的依赖项
* -depth=<number> 显示包及其给定深度的依赖项

npm uninstall <package_name>
卸载npm包
* --save 从package-lock.json文件dependencies属性中移除包
* --save-dev 从package-lock.json文件devDependencies属性中移除包
* -g 删除全局包

npm update
npm update -g
npm update -g <package_name>
升级npm包

npm outdated
npm outdated -g --depth=0
检测npm包是否为最新

包管理配置文件:package.json项目根目录

项目名称、版本号、描述等‘

项目中使用的包:区分仅开发使用与开发及部署均使用

安装的包会自动更新至package.json文件

  • name 项目名称:字符串

  • version 项目版本号:字符串

  • description 包内容描述:字符串

  • keywords 项目的关键词:字符串数组

  • homePage 项目主页:字符串

  • bugs 项目报告错误的网址:字符串数组

  • license 项目的许可证:字符串

  • author 作者:字符串 可使用name、email、url替代

  • contributors 贡献者:字符串数组

  • funding 贡献方式:字符串or字符串数组or对象(type & url)

  • files 包作为依赖项需包含的条目

  • main 标记包的根目录模块

  • browser 同上,特别指明为浏览器环境

  • bin 命令名称到本地文件的映射|

  • man 指定为man程序查找的文件名|

  • directories 指定包结构|

  • repository 指定代码所在位置,常为各种git仓库

  • scripts 指定在包生命周期运行的代码|

  • config 设置持续使用配置参数

  • dependencies 项目开发与发布均使用的包

  • devDependencies 项目开发内使用的包

  • peerDependencies 项目使用的插件|

  • peerDependenciesMeta 标记插件是否为必需|

  • bundledDependencies/bundleDependencies 发布包时将捆绑的包名称|

  • optionalDependencies 可以使用依赖项|

  • overrides 规定依赖项版本|

  • engines 规定适用的node版本

  • os 规定使用的操作系统版本

  • cpu 规定适用的cpu版本

  • private 规定能否发布私有存储库

  • publishConfig 规定发布配置

  • workspaces 描述用作工作空间的文件夹的直接路径

版本号:

  • 第一位数字:大版本
  • 第二位数字:功能版本
  • 第三位数字:bug修复版本

其他:

将node_modules文件夹添加到.gitignore文件内,以使git上传时剔除npm包

node

node

Node

Node 简介

基于 Chrome V8 引擎的 JavaScript 运行环境

  • Node 与 浏览器均存在互不拥有的 API
  • Node.js 中你可以控制环境即控制运行时的 JS 版本
  • Node.js 使用 CommonJS 模块系统,浏览器使用 ES Modules 标准

Node 内置 API

process 核心进程
fs
path
http

Node 第三方框架

express 构建 Web 应用
electron 构建桌面应用
restify 构建 API 接口项目
读写数据库
实用命令行工具

Node 简单命令

node -v 查看 Node 版本号

node -h 查看 Node 的命令帮助

node <filename|filepath> 执行给定文件名或路径的 js 文件

node 进入 node 交互运行模式

终端快捷键
↑ 自动定位至上一条命令
TAB 自动补全路径
ESC 快速清空当前输入命令
cls 清空终端

process 模块

node 内置模块
隐式导入

process.exit(<exitCode>) 关闭正在执行的 node 进程

process.exitCode 规定 node 进程的退出码

process.env 读取 node 进程启动时设置的所有环境变量

fs 模块

node 内置模块

fs.open(<filepath>, <open-mode>, (<err>, <fd>) => {}) 获取文件描述符(?)

fs.readFile(<filepath>, (<err>, <stats>) => {}) 读取文件属性

stats.isFile()stats.isDirectory() 判断文件是否目录或文件
stats.size 获取文件的大小

fs.readFile(<filepath>, [options], (<err>, <data>) => {}) 读取文件内容

会将文件的全部内容读取至内存中,对于大文件使用流更好

fs.writeFile(<filepath>, data,[options], (<err>) => {}) 写文件内容

仅在将全部内容写入文件才会结束执行,对于数据量较大的使用流更好

以上函数均有sync后缀的同步版本函数

在读取文件时,存在相对路径 ./ ../,运行时可能会存在问题,一般推荐使用 path 模块动态拼接文件完整路径(如 __dirname + '/<filename>')或使用绝对路径

__dirname 脚本文件当前的目录路径
D:\程序\前端学习new\Node-eg
__filename 脚本文件当前的绝对路径
D:\程序\前端学习new\Node-eg\index.js

path 模块

node 内置模块

path.join([...paths]) 将多个路径片段拼接为完整的路径字符串

path.basename(<filepath>) 获取文件名部分
path.basename(<filepath>, path.extname(<filepath>)) 获取文件名不含扩展名部分

path.dirname(<filepath>) 获取文件的父文件夹部分

path.extname(<filepath>) 获取文件扩展名部分

path.resolve() 获得相对路径的绝对路径计算
可以在第一个参数的基础上指定路径,以使第二个参数附加第一个参数

需要注意的是,path模块方法仅做单纯的计算而不会主动判断路径的存在与否

http 模块

node 内置模块

基于js语言创建本地服务器

  • IP 地址
    ip 地址是互联网上各计算机的唯一地址
    192.169.1.1
    有 ipv4 与 ipv6
  • 域名
    使用字符串对域名进行唯一的标识
  • 域名服务器
    负责解析域名并转换为IP地址
  • 端口
    区分服务器上不同的服务
    一个服务器只能对应单个服务
    默认端口是80端口

http.createServer() 创建 http 服务器对象

Serve.prototype.on() 规定监听http请求的回调函数

Serve.prototype.listen() 启动 HTTP 服务器并监听http请求

实现基于url的响应
1 获取url地址
2 设置默认返回内容
3 处理数据并返回

express 库

基于 node 的 web 开发框架

快速创建 API 接口服务器与 Web 网站服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 导入
const express = require('express');

// 创建服务器
const app = express();

// 启动服务器
app.listen(8000, () => {
console.log('express server running at http://127.0.0.1:8000');
});

// 监听请求
// req 请求对象
// res 响应对象
app.get('/:id/user', (req, res) => {

// 获取查询参数 `req.query`

// 获取动态参数{如 /:id/} `req.params`

// 发送请求内容 `res.send()`
res.send('get!!!');

});

// 托管静态资源|注册全局中间件
// 外部 http://localhost:8000/0.css
// 内部 /public/0.css
// 托管多个静态资源目录,只需多次调用 express.static() 方法
app.use(express.static('public'));
// 挂载路径前缀
// 外部 http://localhost:8000/static/0.css
// 内部 /public/0.css
app.use('/static/', express.static('public'));

nodemon

监听本地项目文件变动并自动重启项目(类似前端 live server 的作用)

直接使用 nodemon file 指令执行项目

express 路由

一种映射关系,express中指的是客户端的请求与服务器处理函数之间的映射关系
app.METHOD(PATH, HANDLER)

路由模块化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// router.js
const express = require('express');

const router = express.Router();

router.get('/', (req, res) => {});
router.post('/', (req, res) => {});

module.exports = router;

// main.js
...
const router = require('./router.js');
app.use(router);

express 中间件

请求过程中可以调用中间件对请求进行多次预处理

实质是一个 function

next 函数实现多个中间件连续调用,表示启用下一个中间件

1
2
3
4
5
6
7
8
9
// 全局注册中间件
app.use((req, res, next) => {
console.log('mid');
next();
});
// 同时注册多个中间件只需多次调用app.use即可

// 局部注册中间件
app.post('/', (req, res, next) => {}, (req, res) => {});

需在路由之前注册中间件
可以对请求调用多个中间件进行处理
注意执行完中间件代码,需调用next方法
调用next方法后不应执行其他的任何的代码
连续多个中间件之间共享req与res对象

CORS

使用 cors 包

1
2
3
const cors = require('cors');

app.use(cors());

只需服务器做配置,客户端无需做额外的配置

响应头部带 Access-Control-Allow-Origin 字段,表示允许来源的域的名称
Access-Control-Allow-Headers 声明允许的请求头字段,Accept Accept-Language Content-Language DPR Downlink Save-Data Viewport-Width Width Content-Type
Access-Control-Allow-Methods 声明允许的请求方法,默认GET POST HEAD可,其他均需声明

  • 简单请求
    请求方式与请求头部字段有限

  • 预检请求(预先发送OPTION请求确定是否可请求,仅成功后才会发送实际请求)
    其他

mysql.js

在 node 中访问 MySQL 数据库的 js 库

Web 开发模式

  1. 基于服务端渲染的传统 Web 开发模式
    页面由服务器动态生成
    前端耗时少
    利于SEO
    占用服务器端资源
    不利于前后端分离开发效率低
  2. 基于前后端分离的新型 Web 开发模式
    依赖于 Ajax 技术,即前端使用接口,后端提供接口
    开发体验好
    用户体验好
    减轻服务器端渲染压力
    不利于SEO

身份认证

出于安全性考虑,需要对用户身份进行认证

(服务器渲染)Session 认证机制
(前后端分离)JWT 认证机制

Session 认证机制

  • HTTP 协议的无状态性

HTTP 请求独立,服务器无法主动保留每次 HTTP 请求的状态

  • 突破无状态性

使用 Cookie

  • Cookie

一段存储在用户浏览器中的字符串
可以存储一些特有信息
由名称、值及一些可选属性(有效期、安全性、使用范围等)构成
不同域名下Cookie相互独立
每次客户端请求均会自动发送当前域名下所有未过期的Cookie

1
2
3
4
<!-- 设置cookie -->
Set-Cookie: token=1dw21qde43s;
<!-- 发送cookie -->
Cookie: token=1dw21qde43s;

客户端登录,服务器生成对应的cookie发回客户端保存;之后客户端每次请求均将带cookie,服务器需验证通过后再进行操作返回响应内容

webpack

webpack

前端工程化

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

标准化企业级项目开发过程:工具、技术、流程、经验

grunt gulp => webpack(主) parcel => vite

webpack

前端项目工程化

  • 代码压缩混淆
  • 处理JavaScript兼容性
  • 性能优化

安装webpack

npm i webpack webpack-cli -D

配置webpack

在webpack.config.js文件内
保存webpack的打包设定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 导入 path 包
const path = require('path');

module.exports = {
/**
* mode 标记构建模式
* development 开发模式 不会代码压缩或性能优化 打包速度快
* production 发布模式 会代码压缩与性能优化 打包速度慢
* none 无模式
*/
mode: 'development',
/**
* entry 输入文件路径,开始打包的文件路径
*
* __dirname:当前文件绝对路径
*/
entry: path.join(__dirname, './src/index.js'),
/**
* output 输出设定
*/
output: {
/**
* path 输出文件路径
*/
path: path.join(__dirname, './dist'),
/**
* filename 输出文件名称
*/
filename: 'main.js',
},
}

在package.json文件内

1
2
3
"scripts": {
"dev": "webpack"
}

使用webpack

npm run dev


webpack-dev-server

实时更新修改文件,从而能够随时观察编辑效果
实际搭建一个本地服务器,把实时改变的文件放在内存内,以加快访问速度

  1. 安装 npm i webpack-dev-server -D

  2. 修改 package.json 文件如下:

    1
    2
    3
    "scripts": {
    "dev": "webpack serve"
    }
  3. 可通过 npm run dev 编译

  4. 访问 https://localhost:8080

配置 webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
devServer: {
/**
* 初次打包完成后自动打开浏览器
*/
open: true,
/**
* 指定host名
*/
// host: '127.0.0.1',
/**
* 指定端口
*/
// port: 8080,
},
}

html-webpack-plugin

编译时实时移动 html 文件至项目根目录
自动注入项目打包后的 js 文件和其他文件

  1. 安装 npm i html-webpack-plugin -D
  2. 配置 webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
// 导入 HtmlPlugin 包
const HtmlPlugin = require('html-webpack-plugin');

// 添加 plugins 设置
{
plugins: [
new HtmlPlugin({
template: './src/index.html',
filename: './index.html',
}),
],
}

loader

由于 webpack 仅可处理 js 及 json 文件
加载器:协助 webpack 处理特定的文件模块

  • css-loader 处理 css 文件
  • less-loader 处理 less 文件
  • babel-loader 处理高级 js 语法

CSS-loader

协助处理 css 文件

  1. 安装 npm i style-loader css-loader -D

  2. 配置 webpack.config.js 内的 module 选项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    {
    // 第三方模块的匹配规则
    module: {
    // 规则数组
    rules: [
    {
    // 正则表达式匹配的文件类型
    test: /\.css$/,
    // 使用的 loader
    // 特别的: loader 中的顺序不可交换,会按从后往前的顺序调用
    use: [
    'style-loader',
    'css-loader',
    ],
    }
    ],
    },
    }
  3. 在 index.js 中导入 css 文件
    import './css/index.css';

less-loader

协助处理 less 文件

  1. 安装 npm i less less-loader -D

  2. 配置 webpack.config.js 内的 module 选项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    module: {
    rules: [
    {
    test: /\.less$/,
    use: [
    'style-loader',
    'css-loader',
    'less-loader',
    ],
    },
    ],
    },
    }
  3. 在 index.js 中导入 less 文件
    import './css/index.less';

url-loader&file-loader

协助处理图片
会把给定限制大小下的图片转为base64编码,否则仍使用url导入的方式

  1. 安装 npm i url-loader file-loader -D

  2. 配置 webpack.config.js 内的 module 选项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {
    module: {
    rules: [
    {
    test: /\.jpg|png|gif$/,
    // limit 指定转换图片的阈值
    use: 'url-loader?limit=8192',
    },
    ],
    },
    }
  3. 在 index.js 中导入图片
    import logo from './images/icon.png';

  4. 给img标签赋值
    $('#img').attr('src', logo);

babel-loader

  1. 安装 npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D

  2. 配置 webpack.config.js 内的 module 选项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    {
    module: {
    rules: [
    {
    test: /\.js$/,
    use: 'babel-loader',
    exclude: /node_modules/,
    },
    ],
    },
    }
  3. 配置 babel.config.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    module.exports = {
    plugins: [
    [
    '@babel/plugin-proposal-decorators',
    {
    legacy: true,
    },
    ],
    ],
    }

打包发布

package.json 配置

1
2
3
4
"scripts": {
// --mode production 指定发布时模式为 production
"build": "webpack --mode production"
}

优化js路径

1
2
3
4
output: {
path: path.join(__dirname, './dist'),
filename: 'js/main.js',
}

优化img路径

1
2
3
4
5
6
7
8
9
10
{
test: /\.jpg|png|gif$/,
use: {
loader: 'url-loader',
options: {
limit: 10240,
outputPath: 'images',
},
},
},

配置清理 dist 目录 clean-webpack-plugin

  1. 安装 npm i clean-webpack-plugin -D

  2. 导入与配置 webpack.config.js

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

    1
    2
    3
    4
    5
    6
    7
    plugins: [
    new HtmlPlugin({
    template: './src/index.html',
    filename: './index.html',
    }),
    new CleanWebpackPlugin(),
    ],

Source Map

信息文件,保存打包前代码的详细位置信息

webpack.config.js 添加 devTools: 'eval-source-map' 选项

建议发布时去除 source map 选项

只定位行号,不暴露源码:nosources-source-map 设定
定位行号且暴露源码:source-map 会生成一个独立文件

使用@导入文件

  • 配置
1
2
3
4
5
resolve: {
alias: {
'@': path.join(__dirname, './src/'),
},
},
  • 使用
    import msg from '@/msg.js';
git

git

git

版本控制

版本控制软件

操作简便|易于对比|易于回溯|不易丢失|协作方便

本地版本控制系统->集中化版本控制系统->分布式版本控制系统

git

快照:在原有文件基础上重新生成一个文件,类似于备份

操作:本地执行,云端同步

git 文件状态

  • 未跟踪(untracked)未被 git 管理

  • 未修改(unmodified)工作区文件内容与 git 仓库内文件相同

  • 已修改(modified)表示修改了文件,但还没保存到 git 本地仓库中,自上次检出后,作了修改但还没有放到暂存区域

  • 已暂存(staged)表示对一个已修改文件的当前版本做了标记以使之包含在下次提交的快照中,文件已修改并放入暂存区

  • 已提交(committed)表示数据已经安全地保存在 git 仓库中,Git 目录中保存着特定版本的文件

git 项目阶段

  • 工作区是对项目的某个版本独立提取出来的内容,供用户修改与使用

  • 暂存区是一个文件,保存了下次将要提交的文件列表信息

  • Git 仓库目录是 Git 用来保存项目的元数据和对象数据库的地方

git 全局配置

文件路径 C:/Users/用户名文件夹/.gitconfig 文件

查看所有全局配置项 git config --list --global

git 帮助

git help <verb>

git 初始化仓库

  • 将尚未进行版本控制的本地目录转换为 Git 仓库

git init

  • 从其它服务器克隆一个已存在的 Git 仓库

git clone <url> [<storagename>]

  • 允许 https 协议等,以及 git 协议与 SSH 协议

git 文件操作

git status 检测文件所处状态

  • git status -s

  • git status –short

标记 A 表示新建的文件

标记 M 表示修改的文件

标记?? 表示未修改的文件

git diff 显示尚未暂存的改动

git add <filename> 开始跟踪新文件&将已跟踪新文件放至暂存区

git commit [-m "message"] 从暂存区提交更新至 git 仓库

git commit -a [-m "message"] 一次性将跟踪的文件暂存并提交

git checkout -- <filename> 撤销对文件的修改:将对应工作区文件修改还原成 git 仓库中保存的版本

git reset HEAD <filename> 从暂存区移除文件

git rm {-f|--cached} <filename> -f 从仓库与工作区移除文件:–cached 仅从仓库移除文件,但保留工作区文件

git mv <filefrom> <fileto> 移动文件或重命名文件

git 忽略文件

创建 .gitignore 的文件列出要忽略的文件的模式

  • 所有空行或者以 # 开头的行都会被 Git 忽略
  • 可以使用标准的 glob 模式匹配,它会递归地应用在整个工作区中
  • 匹配模式可以以(/)开头防止递归
  • 匹配模式可以以(/)结尾指定目录
  • 要忽略指定模式以外的文件或目录,可以在模式前加上叹号(!)取反
    • glob 模式是指 shell 所使用的简化了的正则表达式
    • 星号(*)匹配零个或多个任意字符
    • [abc] 匹配任何一个列在方括号中的字符 (这个例子要么匹配一个 a,要么匹配一个 b,要么匹配一个 c)
    • 问号(?)只匹配一个任意字符;如果在方括号中使用短划线分隔两个字符, 表示所有在这两个字符范围内的都可以匹配(比如 [0-9] 表示匹配所有 0 到 9 的数字)
    • 使用两个星号(**)表示匹配任意中间目录,比如 a/**/z 可以匹配 a/za/b/za/b/c/z
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 忽略所有的 .a 文件
*.a

# 但跟踪所有的 lib.a,即便你在前面忽略了 .a 文件
!lib.a

# 只忽略当前目录下的 TODO 文件,而不忽略 subdir/TODO
/TODO

# 忽略任何目录下名为 build 的文件夹
build/

# 忽略 doc/notes.txt,但不忽略 doc/server/arch.txt
doc/*.txt

# 忽略 doc/ 目录及其所有子目录下的 .pdf 文件
doc/**/*.pdf

参考链接

git 查看文件历史

git log

-<number> 显示指定的提交历史

按 q 退出

开源

开源:open source code

开源许可协议:open source license

​ GPL MIT 等

开源项目托管平台:github、gitlab、gitee

远程仓库访问方式

  • HTTPS 无需配置,每次需输入账号密码

git remote add <本地版本库> <远程仓库url> git remote add origin gitutl-https
git push <远程主机名> <本地分支名>:<远程分支名> git push origin master

  • SSH 需额外配置,每次无需输入账号密码

SSH key

  • 个人私钥
  • git 服务器公钥

分支

查看、创建、切换、合并、删除、跟踪、拉取

主分支 master
实际用于保存及记录整个项目已完成及审计的代码

功能分支:专门用于开发新功能的分支

查看分支

git branch

分支前的 * 代表当前分支

创建分支

git branch <branch-name>

相较于当前分支创建分支

创建分支时不改变原所在分支

切换分支

git checkout <new-branch-name>

快速创建切换分支

git checkout -b <new-branch-name>

合并分支

git merge <branch-name>

将指定分支合并到当前分支

若两分支存在分歧,需要主动处理冲突

删除分支

git branch -d <branch-name>

git branch -D <branch-name> 强制删除

推送分支至远程仓库

git push -u <remote-repository> <local-branch>:<remote-branch> 第一次

之后直接 git push 即可

查看远程仓库分支列表

git remote show <remote-repository>

跟踪[远程仓库]分支

git checkout <remote-branch>

git checkout <local-branch> <remote-repository>/<remote-branch> 同时重命名本地分支

拉取[远程仓库最新]分支

git pull 相较于当前分支

删除[远程仓库]分支

git push <remote-repository> --delete <remote-branch>


:D 一言句子获取中...