栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Vue3+TypeScript从入门到进阶(八)——项目打包和自动化部署——附沿途学习案例及项目实战代码

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Vue3+TypeScript从入门到进阶(八)——项目打包和自动化部署——附沿途学习案例及项目实战代码

文章目录
      • 一、简介
      • 二、Vue2和Vue3区别
      • 三、Vue知识点学习
      • 四、TypeScript知识点
      • 五、项目实战
      • 六、项目打包和自动化部署
        • 一. 项目部署和DevOps
          • 1.1. 传统的开发模式
          • 1.2. DevOps开发模式
          • 1.3. 持续集成和持续交付
          • 1.4. 自动化部署流程
        • 二. 购买云服务器
          • 2.1. 注册阿里云的账号
          • 2.2. 购买云服务器
        • 三. 搭建服务器环境
          • 3.1.CentOS安装和使用DNF
          • 3.2. jenkins自动化部署
            • 3.2.1. 安装Java环境
            • 3.2.2. 安装Jenkins
            • 3.2.3. Jenkins用户
            • 3.2.4. Jenkins配置
            • 3.2.5. Jenkins任务
            • 3.2.6 Jenkins执行任务时 permission denied
          • 3.3. nginx安装和配置
            • 3.3.1. 安装nginx
            • 3.3.2. 配置nginx
      • 七、沿途学习代码地址及案例地址
        • 1、沿途学习代码地址
        • 2、项目案例地址
      • 八、知识拓展
        • 1、ES6数组与对象的解构赋值详解
          • 数组的解构赋值
          • 对象的解构赋值
          • 字符串的解构赋值
        • 2、JavaScript的 ...(展开运算符)
        • 3、export 'defineEmit' (imported as 'defineEmit') was not found in 'vue'
      • 九、其他知识学习
        • 1、Webpack学习
        • 2、数据可视化-echarts
        • 3、Vue2学习
        • 4、JavaScript面向对象和设计模式
        • 5、微前端学习

一、简介

Vue3+TypeScript从入门到进阶(一)——Vue3简介及介绍——附沿途学习案例及项目实战代码

二、Vue2和Vue3区别

Vue3+TypeScript从入门到进阶(二)——Vue2和Vue3的区别——附沿途学习案例及项目实战代码

三、Vue知识点学习

Vue3+TypeScript从入门到进阶(三)——Vue3基础知识点(上)——附沿途学习案例及项目实战代码

Vue3+TypeScript从入门到进阶(四)——Vue3基础知识点(中)——附沿途学习案例及项目实战代码

Vue3+TypeScript从入门到进阶(五)——Vue3基础知识点(下)——附沿途学习案例及项目实战代码

四、TypeScript知识点

Vue3+TypeScript从入门到进阶(六)——TypeScript知识点——附沿途学习案例及项目实战代码

五、项目实战

Vue3+TypeScript从入门到进阶(七)——项目实战——附沿途学习案例及项目实战代码

六、项目打包和自动化部署 一. 项目部署和DevOps 1.1. 传统的开发模式

在传统的开发模式中,开发的整个过程是按部就班就行:

但是这种模式存在很大的弊端:

  • 工作的不协调:开发人员在开发阶段,测试和运维人员其实是处于等待的状态。等到测试阶段,开发人员等待测试反馈bug,也会处于等待状态。
  • 线上bug的隐患:项目准备交付时,突然出现了bug,所有人员需要加班、等待问题的处理;
1.2. DevOps开发模式

DevOps是Development和Operations两个词的结合,将开发和运维结合起来的模式:

1.3. 持续集成和持续交付

伴随着DevOps一起出现的两个词就是持续集成和持续交付(部署):

  • CI是Continuous Integration(持续集成);
  • CD是两种翻译:Continuous Delivery(持续交付)或Continuous Deployment(持续部署);

持续集成CI:

持续交付和持续部署:

1.4. 自动化部署流程

二. 购买云服务器 2.1. 注册阿里云的账号

云服务器我们可以有很多的选择:阿里云、腾讯云、华为云。

  • 目前在公司使用比较多的是阿里云;
  • 我自己之前也一直使用阿里云,也在使用腾讯云;
  • 之前华为云也有找我帮忙推广他们的活动;

但是在我们的课程中,我选择目前使用更加广泛的阿里云来讲解:

我们需要注册阿里云账号

  • https://aliyun.com/

  • 注册即可,非常简单

2.2. 购买云服务器

购买云服务器其实是购买一个实例。

1.来到控制台:

2.创建实例,选择类型和配置

3.配置网络安全组

4.创建实例

三. 搭建服务器环境 3.1.CentOS安装和使用DNF

DNF新一代的RPM软件包管理器。他首先出现在 Fedora 18 这个发行版中。而最近,他取代了YUM,正式成为 Fedora 22 的包管理器。

DNF包管理器克服了YUM包管理器的一些瓶颈,提升了包括用户体验,内存占用,依赖分析,运行速度等多方面的内容。

DNF使用 RPM, libsolv 和 hawkey 库进行包管理操作。尽管它没有预装在 CentOS 和 RHEL 7 中,但你可以在使用 YUM 的同时使用 DNF 。

DNF 的最新稳定发行版版本号是 1.0,发行日期是2015年5月11日。 这一版本的额 DNF 包管理器(包括在他之前的所有版本) 都大部分采用 Pathon 编写,发行许可为GPL v2.

– 安装 DNF 包管理器

DNF 并未默认安装在 RHEL 或 CentOS 7系统中,但是 Fedora 22 已经默认使用 DNF .

1.为了安装 DNF ,您必须先安装并启用 epel-release 依赖。

在系统中执行以下命令:

yum install epel-release

或者

yum install epel-release -y

其实这里并没有强制使用”-y”的理由,相反的,在不使用”-y”的情况下,用户可以在安装过程中查看到底有哪些东西被安装进了系统。但对于没有这个需求的用户,您可以在 YUM 中使用”-y”参数来自动安装所有东西。

2.使用 epel-release 依赖中的 YUM 命令来安装 DNF 包。、

在系统中执行以下命令:

yum install dnf

然后, DNF 包管理器就被成功的安装到你的系统中了。接下来,是时候开始我们的教程了!在这个教程中,您将会学到27个用于 DNF 包管理器的命令。使用这些命令,你可以方便有效的管理您系统中的 RPM 软件包。现在,让我们开始学习 DNF 包管理器的27条常用命令吧!

– 查看 DNF 包管理器版本

用处:该命令用于查看安装在您系统中的 DNF 包管理器的版本

命令:

dnf –version
3.2. jenkins自动化部署 3.2.1. 安装Java环境

Jenkins本身是依赖Java的,所以我们需要先安装Java环境:

  • 这里我安装了Java1.8的环境
dnf search java-1.8
dnf install java-1.8.0-openjdk.x86_64
3.2.2. 安装Jenkins

因为Jenkins本身是没有在dnf的软件仓库包中的,所以我们需要连接Jenkins仓库:

  • wget是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

  • 可以通过vim编辑
[jenkins]

name=Jenkins-stable

baseurl=http://pkg.jenkins.io/redhat

gpgcheck=1

安装Jenkins

dnf install jenkins # --nogpgcheck(可以不加)

启动Jenkins的服务:

systemctl start jenkins
systemctl status jenkins
systemctl enable jenkins

Jenkins默认使用8080端口提供服务,所以需要加入到安全组中:

3.2.3. Jenkins用户

我们后面会访问centos中的某些文件夹,默认Jenkins使用的用户是 jenkins,可能会没有访问权限,所以我们需要修改一下它的用户:

修改文件的路径:/etc/sysconfig/jenkins

之后需要重启一下Jenkins:

systemctl restart jenkins
3.2.4. Jenkins配置

打开浏览器,输入:http://8.134.60.235:8080/

  • 注意:你输入自己的IP地址

获取输入管理员密码:

  • 在下面的地址中 cat /var/lib/jenkins/secrets/initialAdminPassword

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGFIYzwF-1653820193033)(/Users/coderwhy/Library/Application Support/typora-user-images/image-20201203173047824.png)]

可以安装推荐的插件:

3.2.5. Jenkins任务

新建任务:

配置项目和保留策略:

源码管理:

构建触发器:

这里的触发器规则是这样的:

  • 定时字符串从左往右分别是:分 时 日 月 周
#每半小时构建一次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

构建环境:

注意:我们需要搭建Node的环境

  • 第一步:配置Node的环境;
  • 第二步:安装Node的插件;

第一步:配置Node的环境

第二步:安装Node的插件

  • 这里因为我已经安装过了,所以没有搜索到;

构建执行的任务:

  • 查看Node的版本等是否有问题;
  • 执行 npm install 安装项目的依赖;
  • 移除原来mall_cms文件的所有内容;
  • 将打包的dist文件夹内容移动到mall_cms文件夹;
pwd
node -v
npm -v

npm install 
npm run build

pwd

echo '构建成功'

ls

# 删除/root/mall_cms文件夹里所有的内容
rm -rf /root/mall_cms
 let { name, age } = person
 console.log(name,age)

如上面注释中所说,声明了变量 name和age,然后分别从对象person中寻找与变量同名的属性,并将属性的值赋值给变量

所以,这里的关键,就是首先要知道对象中都有哪些属性,然后再使用字面量的方式声明与其同名的变量

2、属性不存在怎么办
如果不小心声明了一个对象中不存在的属性怎么办?

或者,实际情况下,可能是我们就是想再声明一个变量,但是这个变量也不需要从对象中获取值,这个时候,此变量的值就是 undefined

let person = {
    name: 'yhb',
    age: 20
}   
let { name, age,address } = person
console.log(name,age,address)

此时,可以给变量加入一个默认值

let { name, age,address='北京' } = person

3、属性太受欢迎怎么办

当前声明了 name 和 age 变量,其值就是person对象中name和age属性的值,如果还有其他变量也想获取这两个属性的值怎么办?

 let { name, age, address = '北京' } = person
 console.log(name, age, address)
 let { name, age } = person
 console.log(name, age)

上面的方法肯定不行,会提示定义了重复的变量 name 和 age

那怎么办呢?

难道只能放弃结构赋值,使用老旧的方式吗?

let l_name=person.name
let l_age=person.age
console.log(l_name,l_age)

其实不然!

let {name:l_name,age:l_age}=person
console.log(l_name,l_age)

说明:

声明变量 l_name 并从对象person中获取name属性的值赋予此变量
声明变量 l_age, 并从对象person中获取age属性的值赋予此变量
这里的重点是下面这行代码

let {name:l_name,age:l_age}=person

按照创建对象字面量的逻辑,name 为键,l_name 为值。但注意,这里是声明变量,并不是创建对象字面量,所以争取的解读应该是

声明变量 l_name,并从person 对象中找到与 name 同名的属性,然后将此属性的值赋值给变量 l_name

所以,我们最后输出的是变量 l_name和l_age

console.log(l_name,l_age)

当然这种状态下,也是可以给变量赋予默认值的

let { name:l_name, age:l_age, address:l_address='北京' }=person

4、嵌套对象如何解构赋值

let person = {
 name: 'yhb',
 age: 20,
 address: {
     province: '河北省',
     city: '保定'
 }
}
// 从对象 person 中找到 address 属性,并将值赋给变量 address
let {address}=person
// 从对象 address 中找到 province 属性,并将值赋给变量 province
let {province}=address
console.log(province)

上面代码一层层的进行结构赋值,也可以简写为如下形式

let {address:{province}}=person  

从peson 对象中找到 address 属性,取出其值赋值给冒号前面的变量 address,然后再将 变量address 的值赋值给 冒号 后面的变量 {province},相当于下面的写法

let {province}=address
字符串的解构赋值

1、字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = 'hello';
len // 5
2、JavaScript的 …(展开运算符)

三个连续的点具有两个含义:展开运算符(spread operator)和剩余运算符(rest operator)。

展开运算符

展开运算符允许迭代器在接收器内部分别展开或扩展。迭代器和接收器可以是任何可以循环的对象,例如数组、对象、集合、映射等。你可以把一个容器的每个部分分别放入另一个容器。

const newArray = ['first', ...anotherArray];

剩余参数

剩余参数语法允许我们将无限数量的参数表示为数组。命名参数的位置可以在剩余参数之前。

const func = (first, second, ...rest) => {};

用例

定义是非常有用的,但是很难仅从定义中理解概念。我认为用日常用例会加强对定义的理解。

复制数组

当我们需要修改一个数组,但又不想改变原始数组(其他人可能会使用它)时,就必须复制它。

const fruits = ['apple', 'orange', 'banana'];
const fruitsCopied = [...fruits]; // ['apple', 'orange', 'banana']

console.log(fruits === fruitsCopied); // false

// 老方法
fruits.map(fruit => fruit);

它正在选择数组中的每个元素,并将每个元素放在新的数组结构中。我们也可以使用 map 操作符实现数组的复制并进行身份映射。

唯一数组

如果我们想从数组中筛选出重复的元素,那么最简单的解决方案是什么?

Set 对象仅存储唯一的元素,并且可以用数组填充。它也是可迭代的,因此我们可以将其展开到新的数组中,并且得到的数组中的值是唯一的。

const fruits = ['apple', 'orange', 'banana', 'banana'];
const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana']

// old way
fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);

串联数组
可以用 concat 方法连接两个独立的数组,但是为什么不再次使用展开运算符呢?

const fruits = ['apple', 'orange', 'banana'];
const vegetables = ['carrot'];
const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot']
const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana']

// 老方法
const fruitsAndVegetables = fruits.concat(vegetables);
fruits.unshift('carrot');

将参数作为数组进行传递

当传递参数时,展开运算符能够使我们的代码更具可读性。在 ES6 之前,我们必须将该函数应用于 arguments。现在我们可以将参数展开到函数中,从而使代码更简洁。

const mixer = (x, y, z) => console.log(x, y, z);
const fruits = ['apple', 'orange', 'banana'];

mixer(...fruits); // 'apple', 'orange', 'banana'

// 老方法
mixer.apply(null, fruits);

数组切片

使用 slice 方法切片更加直接,但是如果需要的话,展开运算符也可以做到。但是必须一个个地去命名其余的元素,所以从大数组中进行切片的话,这不是个好方法。

const fruits = ['apple', 'orange', 'banana'];
const [apple, ...remainingFruits] = fruits; // ['orange', 'banana']

// 老方法
const remainingFruits = fruits.slice(1);

将参数转换为数组
Javascript 中的参数是类似数组的对象。你可以用索引来访问它,但是不能调用像 map、filter 这样的数组方法。参数是一个可迭代的对象,那么我们做些什么呢?在它们前面放三个点,然后作为数组去访问!

const mixer = (...args) => console.log(args);
mixer('apple'); // ['apple']

将 NodeList 转换为数组
参数就像从 querySelectorAll 函数返回的 NodeList 一样。它们的行为也有点像数组,只是没有对应的方法。

[...document.querySelectorAll('div')];

// 老方法
Array.prototype.slice.call(document.querySelectorAll('div'));

复制对象
最后,我们介绍对象操作。复制的工作方式与数组相同。在以前它可以通过 Object.assign 和一个空的对象常量来实现。

const todo = { name: 'Clean the dishes' };
const todoCopied = { ...todo }; // { name: 'Clean the dishes' }
console.log(todo === todoCopied); // false

// 老方法
Object.assign({}, todo);

合并对象
合并的唯一区别是具有相同键的属性将被覆盖。最右边的属性具有最高优先级。

const todo = { name: 'Clean the dishes' };
const state = { completed: false };
const nextTodo = { name: 'Ironing' };
const merged = { ...todo, ...state, ...nextTodo }; // { name: 'Ironing', completed: false }

// 老方法
Object.assign({}, todo, state, nextTodo);

需要注意的是,合并仅在层次结构的第一级上创建副本。层次结构中的更深层次将是相同的引用。

将字符串拆分为字符
最后是字符串。你可以用展开运算符把字符串拆分为字符。当然,如果你用空字符串调用 split 方法也是一样的。

const country = 'USA';
console.log([...country]); // ['U', 'S', 'A']

// 老方法
country.split('');
3、export ‘defineEmit’ (imported as ‘defineEmit’) was not found in ‘vue’



在学习vue3的顶层编写方式时的父子组件通信的时候,我们会看到一些比较老(2020、2021年初)的博客里面会有使用defineEmit的,但是如果我们用比较新版本的Vue3的话,就会报错。原因是,新版本的Vue3将defineEmit改成了defineEmits了

九、其他知识学习 1、Webpack学习

Webpack从入门到进阶(一)—附沿路学习案例代码

Webpack从入门到进阶(二)—附沿路学习案例代码

Webpack从入门到进阶(三)—附沿路学习案例代码

2、数据可视化-echarts

数据可视化-echarts入门、常见图表案例、超详细配置解析及项目案例

3、Vue2学习

Vue项目开发-仿蘑菇街电商APP

Vue 知识点汇总(上)–附案例代码及项目地址

Vue 知识点汇总(下)–附案例代码及项目地址

4、JavaScript面向对象和设计模式

JavaScript面向对象编程浅析

JavaScript设计模式浅析

5、微前端学习

SingleSpa及qiankun入门、源码分析及案例

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/940925.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号