diff --git a/authors/coderwhy/index.html b/authors/coderwhy/index.html index c8fc41b..c2ba233 100644 --- a/authors/coderwhy/index.html +++ b/authors/coderwhy/index.html @@ -8,8 +8,8 @@ - coderWhy · Moqizhongyuan的个人网站 - + coderwhy · Moqizhongyuan的个人网站 + @@ -64,14 +64,14 @@ - + - + @@ -473,7 +473,7 @@
-

coderWhy

+

coderwhy

diff --git a/authors/coderwhy/index.xml b/authors/coderwhy/index.xml index 3f90de3..781886d 100644 --- a/authors/coderwhy/index.xml +++ b/authors/coderwhy/index.xml @@ -1,9 +1,9 @@ - coderWhy on Moqizhongyuan的个人网站 + coderwhy on Moqizhongyuan的个人网站 /authors/coderwhy/ - Recent content in coderWhy on Moqizhongyuan的个人网站 + Recent content in coderwhy on Moqizhongyuan的个人网站 Hugo -- gohugo.io zh-cn © 2024 Moqizhongyuan diff --git a/authors/index.html b/authors/index.html index a3ba048..e470cba 100644 --- a/authors/index.html +++ b/authors/index.html @@ -524,7 +524,7 @@

coderWhycoderwhy · diff --git a/authors/index.xml b/authors/index.xml index 69aa138..579f4dc 100644 --- a/authors/index.xml +++ b/authors/index.xml @@ -9,7 +9,7 @@ © 2024 Moqizhongyuan Tue, 04 Jun 2024 00:00:00 +0000 - coderWhy + coderwhy /authors/coderwhy/ Tue, 04 Jun 2024 00:00:00 +0000 diff --git a/index.json b/index.json index 11a8b8c..9852546 100644 --- a/index.json +++ b/index.json @@ -1,2 +1,2 @@ -[{"content":"","date":"2024/06/04","externalUrl":null,"permalink":"/posts/","section":"","summary":"","title":"","type":"posts"},{"content":"","date":"2024/06/04","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"An all-round web worker\n","date":"2024/06/04","externalUrl":null,"permalink":"/authors/coderwhy/","section":"Authors","summary":"An all-round web worker","title":"coderWhy","type":"authors"},{"content":"欢迎来到我的网站!我很高兴你的来访。\n","date":"2024/06/04","externalUrl":null,"permalink":"/","section":"欢迎来到 Blowfish !","summary":"欢迎来到我的网站!我很高兴你的来访。","title":"欢迎来到 Blowfish !","type":"page"},{"content":" 项目打包和自动化部署 # 一. 项目部署和 DevOps # 1.1. 传统的开发模式 # 在传统的开发模式中,开发的整个过程是按部就班就行:\n但是这种模式存在很大的弊端:\n工作的不协调:开发人员在开发阶段,测试和运维人员其实是处于等待的状态。等到测试阶段,开发人员等待测试反馈 bug,也会处于等待状态。 线上 bug 的隐患:项目准备交付时,突然出现了 bug,所有人员需要加班、等待问题的处理; 1.2. DevOps 开发模式 # DevOps 是 Development 和 Operations 两个词的结合,将开发和运维结合起来的模式:\n1.3. 持续集成和持续交付 # 伴随着 DevOps 一起出现的两个词就是持续集成和持续交付(部署):\nCI 是 Continuous Integration(持续集成); CD 是两种翻译:Continuous Delivery(持续交付)或 Continuous Deployment(持续部署); 持续集成 CI:\n持续交付和持续部署:\n1.4. 自动化部署流程 # 二. 购买云服务器 # 2.1. 注册阿里云的账号 # 云服务器我们可以有很多的选择:阿里云、腾讯云、华为云。\n目前在公司使用比较多的是阿里云; 我自己之前也一直使用阿里云,也在使用腾讯云; 之前华为云也有找我帮忙推广他们的活动; 但是在我们的课程中,我选择目前使用更加广泛的阿里云来讲解:\n我们需要注册阿里云账号\nhttps://aliyun.com/\n注册即可,非常简单\n2.2. 购买云服务器 # 购买云服务器其实是购买一个实例。\n来到控制台: 创建实例,选择类型和配置 配置网络安全组 设置登录密码 三. 搭建服务器环境 # 3.1. jenkins 自动化部署 # 3.1.1. 安装 Java 环境 # Jenkins 本身是依赖 Java 的,所以我们需要先安装 Java 环境:\n这里我安装了 Java1.8 的环境 dnf search java-1.8 dnf install java-1.8.0-openjdk.x86_64 3.1.2. 安装 Jenkins # 因为 Jenkins 本身是没有在 dnf 的软件仓库包中的,所以我们需要连接 Jenkins 仓库:\nwget 是 Linux 中下载文件的一个工具,-O 表示输出到某个文件夹并且命名为什么文件; rpm:全称为The RPM Package Manage,是 Linux 下一个软件包管理器; wget –O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo # 导入GPG密钥以确保您的软件合法 rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key # 或者 rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key 编辑一下文件/etc/yum.repos.d/jenkins.repo\n可以通过 vim 编辑 [jenkins]\rname=Jenkins-stable\rbaseurl=http://pkg.jenkins.io/redhat\rgpgcheck=1 安装 Jenkins\ndnf install jenkins # --nogpgcheck(可以不加) 启动 Jenkins 的服务:\nsystemctl start jenkins systemctl status jenkins systemctl enable jenkins Jenkins 默认使用 8080 端口提供服务,所以需要加入到安全组中:\n3.1.3. Jenkins 用户 # 我们后面会访问 centos 中的某些文件夹,默认 Jenkins 使用的用户是 jenkins,可能会没有访问权限,所以我们需要修改一下它的用户:\n修改文件的路径:/etc/sysconfig/jenkins\n之后需要重启一下 Jenkins:\n# 也可以将Jenkins添加到root组中 sudo usermod -a -G root jenkins systemctl restart jenkins 3.1.4. Jenkins 配置 # 打开浏览器,输入:http://8.134.60.235:8080/\n注意:你输入自己的 IP 地址 获取输入管理员密码:\n在下面的地址中 cat /var/lib/jenkins/secrets/initialAdminPassword ![image-20201203173047824](/Users/coderwhy/Library/Application Support/typora-user-images/image-20201203173047824.png)\n可以安装推荐的插件:\n3.1.5. Jenkins 任务 # 新建任务:\n配置项目和保留策略:\n源码管理:\n构建触发器:\n这里的触发器规则是这样的:\n定时字符串从左往右分别是:分 时 日 月 周 #每半小时构建一次OR每半小时检查一次远程代码分支,有更新则构建 H/30 * * * * #每两小时构建一次OR每两小时检查一次远程代码分支,有更新则构建 H H/2 * * * #每天凌晨两点定时构建 H 2 * * * #每月15号执行构建 H H 15 * * #工作日,上午9点整执行 H 9 * * 1-5 #每周1,3,5,从8:30开始,截止19:30,每4小时30分构建一次 H/30 8-20/4 * * 1,3,5 构建环境:\n注意:我们需要搭建 Node 的环境\n第一步:配置 Node 的环境; 第二步:安装 Node 的插件; 第一步:配置 Node 的环境\n第二步:安装 Node 的插件\n这里因为我已经安装过了,所以没有搜索到; 构建执行的任务:\n查看 Node 的版本等是否有问题; 执行 npm install 安装项目的依赖; 移除原来 mall_cms 文件的所有内容; 将打包的 dist 文件夹内容移动到 mall_cms 文件夹; pwd node -v npm -v npm install npm run build pwd echo \u0026#39;构建成功\u0026#39; ls # 删除/root/mall_cms文件夹里所有的内容 rm -rf /root/mall_cms/* cp -rf ./dist/* /root/mall_cms/ 3.2. nginx 安装和配置 # 3.2.1. 安装 nginx # 后续我们部署会使用 nginx,所以需要先安装一下 nginx:\ndnf install nginx 启动 nginx:\nsystemctl start nginx systemctl status nginx systemctl enable nginx 3.2.2. 配置 nginx # 我们这里主要配置 nginx 的用户和默认访问目录:\n/etc/nginx/nginx.conf 配置用户:\n通过 Linux 命令创建文件夹和文件:\nmkdir /root/mall_cms cd /root/mall_cms touch index.html vi index.html 配置访问目录:\n","date":"2024/06/04","externalUrl":null,"permalink":"/posts/%E9%A1%B9%E7%9B%AE%E6%89%93%E5%8C%85%E5%92%8C%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/","section":"","summary":"项目打包和自动化部署 # 一.","title":"项目打包和自动化部署","type":"posts"},{"content":" 引言 # 在项目中直接使用Axios或其他第三方库来发送网络请求获取数据时,会导致代码与网络请求的逻辑耦合度过高,导致难以维护。 本文将讲解如何将网路请求的代码进行封装来进行解耦操作 理解耦合度 # 代码耦合分为两种,直接依赖的结构耦合和间接依赖的内容耦合,这两种耦合都会导致可维护性下降、可测试性下降、可复用性下降、可扩展性下降。 这里在项目中直接使用Axios发送网络请求就是结构耦合,如果Axios的第三方库发生更新或者废弃,会导致我们的项目非常难以维护,这时将Axios封装到一个类中,就可以降低这种直接依赖带来的影响 Axios 概述 # Axios 是一个流行的用于发起 HTTP 请求的 JavaScript 库。它提供了一种简洁、灵活且易于使用的方式来处理网络请求,并且可以在浏览器和 Node.js 环境中使用。\n以下是 Axios 的一些主要功能:\n支持多种请求方式:Axios 支持常见的 HTTP 请求方法,如 GET、POST、PUT、DELETE 等,可以满足不同类型的请求需求。\n拦截器支持:Axios 提供了拦截器(Interceptors)功能,可以在请求发送或响应返回之前对它们进行拦截和处理。这使得可以在请求和响应的不同阶段添加全局的处理逻辑,例如认证、错误处理、请求/响应转换等。\nPromise API:Axios 基于 Promise 提供了一致的 API,可以使用链式调用来处理请求和响应。这使得可以更容易地处理异步操作,并使用 Promise 的特性,如 .then()、.catch()、.finally() 等。\n请求和响应的转换:Axios 允许自定义请求和响应的数据转换逻辑。可以通过拦截器将请求数据格式化为特定格式(如 JSON),或者将响应数据进行解析和转换,以适应项目的需求。\n错误处理:Axios 提供了全面的错误处理机制。它会自动检测和处理 HTTP 错误状态码,并将其包装为可读的错误对象。此外,还可以添加自定义的错误处理逻辑,以便更好地处理错误情况。\n取消请求:Axios 允许取消尚未完成的请求。这对于需要中止或忽略之前发出的请求非常有用,例如在用户取消操作或页面导航时。\nAxios 成为流行的发起 HTTP 请求的工具有以下原因:\n易于使用:Axios 提供了简洁而直观的 API,使得发送和处理 HTTP 请求变得简单和容易上手。\n广泛的应用:Axios 可以在浏览器和 Node.js 环境中使用,使得它在前端和后端开发中都具有广泛的适用性。\n功能丰富:Axios 提供了许多实用的功能,如拦截器、请求和响应的转换、错误处理等,使得开发人员能够更好地控制和处理网络请求。\n活跃的社区支持:Axios 有一个活跃的社区,拥有广泛的用户群体,因此可以获得广泛的支持和资源。这包括文档、示例代码、问题解答等。\n总而言之,Axios 是一个功能强大、易于使用且受欢迎的用于发起 HTTP 请求的工具,它提供了许多便捷的功能和良好的开发体验,使得处理网络请求变得更加简单和高效。\n封装Axios # 在项目目录中创建一个 services 文件夹来封装网络请求的逻辑。 在 services 中创建 modules 文件夹来编写复杂的网络请求逻辑,在 request 中封装Axios逻辑,创建 index 文件作为 services 统一出口。 在 request 中配置 index.js 文件封装一个类来处理网络请求,在 config.js 文件中配置基本选项,例如 BASE_URL、TIMEOUT。 配置 request 中的 index.js 文件 import axios from \u0026#34;axios\u0026#34;; import { BASE_URL, TIMEOUT } from \u0026#34;./config\u0026#34;; class HYRequest { // 创建构造函数 constructor(baseURL, timeout) { // 创建instance实例 this.instance = axios.create({ baseURL, timeout, }); // 配置拦截器,对获取数据进行响应 this.instance.interceptors.response.use( (res) =\u0026gt; { return res.data; }, (err) =\u0026gt; { return err; } ); } // request请求 request(config) { return this.instance.request(config); } // 配置get请求方法 get(config) { return this.request({ ...config, method: \u0026#34;get\u0026#34; }); } // 配置post请求方法 post(config) { return this.request({ ...config, method: \u0026#34;post\u0026#34; }); } } const hyRequest = new HYRequest(BASE_URL, TIMEOUT); export default hyRequest; 这里通过类的内聚性将网络请求的逻辑汇集到一起,用axios.create函数创建instance实例,构造函数接收baseUrl和timeout来配置instance,通过interceptor拦截器拦截response结果,在通过配置request、get、post实现对Axios的调用来完成网络请求,最后用创建好的类来创建一个实例,接收的参数为在config文件中配置好的基本选项,然后导出这个实例即可在项目代码中进行使用。\n配置 request 中的 config 文件 export const BASE_URL = \u0026#34;http://codercba.com:1888/airbnb/api\u0026#34;; export const TIMEOUT = 10000; 这里简单配置request的基本选项来方便我们发送网络请求\n对封装好的 hyRequest 进行导出 import hyRequest from \u0026#34;./request\u0026#34;; export default hyRequest; 这里是services文件夹的统一导出出口,方便进行代码维护\n使用这里封装的类进行网络请求 # import React, { memo, useEffect } from \u0026#34;react\u0026#34;; import hyRequest from \u0026#34;@/services\u0026#34;; const Home = memo(() =\u0026gt; { // 网络请求的代码 useEffect(() =\u0026gt; { hyRequest.get({ url: \u0026#34;/home/highscore\u0026#34; }).then((res) =\u0026gt; { console.log(res); }); }, []); return \u0026lt;div\u0026gt;Home\u0026lt;/div\u0026gt;; }); export default Home; 这里在 home 组件中先进行导入 hyRequest,即可发送网络请求,配置 config 参数,传入{ url: \u0026quot;/home/highscore\u0026quot; }来发送网络请求。\n这便是通过封装好的hyRequest类发送网络请求得到的结果\n总结 # 封装 Axios 的好处:\n降低代码耦合度:通过封装 Axios,可以将网络请求的具体实现细节隐藏在封装的模块或类中,其他模块只需要与封装后的接口进行交互,从而降低了代码的耦合度。 提高可维护性:封装 Axios 可以将网络请求的逻辑集中在一个地方,使得对网络请求的修改和维护更加方便和一致。如果需要更换或升级网络请求库,只需在封装层进行修改,而不需要在整个项目中的各个地方进行修改。 增强可测试性:通过封装 Axios,可以更容易地进行单元测试。由于网络请求的逻辑被封装在一个独立的模块或类中,可以方便地模拟请求和响应,编写针对封装层的单元测试。 提升代码的可复用性:封装 Axios 可以使得网络请求的代码在不同的项目中更易于复用。封装后的模块或类可以被多个模块或项目共享,而不需要重复编写发送网络请求的代码。 结束语 # 通过封装 Axios 来降低项目代码对于 Axios 的直接依赖,即使后面要更换使用网络请求的第三方库,也可以更加方便的修改和维护代码,在编写项目的时候我们也应该多应用这种思路,合理抽取代码逻辑,使代码更容易维护,提高代码复用性。\n","date":"2024/06/03","externalUrl":null,"permalink":"/posts/%E5%B0%81%E8%A3%85axios%E9%99%8D%E4%BD%8E%E4%BB%A3%E7%A0%81%E8%80%A6%E5%90%88%E5%BA%A6/","section":"","summary":"引言 # 在项目中直接使用Axios或其他第三方库来发送网络请求获取数据时,会导致代码与网络请求的逻辑耦合度过高,导致难以维护。 本文将讲解如何将网路请求的代码进行封装来进行解耦操作 理解耦合度 # 代码耦合分为两种,直接依赖的结构耦合和间接依赖的内容耦合,这两种耦合都会导致可维护性下降、可测试性下降、可复用性下降、可扩展性下降。 这里在项目中直接使用Axios发送网络请求就是结构耦合,如果Axios的第三方库发生更新或者废弃,会导致我们的项目非常难以维护,这时将Axios封装到一个类中,就可以降低这种直接依赖带来的影响 Axios 概述 # Axios 是一个流行的用于发起 HTTP 请求的 JavaScript 库。它提供了一种简洁、灵活且易于使用的方式来处理网络请求,并且可以在浏览器和 Node.","title":"关于封装axios网络请求降低代码耦合度","type":"posts"},{"content":" 速通 jQuery # 一、基础概念和选择器 # 1.基本概念及作用,如何简化 js 编程 # 简介的语法:简化 DOM 操作 跨浏览器兼容性 丰富的功能库:DOM 操作、事件处理、动画效果、AJAX 请求 强大的选择器:类似于 CSS 选择器,使开发人员轻松选取 DOM 元素 插件生态系统 社区支持和文档资源 2.jQuery 选择器语法 # 元素选择器 选择所有 p 元素:$(\u0026ldquo;p\u0026rdquo;) 选择所有 div 元素:$(\u0026ldquo;div\u0026rdquo;) 类选择器 选择所有 example 类的元素:$(\u0026quot;.example\u0026quot;) 选择同时具有 class1 和 class2 类的元素:$(\u0026quot;.class1.class2\u0026quot;) ID 选择器 选择具有 myId ID 的元素:$(\u0026quot;#myId\u0026quot;) 属性选择器 选择具有 data-name 属性的元素:$(\u0026quot;[data-name]\u0026quot;) 选择具有 data-cagetory 属性且值为 books 的元素:$(\u0026quot;[data-category=\u0026lsquo;books\u0026rsquo;]\u0026quot;) 子元素选择器: 选择所有 ul 元素下的 li 子元素:$(\u0026ldquo;ul \u0026gt; li\u0026rdquo;) 后代元素选择器: 选择所有 div 元素下的 p 后代元素:$(\u0026ldquo;div p\u0026rdquo;) 兄弟元素选择器: 选择紧接在 h2 元素后的所有 p 元素的兄弟元素:$(\u0026ldquo;h2 + p\u0026rdquo;) 过滤选择器 选择第一个 div 元素:$(\u0026ldquo;div:first\u0026rdquo;) 选择最后一个 p 元素:$(\u0026ldquo;p:last\u0026rdquo;) 选择所有偶数位置的 li 元素:$(\u0026ldquo;li:even\u0026rdquo;) 选择所有包含文本 example 的元素:$(\u0026quot;:contains(\u0026rsquo;example\u0026rsquo;)\u0026quot;) 实践 # 二、DOM 操作和事件处理 # 1.jQuery 常见操作 DOM 元素方法 # 添加元素\nappend():挂载节点末尾(子节点) prepend():挂载节点开头(子节点) after():挂载节点之后(兄弟节点) before():挂载节点之前(兄弟节点) 删除元素\nremove():移除节点 empty():清空节点内容(元素、文本) 移动元素\nappendTo():移动到节点末尾(子节点) prependTo():移动到节点开头(子节点) insertAfter():移动到节点之后(兄弟节点) insertBefore():移动到节点之前(兄弟节点) 替换元素\nreplaceWith():替换节点(文本/元素) 2.jQuery 常见的 DOM 操作方法 # addClass():增加 class removeClass():移除 class toggleClass():切换 class 属性 attr():获取节点属性 removeAttr():移除节点属性 val():获取表单值 text():获取文本节点内容 html():获取节点内容,包括子节点,返回一个字符串 3.jQuery 处理事件的基本概念和用法 # 绑定事件处理 事件委托 解除事件绑定 事件对象 三、动画效果和特效 # 1.动画效果 # 淡入淡出(fadeIn/fadeOut) 滑动效果(slideUp / slideDown) 动态调整样式(animate) 2.与用户交互添加特效和动态效果 # hover() click() scroll() 四、AJAX 和数据交互 # 1.使用 jQuery 来进行 AJAX 请求,从服务器获取数据并更新页面内容 # $.ajax(url, method, dataType, success(), error()) $.get(url, data, function) $.post(url, data, function) 2.实践通过 AJAX 请求获取数据,处理响应并动态更新页面内容 # 五、插件和扩展 # 1.jQuery 插件的概念和用法 # 选择合适的插件 引入 jQuery 和插件 配置和初始化插件 调用插件方法 处理插件回调 样式和定制 2.编写自定义的 jQuery 插件,以便根据自己的需求扩展 jQuery 的功能 # 引入 jQuery 库\n创建插件函数\n$.fn.myPlugin = function(options) {\r// 插件的代码逻辑\r};\r})(jQuery); 处理选项\n$.fn.myPlugin = function(options) {\rvar settings = $.extend({\roption1: defaultValue1,\roption2: defaultValue2\r}, options);\r// 使用 settings.option1 和 settings.option2 处理插件逻辑\r};\r})(jQuery); 遍历元素集合\n$.fn.myPlugin = function(options) {\rvar settings = $.extend({\roption1: defaultValue1,\roption2: defaultValue2\r}, options);\rreturn this.each(function() {\r// 在这里处理每个元素的逻辑,使用 $(this) 引用当前元素\r});\r};\r})(jQuery); 创建插件函数\n(function($) {\r$.fn.myPlugin = function(options) {\rvar settings = $.extend({\roption1: defaultValue1,\roption2: defaultValue2\r}, options);\rreturn this.each(function() {\rvar $element = $(this);\r// 操作元素,绑定事件等等\r$element.text(settings.option1);\r$element.on(\u0026#39;click\u0026#39;, function() {\r// 处理点击事件\r});\r});\r};\r})(jQuery); 使用插件 \u0026lt;script src=\u0026#34;your-plugin.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;\r\u0026lt;script\u0026gt;\r$(document).ready(function() {\r$(\u0026#39;.target-elements\u0026#39;).myPlugin({\roption1: value1,\roption2: value2\r});\r});\r\u0026lt;/script\u0026gt; ","date":"2024/06/03","externalUrl":null,"permalink":"/posts/%E9%80%9F%E9%80%9Ajquery/","section":"","summary":"速通 jQuery # 一、基础概念和选择器 # 1.","title":"速通jQuery","type":"posts"},{"content":" Introduction # This is bold text, and this is emphasized text.\nHello! \u0026#x1f44b;\nVisit the Hugo website!\n","date":"2024/06/01","externalUrl":null,"permalink":"/posts/second-post/","section":"","summary":"Introduction # This is bold text, and this is emphasized text.","title":"My First Post","type":"posts"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/about/","section":"欢迎来到 Blowfish !","summary":"","title":"","type":"page"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/topics/","section":"Topics","summary":"","title":"Topics","type":"topics"},{"content":"本节包含了我所有的当前项目。\n","date":"0001/01/01","externalUrl":null,"permalink":"/projects/","section":"项目","summary":"本节包含了我所有的当前项目。","title":"项目","type":"projects"},{"content":"本节包含了我所有的 React 项目。\n","date":"0001/01/01","externalUrl":null,"permalink":"/projects/reactprojects/","section":"项目","summary":"本节包含了我所有的 React 项目。","title":"项目","type":"projects"},{"content":"本节包含了我所有的 Vue 项目。\n","date":"0001/01/01","externalUrl":null,"permalink":"/projects/vueprojects/","section":"项目","summary":"本节包含了我所有的 Vue 项目。","title":"项目","type":"projects"}] \ No newline at end of file +[{"content":"","date":"2024/06/04","externalUrl":null,"permalink":"/posts/","section":"","summary":"","title":"","type":"posts"},{"content":"","date":"2024/06/04","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"An all-round web worker\n","date":"2024/06/04","externalUrl":null,"permalink":"/authors/coderwhy/","section":"Authors","summary":"An all-round web worker","title":"coderwhy","type":"authors"},{"content":"欢迎来到我的网站!我很高兴你的来访。\n","date":"2024/06/04","externalUrl":null,"permalink":"/","section":"欢迎来到 Blowfish !","summary":"欢迎来到我的网站!我很高兴你的来访。","title":"欢迎来到 Blowfish !","type":"page"},{"content":" 项目打包和自动化部署 # 一. 项目部署和 DevOps # 1.1. 传统的开发模式 # 在传统的开发模式中,开发的整个过程是按部就班就行:\n但是这种模式存在很大的弊端:\n工作的不协调:开发人员在开发阶段,测试和运维人员其实是处于等待的状态。等到测试阶段,开发人员等待测试反馈 bug,也会处于等待状态。 线上 bug 的隐患:项目准备交付时,突然出现了 bug,所有人员需要加班、等待问题的处理; 1.2. DevOps 开发模式 # DevOps 是 Development 和 Operations 两个词的结合,将开发和运维结合起来的模式:\n1.3. 持续集成和持续交付 # 伴随着 DevOps 一起出现的两个词就是持续集成和持续交付(部署):\nCI 是 Continuous Integration(持续集成); CD 是两种翻译:Continuous Delivery(持续交付)或 Continuous Deployment(持续部署); 持续集成 CI:\n持续交付和持续部署:\n1.4. 自动化部署流程 # 二. 购买云服务器 # 2.1. 注册阿里云的账号 # 云服务器我们可以有很多的选择:阿里云、腾讯云、华为云。\n目前在公司使用比较多的是阿里云; 我自己之前也一直使用阿里云,也在使用腾讯云; 之前华为云也有找我帮忙推广他们的活动; 但是在我们的课程中,我选择目前使用更加广泛的阿里云来讲解:\n我们需要注册阿里云账号\nhttps://aliyun.com/\n注册即可,非常简单\n2.2. 购买云服务器 # 购买云服务器其实是购买一个实例。\n来到控制台: 创建实例,选择类型和配置 配置网络安全组 设置登录密码 三. 搭建服务器环境 # 3.1. jenkins 自动化部署 # 3.1.1. 安装 Java 环境 # Jenkins 本身是依赖 Java 的,所以我们需要先安装 Java 环境:\n这里我安装了 Java1.8 的环境 dnf search java-1.8 dnf install java-1.8.0-openjdk.x86_64 3.1.2. 安装 Jenkins # 因为 Jenkins 本身是没有在 dnf 的软件仓库包中的,所以我们需要连接 Jenkins 仓库:\nwget 是 Linux 中下载文件的一个工具,-O 表示输出到某个文件夹并且命名为什么文件; rpm:全称为The RPM Package Manage,是 Linux 下一个软件包管理器; wget –O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo # 导入GPG密钥以确保您的软件合法 rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key # 或者 rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key 编辑一下文件/etc/yum.repos.d/jenkins.repo\n可以通过 vim 编辑 [jenkins]\rname=Jenkins-stable\rbaseurl=http://pkg.jenkins.io/redhat\rgpgcheck=1 安装 Jenkins\ndnf install jenkins # --nogpgcheck(可以不加) 启动 Jenkins 的服务:\nsystemctl start jenkins systemctl status jenkins systemctl enable jenkins Jenkins 默认使用 8080 端口提供服务,所以需要加入到安全组中:\n3.1.3. Jenkins 用户 # 我们后面会访问 centos 中的某些文件夹,默认 Jenkins 使用的用户是 jenkins,可能会没有访问权限,所以我们需要修改一下它的用户:\n修改文件的路径:/etc/sysconfig/jenkins\n之后需要重启一下 Jenkins:\n# 也可以将Jenkins添加到root组中 sudo usermod -a -G root jenkins systemctl restart jenkins 3.1.4. Jenkins 配置 # 打开浏览器,输入:http://8.134.60.235:8080/\n注意:你输入自己的 IP 地址 获取输入管理员密码:\n在下面的地址中 cat /var/lib/jenkins/secrets/initialAdminPassword ![image-20201203173047824](/Users/coderwhy/Library/Application Support/typora-user-images/image-20201203173047824.png)\n可以安装推荐的插件:\n3.1.5. Jenkins 任务 # 新建任务:\n配置项目和保留策略:\n源码管理:\n构建触发器:\n这里的触发器规则是这样的:\n定时字符串从左往右分别是:分 时 日 月 周 #每半小时构建一次OR每半小时检查一次远程代码分支,有更新则构建 H/30 * * * * #每两小时构建一次OR每两小时检查一次远程代码分支,有更新则构建 H H/2 * * * #每天凌晨两点定时构建 H 2 * * * #每月15号执行构建 H H 15 * * #工作日,上午9点整执行 H 9 * * 1-5 #每周1,3,5,从8:30开始,截止19:30,每4小时30分构建一次 H/30 8-20/4 * * 1,3,5 构建环境:\n注意:我们需要搭建 Node 的环境\n第一步:配置 Node 的环境; 第二步:安装 Node 的插件; 第一步:配置 Node 的环境\n第二步:安装 Node 的插件\n这里因为我已经安装过了,所以没有搜索到; 构建执行的任务:\n查看 Node 的版本等是否有问题; 执行 npm install 安装项目的依赖; 移除原来 mall_cms 文件的所有内容; 将打包的 dist 文件夹内容移动到 mall_cms 文件夹; pwd node -v npm -v npm install npm run build pwd echo \u0026#39;构建成功\u0026#39; ls # 删除/root/mall_cms文件夹里所有的内容 rm -rf /root/mall_cms/* cp -rf ./dist/* /root/mall_cms/ 3.2. nginx 安装和配置 # 3.2.1. 安装 nginx # 后续我们部署会使用 nginx,所以需要先安装一下 nginx:\ndnf install nginx 启动 nginx:\nsystemctl start nginx systemctl status nginx systemctl enable nginx 3.2.2. 配置 nginx # 我们这里主要配置 nginx 的用户和默认访问目录:\n/etc/nginx/nginx.conf 配置用户:\n通过 Linux 命令创建文件夹和文件:\nmkdir /root/mall_cms cd /root/mall_cms touch index.html vi index.html 配置访问目录:\n","date":"2024/06/04","externalUrl":null,"permalink":"/posts/%E9%A1%B9%E7%9B%AE%E6%89%93%E5%8C%85%E5%92%8C%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2/","section":"","summary":"项目打包和自动化部署 # 一.","title":"项目打包和自动化部署","type":"posts"},{"content":" 引言 # 在项目中直接使用Axios或其他第三方库来发送网络请求获取数据时,会导致代码与网络请求的逻辑耦合度过高,导致难以维护。 本文将讲解如何将网路请求的代码进行封装来进行解耦操作 理解耦合度 # 代码耦合分为两种,直接依赖的结构耦合和间接依赖的内容耦合,这两种耦合都会导致可维护性下降、可测试性下降、可复用性下降、可扩展性下降。 这里在项目中直接使用Axios发送网络请求就是结构耦合,如果Axios的第三方库发生更新或者废弃,会导致我们的项目非常难以维护,这时将Axios封装到一个类中,就可以降低这种直接依赖带来的影响 Axios 概述 # Axios 是一个流行的用于发起 HTTP 请求的 JavaScript 库。它提供了一种简洁、灵活且易于使用的方式来处理网络请求,并且可以在浏览器和 Node.js 环境中使用。\n以下是 Axios 的一些主要功能:\n支持多种请求方式:Axios 支持常见的 HTTP 请求方法,如 GET、POST、PUT、DELETE 等,可以满足不同类型的请求需求。\n拦截器支持:Axios 提供了拦截器(Interceptors)功能,可以在请求发送或响应返回之前对它们进行拦截和处理。这使得可以在请求和响应的不同阶段添加全局的处理逻辑,例如认证、错误处理、请求/响应转换等。\nPromise API:Axios 基于 Promise 提供了一致的 API,可以使用链式调用来处理请求和响应。这使得可以更容易地处理异步操作,并使用 Promise 的特性,如 .then()、.catch()、.finally() 等。\n请求和响应的转换:Axios 允许自定义请求和响应的数据转换逻辑。可以通过拦截器将请求数据格式化为特定格式(如 JSON),或者将响应数据进行解析和转换,以适应项目的需求。\n错误处理:Axios 提供了全面的错误处理机制。它会自动检测和处理 HTTP 错误状态码,并将其包装为可读的错误对象。此外,还可以添加自定义的错误处理逻辑,以便更好地处理错误情况。\n取消请求:Axios 允许取消尚未完成的请求。这对于需要中止或忽略之前发出的请求非常有用,例如在用户取消操作或页面导航时。\nAxios 成为流行的发起 HTTP 请求的工具有以下原因:\n易于使用:Axios 提供了简洁而直观的 API,使得发送和处理 HTTP 请求变得简单和容易上手。\n广泛的应用:Axios 可以在浏览器和 Node.js 环境中使用,使得它在前端和后端开发中都具有广泛的适用性。\n功能丰富:Axios 提供了许多实用的功能,如拦截器、请求和响应的转换、错误处理等,使得开发人员能够更好地控制和处理网络请求。\n活跃的社区支持:Axios 有一个活跃的社区,拥有广泛的用户群体,因此可以获得广泛的支持和资源。这包括文档、示例代码、问题解答等。\n总而言之,Axios 是一个功能强大、易于使用且受欢迎的用于发起 HTTP 请求的工具,它提供了许多便捷的功能和良好的开发体验,使得处理网络请求变得更加简单和高效。\n封装Axios # 在项目目录中创建一个 services 文件夹来封装网络请求的逻辑。 在 services 中创建 modules 文件夹来编写复杂的网络请求逻辑,在 request 中封装Axios逻辑,创建 index 文件作为 services 统一出口。 在 request 中配置 index.js 文件封装一个类来处理网络请求,在 config.js 文件中配置基本选项,例如 BASE_URL、TIMEOUT。 配置 request 中的 index.js 文件 import axios from \u0026#34;axios\u0026#34;; import { BASE_URL, TIMEOUT } from \u0026#34;./config\u0026#34;; class HYRequest { // 创建构造函数 constructor(baseURL, timeout) { // 创建instance实例 this.instance = axios.create({ baseURL, timeout, }); // 配置拦截器,对获取数据进行响应 this.instance.interceptors.response.use( (res) =\u0026gt; { return res.data; }, (err) =\u0026gt; { return err; } ); } // request请求 request(config) { return this.instance.request(config); } // 配置get请求方法 get(config) { return this.request({ ...config, method: \u0026#34;get\u0026#34; }); } // 配置post请求方法 post(config) { return this.request({ ...config, method: \u0026#34;post\u0026#34; }); } } const hyRequest = new HYRequest(BASE_URL, TIMEOUT); export default hyRequest; 这里通过类的内聚性将网络请求的逻辑汇集到一起,用axios.create函数创建instance实例,构造函数接收baseUrl和timeout来配置instance,通过interceptor拦截器拦截response结果,在通过配置request、get、post实现对Axios的调用来完成网络请求,最后用创建好的类来创建一个实例,接收的参数为在config文件中配置好的基本选项,然后导出这个实例即可在项目代码中进行使用。\n配置 request 中的 config 文件 export const BASE_URL = \u0026#34;http://codercba.com:1888/airbnb/api\u0026#34;; export const TIMEOUT = 10000; 这里简单配置request的基本选项来方便我们发送网络请求\n对封装好的 hyRequest 进行导出 import hyRequest from \u0026#34;./request\u0026#34;; export default hyRequest; 这里是services文件夹的统一导出出口,方便进行代码维护\n使用这里封装的类进行网络请求 # import React, { memo, useEffect } from \u0026#34;react\u0026#34;; import hyRequest from \u0026#34;@/services\u0026#34;; const Home = memo(() =\u0026gt; { // 网络请求的代码 useEffect(() =\u0026gt; { hyRequest.get({ url: \u0026#34;/home/highscore\u0026#34; }).then((res) =\u0026gt; { console.log(res); }); }, []); return \u0026lt;div\u0026gt;Home\u0026lt;/div\u0026gt;; }); export default Home; 这里在 home 组件中先进行导入 hyRequest,即可发送网络请求,配置 config 参数,传入{ url: \u0026quot;/home/highscore\u0026quot; }来发送网络请求。\n这便是通过封装好的hyRequest类发送网络请求得到的结果\n总结 # 封装 Axios 的好处:\n降低代码耦合度:通过封装 Axios,可以将网络请求的具体实现细节隐藏在封装的模块或类中,其他模块只需要与封装后的接口进行交互,从而降低了代码的耦合度。 提高可维护性:封装 Axios 可以将网络请求的逻辑集中在一个地方,使得对网络请求的修改和维护更加方便和一致。如果需要更换或升级网络请求库,只需在封装层进行修改,而不需要在整个项目中的各个地方进行修改。 增强可测试性:通过封装 Axios,可以更容易地进行单元测试。由于网络请求的逻辑被封装在一个独立的模块或类中,可以方便地模拟请求和响应,编写针对封装层的单元测试。 提升代码的可复用性:封装 Axios 可以使得网络请求的代码在不同的项目中更易于复用。封装后的模块或类可以被多个模块或项目共享,而不需要重复编写发送网络请求的代码。 结束语 # 通过封装 Axios 来降低项目代码对于 Axios 的直接依赖,即使后面要更换使用网络请求的第三方库,也可以更加方便的修改和维护代码,在编写项目的时候我们也应该多应用这种思路,合理抽取代码逻辑,使代码更容易维护,提高代码复用性。\n","date":"2024/06/03","externalUrl":null,"permalink":"/posts/%E5%B0%81%E8%A3%85axios%E9%99%8D%E4%BD%8E%E4%BB%A3%E7%A0%81%E8%80%A6%E5%90%88%E5%BA%A6/","section":"","summary":"引言 # 在项目中直接使用Axios或其他第三方库来发送网络请求获取数据时,会导致代码与网络请求的逻辑耦合度过高,导致难以维护。 本文将讲解如何将网路请求的代码进行封装来进行解耦操作 理解耦合度 # 代码耦合分为两种,直接依赖的结构耦合和间接依赖的内容耦合,这两种耦合都会导致可维护性下降、可测试性下降、可复用性下降、可扩展性下降。 这里在项目中直接使用Axios发送网络请求就是结构耦合,如果Axios的第三方库发生更新或者废弃,会导致我们的项目非常难以维护,这时将Axios封装到一个类中,就可以降低这种直接依赖带来的影响 Axios 概述 # Axios 是一个流行的用于发起 HTTP 请求的 JavaScript 库。它提供了一种简洁、灵活且易于使用的方式来处理网络请求,并且可以在浏览器和 Node.","title":"关于封装axios网络请求降低代码耦合度","type":"posts"},{"content":" 速通 jQuery # 一、基础概念和选择器 # 1.基本概念及作用,如何简化 js 编程 # 简介的语法:简化 DOM 操作 跨浏览器兼容性 丰富的功能库:DOM 操作、事件处理、动画效果、AJAX 请求 强大的选择器:类似于 CSS 选择器,使开发人员轻松选取 DOM 元素 插件生态系统 社区支持和文档资源 2.jQuery 选择器语法 # 元素选择器 选择所有 p 元素:$(\u0026ldquo;p\u0026rdquo;) 选择所有 div 元素:$(\u0026ldquo;div\u0026rdquo;) 类选择器 选择所有 example 类的元素:$(\u0026quot;.example\u0026quot;) 选择同时具有 class1 和 class2 类的元素:$(\u0026quot;.class1.class2\u0026quot;) ID 选择器 选择具有 myId ID 的元素:$(\u0026quot;#myId\u0026quot;) 属性选择器 选择具有 data-name 属性的元素:$(\u0026quot;[data-name]\u0026quot;) 选择具有 data-cagetory 属性且值为 books 的元素:$(\u0026quot;[data-category=\u0026lsquo;books\u0026rsquo;]\u0026quot;) 子元素选择器: 选择所有 ul 元素下的 li 子元素:$(\u0026ldquo;ul \u0026gt; li\u0026rdquo;) 后代元素选择器: 选择所有 div 元素下的 p 后代元素:$(\u0026ldquo;div p\u0026rdquo;) 兄弟元素选择器: 选择紧接在 h2 元素后的所有 p 元素的兄弟元素:$(\u0026ldquo;h2 + p\u0026rdquo;) 过滤选择器 选择第一个 div 元素:$(\u0026ldquo;div:first\u0026rdquo;) 选择最后一个 p 元素:$(\u0026ldquo;p:last\u0026rdquo;) 选择所有偶数位置的 li 元素:$(\u0026ldquo;li:even\u0026rdquo;) 选择所有包含文本 example 的元素:$(\u0026quot;:contains(\u0026rsquo;example\u0026rsquo;)\u0026quot;) 实践 # 二、DOM 操作和事件处理 # 1.jQuery 常见操作 DOM 元素方法 # 添加元素\nappend():挂载节点末尾(子节点) prepend():挂载节点开头(子节点) after():挂载节点之后(兄弟节点) before():挂载节点之前(兄弟节点) 删除元素\nremove():移除节点 empty():清空节点内容(元素、文本) 移动元素\nappendTo():移动到节点末尾(子节点) prependTo():移动到节点开头(子节点) insertAfter():移动到节点之后(兄弟节点) insertBefore():移动到节点之前(兄弟节点) 替换元素\nreplaceWith():替换节点(文本/元素) 2.jQuery 常见的 DOM 操作方法 # addClass():增加 class removeClass():移除 class toggleClass():切换 class 属性 attr():获取节点属性 removeAttr():移除节点属性 val():获取表单值 text():获取文本节点内容 html():获取节点内容,包括子节点,返回一个字符串 3.jQuery 处理事件的基本概念和用法 # 绑定事件处理 事件委托 解除事件绑定 事件对象 三、动画效果和特效 # 1.动画效果 # 淡入淡出(fadeIn/fadeOut) 滑动效果(slideUp / slideDown) 动态调整样式(animate) 2.与用户交互添加特效和动态效果 # hover() click() scroll() 四、AJAX 和数据交互 # 1.使用 jQuery 来进行 AJAX 请求,从服务器获取数据并更新页面内容 # $.ajax(url, method, dataType, success(), error()) $.get(url, data, function) $.post(url, data, function) 2.实践通过 AJAX 请求获取数据,处理响应并动态更新页面内容 # 五、插件和扩展 # 1.jQuery 插件的概念和用法 # 选择合适的插件 引入 jQuery 和插件 配置和初始化插件 调用插件方法 处理插件回调 样式和定制 2.编写自定义的 jQuery 插件,以便根据自己的需求扩展 jQuery 的功能 # 引入 jQuery 库\n创建插件函数\n$.fn.myPlugin = function(options) {\r// 插件的代码逻辑\r};\r})(jQuery); 处理选项\n$.fn.myPlugin = function(options) {\rvar settings = $.extend({\roption1: defaultValue1,\roption2: defaultValue2\r}, options);\r// 使用 settings.option1 和 settings.option2 处理插件逻辑\r};\r})(jQuery); 遍历元素集合\n$.fn.myPlugin = function(options) {\rvar settings = $.extend({\roption1: defaultValue1,\roption2: defaultValue2\r}, options);\rreturn this.each(function() {\r// 在这里处理每个元素的逻辑,使用 $(this) 引用当前元素\r});\r};\r})(jQuery); 创建插件函数\n(function($) {\r$.fn.myPlugin = function(options) {\rvar settings = $.extend({\roption1: defaultValue1,\roption2: defaultValue2\r}, options);\rreturn this.each(function() {\rvar $element = $(this);\r// 操作元素,绑定事件等等\r$element.text(settings.option1);\r$element.on(\u0026#39;click\u0026#39;, function() {\r// 处理点击事件\r});\r});\r};\r})(jQuery); 使用插件 \u0026lt;script src=\u0026#34;your-plugin.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;\r\u0026lt;script\u0026gt;\r$(document).ready(function() {\r$(\u0026#39;.target-elements\u0026#39;).myPlugin({\roption1: value1,\roption2: value2\r});\r});\r\u0026lt;/script\u0026gt; ","date":"2024/06/03","externalUrl":null,"permalink":"/posts/%E9%80%9F%E9%80%9Ajquery/","section":"","summary":"速通 jQuery # 一、基础概念和选择器 # 1.","title":"速通jQuery","type":"posts"},{"content":" Introduction # This is bold text, and this is emphasized text.\nHello! \u0026#x1f44b;\nVisit the Hugo website!\n","date":"2024/06/01","externalUrl":null,"permalink":"/posts/second-post/","section":"","summary":"Introduction # This is bold text, and this is emphasized text.","title":"My First Post","type":"posts"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/about/","section":"欢迎来到 Blowfish !","summary":"","title":"","type":"page"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"0001/01/01","externalUrl":null,"permalink":"/topics/","section":"Topics","summary":"","title":"Topics","type":"topics"},{"content":"本节包含了我所有的当前项目。\n","date":"0001/01/01","externalUrl":null,"permalink":"/projects/","section":"项目","summary":"本节包含了我所有的当前项目。","title":"项目","type":"projects"},{"content":"本节包含了我所有的 React 项目。\n","date":"0001/01/01","externalUrl":null,"permalink":"/projects/reactprojects/","section":"项目","summary":"本节包含了我所有的 React 项目。","title":"项目","type":"projects"},{"content":"本节包含了我所有的 Vue 项目。\n","date":"0001/01/01","externalUrl":null,"permalink":"/projects/vueprojects/","section":"项目","summary":"本节包含了我所有的 Vue 项目。","title":"项目","type":"projects"}] \ No newline at end of file diff --git "a/posts/\351\241\271\347\233\256\346\211\223\345\214\205\345\222\214\350\207\252\345\212\250\345\214\226\351\203\250\347\275\262/index.html" "b/posts/\351\241\271\347\233\256\346\211\223\345\214\205\345\222\214\350\207\252\345\212\250\345\214\226\351\203\250\347\275\262/index.html" index b50b515..1cad4a1 100644 --- "a/posts/\351\241\271\347\233\256\346\211\223\345\214\205\345\222\214\350\207\252\345\212\250\345\214\226\351\203\250\347\275\262/index.html" +++ "b/posts/\351\241\271\347\233\256\346\211\223\345\214\205\345\222\214\350\207\252\345\212\250\345\214\226\351\203\250\347\275\262/index.html" @@ -713,7 +713,7 @@

作者

- coderWhy + coderwhy