learn.lianglianglee.com/专栏/前端工程化精讲-完/18 工具盘点:掌握那些流行的代码部署工具.md.html
2022-09-06 22:30:37 +08:00

288 lines
21 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>18 工具盘点:掌握那些流行的代码部署工具.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/前端工程化精讲-完/00 开篇词 建立上帝视角,全面系统掌握前端效率工程化.md.html">00 开篇词 建立上帝视角,全面系统掌握前端效率工程化</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/01 项目基石:前端脚手架工具探秘.md.html">01 项目基石:前端脚手架工具探秘</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/02 界面调试:热更新技术如何开着飞机修引擎?.md.html">02 界面调试:热更新技术如何开着飞机修引擎?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/03 构建提速:如何正确使用 SourceMap.md.html">03 构建提速:如何正确使用 SourceMap</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/04 接口调试Mock 工具如何快速进行接口调试?.md.html">04 接口调试Mock 工具如何快速进行接口调试?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/05 编码效率:如何提高编写代码的效率?.md.html">05 编码效率:如何提高编写代码的效率?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/06 团队工具:如何利用云开发提升团队开发效率?.md.html">06 团队工具:如何利用云开发提升团队开发效率?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/07 低代码工具:如何用更少的代码实现更灵活的需求.md.html">07 低代码工具:如何用更少的代码实现更灵活的需求</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/08 无代码工具:如何做到不写代码就能高效交付?.md.html">08 无代码工具:如何做到不写代码就能高效交付?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/09 构建总览:前端构建工具的演进.md.html">09 构建总览:前端构建工具的演进</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/10 流程分解Webpack 的完整构建流程.md.html">10 流程分解Webpack 的完整构建流程</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/11 编译提效:如何为 Webpack 编译阶段提速?.md.html">11 编译提效:如何为 Webpack 编译阶段提速?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/12 打包提效:如何为 Webpack 打包阶段提速?.md.html">12 打包提效:如何为 Webpack 打包阶段提速?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/13 缓存优化:那些基于缓存的优化方案.md.html">13 缓存优化:那些基于缓存的优化方案</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/14 增量构建Webpack 中的增量构建.md.html">14 增量构建Webpack 中的增量构建</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/15 版本特性Webpack 5 中的优化细节.md.html">15 版本特性Webpack 5 中的优化细节</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/16 无包构建:盘点那些 No-bundle 的构建方案.md.html">16 无包构建:盘点那些 No-bundle 的构建方案</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/17 部署初探:为什么一般不在开发环境下部署代码?.md.html">17 部署初探:为什么一般不在开发环境下部署代码?</a>
</li>
<li>
<a class="current-tab" href="/专栏/前端工程化精讲-完/18 工具盘点:掌握那些流行的代码部署工具.md.html">18 工具盘点:掌握那些流行的代码部署工具</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/19 安装提效:部署流程中的依赖安装效率优化.md.html">19 安装提效:部署流程中的依赖安装效率优化</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/20 流程优化:部署流程中的构建流程策略优化.md.html">20 流程优化:部署流程中的构建流程策略优化</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/21 容器方案:从构建到部署,容器化方案的优势有哪些?.md.html">21 容器方案:从构建到部署,容器化方案的优势有哪些?</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/22 案例分析:搭建基本的前端高效部署系统.md.html">22 案例分析:搭建基本的前端高效部署系统</a>
</li>
<li>
<a href="/专栏/前端工程化精讲-完/23 结束语 前端效率工程化的未来展望.md.html">23 结束语 前端效率工程化的未来展望</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>18 工具盘点:掌握那些流行的代码部署工具</h1>
<p>上节课我们通过分析“为什么不在本地环境进行部署”这个问题,来对比部署系统的重要性:一个优秀的部署系统,能够自动化地完整部署流程的各环节,无须占用开发人员的时间与精力,同时又能保证环境与过程的一致性,增强流程的稳定性,降低外部因素导致的风险。此外,部署系统还可以提供过程日志、历史版本构建包、通知邮件等各类辅助功能模块,来打造更完善的部署工作流程。</p>
<p>这节课我就来为你介绍在企业项目和开源项目中被广泛使用的几个典型部署工具,包括 Jenkins、CircleCI、Github Actions、Gitlab CI。</p>
<h3>Jenkins</h3>
<p><img src="assets/Ciqc1F-AFmqADoTDAADSwJG8TWA117.png" alt="png" /></p>
<p>Jenkins Logo</p>
<p><a href="https://www.jenkins.io/">Jenkins</a> 是诞生较早且使用广泛的开源持续集成工具。早在 2004 年Sun 公司就推出了它的前身 Husdon它在 2011 年更名为 Jenkins。下面介绍它的功能特点。</p>
<h4>功能特点</h4>
<ul>
<li><strong>搭建方式</strong>Jenkins 是一款基于 Java 的应用程序,官方提供了 Linux、Mac 和 Windows 等各系统下的搭建方式,同时也提供了基于 Docker 的容器化搭建方式。此外Jenkins 支持分布式的服务方式,各任务可以在不同的节点服务器上运行。</li>
<li><strong>收费方式</strong>Jenkins 是完全免费的开源产品。</li>
<li><strong>多类型 Job</strong>Job 是 Jenkins 中的基本工作单元。它可以是一个项目的构建部署流程也可以是其他类型例如流水线Pipeline。在 Jenkins 中支持各种类型的 Job自定义项目、流水线、文件夹、多配置项目、Github 组织等。</li>
<li><strong>插件系统</strong>Jenkins 架构中内置的插件系统为它提供了极强的功能扩展性。目前 Jenkins 社区中共有超过<a href="https://plugins.jenkins.io/">1500 个插件</a>,功能涵盖了继续继承和部署的各个环节。</li>
<li><strong>Job 配置</strong>:得益于其插件系统,在 Jenkins 的 Job 配置中可以灵活定制各种复杂的构建与部署选项,例如构建远程触发、构建参数化选项、关联 Jira、执行 Windows 批处理、邮件通知等。</li>
<li><strong>API 调用</strong>Jenkins 提供了 Restful 的 API 接口,可用于外部调用控制节点、任务、配置、构建等处理过程。</li>
</ul>
<p><img src="assets/Ciqc1F-AFoiAbc1YAAIiZzD3poU694.png" alt="png" /></p>
<p>Jenkins 中 Job 的基本配置界面</p>
<h3>CircleCI</h3>
<p><img src="assets/Ciqc1F-AFpGAfFjTAAAXBcXm7AQ619.png" alt="png" /></p>
<p>CircleCI Logo</p>
<p><a href="https://circleci.com/product/">CircleCI</a> 是一款基于云端的持续集成服务,下面介绍它的功能特点。</p>
<h4>功能特点</h4>
<ul>
<li><strong>云端服务</strong>:由于 CircleCI 是一款基于云端的持续集成服务,因此无须搭建和管理即可直接使用。同时也提供了收费的本地化搭建服务方式。</li>
<li><strong>收费方式</strong>CircleCI 的云端服务分为免费与收费两种,免费版本一个账号只能同时运行一个 Job同时对使用数据量、构建环境等有一定限制。而收费版本则提供了更多的并发构建数、更多的环境、更快的性能等。此外如第一点所述企业内部使用的本地化搭建服务方式也是收费的。</li>
<li><strong>缓存优化</strong>CircleCI 的任务构建是基于容器化的,因此能够缓存依赖安装的数据,从而加速构建流程。</li>
<li><strong>SSH 调试</strong>:它提供了基于 SSH 访问构建容器的功能,便于在构建错误时快速地进入容器内进行调试。</li>
<li><strong>配置简化</strong>:在 CircleCI 中提供了开箱即用的用户体验,只需要少量配置即可快速开始构建项目。</li>
<li><strong>API 调用</strong>CircleCI 中也提供了 Restfull 的 API 接口,可用于访问项目、构建和产物。</li>
</ul>
<p><img src="assets/Ciqc1F-AFqKAU29WAARwRnLOcKU376.png" alt="png" /></p>
<p>CircleCI 项目流水线示例界面</p>
<h3>Github Actions</h3>
<p><img src="assets/Ciqc1F-AFquAK06qAAATdguATCs007.png" alt="png" /></p>
<p>Github Actions Logo</p>
<p><a href="https://github.com/features/actions">Github Actions</a>GHA是 Github 官方提供的 CI/CD 流程工具,用于为 Github 中的开源项目提供简单易用的持续集成工作流能力。</p>
<h4>功能特点</h4>
<ul>
<li><strong>多系统</strong>:提供 Linux、Mac、Windows 等各主流操作系统环境下的运行能力,同时也支持在容器中运行。</li>
<li><strong>矩阵运行</strong>:支持同时在多个操作系统或不同环境下(例如不同 NodeJS 版本的环境中)运行构建和测试流程。</li>
<li><strong>多语言</strong>:支持 NodeJS、JAVA、PHP、Python、Go、Rust 等各种编程语言的工作流程。</li>
<li><strong>多容器测试</strong>:支持直接使用 Docker-Compose 进行多容器关联的测试(而 CircleCI 中则需要先执行安装才能使用)。</li>
<li><strong>社区支持</strong>Github 社区中提供了众多工作流的模板可供选择使用,例如构建并发布 npm 包、构建并提交到 Docker Hub 等。</li>
<li><strong>费用情况</strong>Github Action 对于公开的仓库,以及在自运维执行器的情况下是免费的。而对于私有仓库则提供一定额度的免费执行时间和免费存储空间,超出部分则需要收费。</li>
</ul>
<p><img src="assets/CgqCHl-AFrqAZddtAAJj5zKVbrY255.png" alt="png" /></p>
<p>Github Actions 的工作流模板</p>
<p><img src="assets/Ciqc1F-AFsGAVzEOAAF9PCfkPQQ795.png" alt="png" /></p>
<p>Github Actions 中的矩阵执行示例</p>
<h3>Gitlab CI</h3>
<p>Gitlab 是由 Gitlab Inc. 开发的基于 Git 的版本管理与软件开发平台。除了作为代码仓库外它还具有在线编辑、Wiki、CI/CD 等功能。在费用方面它提供了免费的社区版本Community EditionCE和免费或收费的商用版本Enterprise EditionEE。其中社区版本和免费的商用版本的区别主要体现在升级到付费商用版本时的操作成本。另一方面即使是免费的社区版本其功能也能够满足企业内的一般使用场景因此常作为企业内部版本管理系统的主要选择之一下面我们就来了解 Gitlab 内置的 CI/CD 功能。</p>
<h4>功能特点</h4>
<ul>
<li>与前面两款产品相似的是Gitlab CI 也使用 yml 文件作为 CI/CD 工作流程的配置文件,在 Gitlab 中,默认的配置文件名为 .gitlab-ci.yml。在配置文件中涵盖了任务流水线Pipeline的处理过程细节例如在配置文件中可以定义一到多个任务Job每个任务可以指定一个任务运行的阶段Stage和一到多个执行脚本Script等。完整的 .gitlab-ci.yml 配置项可参考<a href="https://docs.gitlab.com/ee/ci/yaml/README.html">官方文档</a></li>
<li><strong>独立安装执行器</strong>与前面两款产品不同的是Gitlab 中需要单独安装执行器。Gitlab 中的执行器 Gitlab Runner 是一个独立运行的开源程序,它的作用是执行任务,并将结果反馈到 Gitlab 中。开发者可以在独立的服务器上<a href="https://docs.gitlab.com/runner/install/index.html">安装</a>Gitlab Runner 工具,然后依次执行<strong>gitlab-runner register</strong>注册特定配置的 Runner最后执行<strong>gitlab-runner start</strong>启动相应服务。此外,项目中除了注册独立的 Runner 外,也可以使用共享的或组内通用的 Runner。</li>
</ul>
<p>当项目根目录中存在.gitlab-ci.yml 文件时,用户提交代码到 Git 仓库时,在 Gitlab 的 CI/CD 面板中即可看到相应的任务记录,当成功设置 gitlab-runner 时这些任务就会在相应的 Runner 中执行并反馈日志和结果。如下图所示:</p>
<p><img src="assets/CgqCHl-AFtSAdFLVAAJ3DhDFMt0140.png" alt="png" /></p>
<p>Gitlab CI/CD 的任务列表示例界面</p>
<h3>总结</h3>
<p>最后我们来做一个总结。在今天的课程里,我们一起了解了 4 个典型 CI/CD 工具Jenkins、CircleCI、Github Actions 和 Gitlab CI。</p>
<ul>
<li>在这四款工具中Jenkins 是诞生最早也最广为人知的,它的优点在于插件功能丰富且完全开源免费,因此在企业中应用较多。但缺点在于缺少特定语言环境工作流的配置模板,使用成本相对较高。此外,它的服务器需要独立部署和运维。</li>
<li>CircleCI 和 Github Actions 都提供了基于容器化的云端服务的能力提供不同的收费策略以满足普通小型开源项目和大型私有项目的各类需求。两者相比CircleCI 胜在除了对接 Github 中的项目外,还支持 BitBucket、Heroku 等平台的流程对接。而 Github Actions 则是 Github 项目中内置的 CI/CD 工具,使用成本最低,且提供了矩阵运行、多容器测试、多工作流模板等特色功能。</li>
<li>Gitlab CI 则是企业中较受欢迎的版本管理工具。Gitlab 中内置 CI/CD 工具,和 CircleCI 与 Github Actions 相同的是Gitlab CI 也使用 yml 格式的配置文件,不同之处主要在于需要独立安装与配置 Runner。</li>
</ul>
<p>本节课的课后思考题是:如果你所在的企业需要选择一款 CI/CD 工具,你选择的主要依据有哪些呢?以今天谈到的几款工具为例,谈谈你的选择和想法吧。</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/前端工程化精讲-完/17 部署初探:为什么一般不在开发环境下部署代码?.md.html">上一页</a>
</div>
<div style="float: right">
<a href="/专栏/前端工程化精讲-完/19 安装提效:部署流程中的依赖安装效率优化.md.html">下一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"7099776fa8b23cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>