前端部署实战:从人工发布到全自动化流程

"又发错环境了!"周四下午,测试同学小李急匆匆地找到我。原来是开发人员手动部署时,不小心把测试代码发布到了生产环境。这已经是本月第二次类似的事故了。

回想起每次发布时的场景:手动打包、手动上传、手动替换文件...每一步都战战兢兢,生怕出错。作为技术负责人,我决定要彻底改变这种状况,建立一套可靠的自动化部署流程。

现状问题

首先梳理了当前部署流程中的痛点:

  • 人工操作步骤多,容易出错
  • 环境配置混乱,经常配错
  • 发布耗时长,经常加班
  • 回滚困难,出问题很被动
  • 缺乏发布记录,无法追溯

就像是一场没有彩排的演出,每次都提心吊胆。我们需要把这个过程变得像工厂的流水线一样可靠。

自动化方案

1. 构建脚本

首先是统一的构建脚本:

// scripts/build.js
const webpack = require('webpack')
const { merge } = require('webpack-merge')
const baseConfig = require('./webpack.base')
const envConfigs = {dev: require('./webpack.dev'),test: require('./webpack.test'),prod: require('./webpack.prod')
}async function build(env) {// 合并配置const config = merge(baseConfig, envConfigs[env], {mode: env === 'dev' ? 'development' : 'production'})// 执行构建const compiler = webpack(config)const stats = await new Promise((resolve, reject) => {compiler.run((err, stats) => {if (err) reject(err)else resolve(stats)})})// 输出构建信息console.log(stats.toString({colors: true,modules: false,children: false}))// 验证构建产物await validateBuild()
}// 构建产物验证
async function validateBuild() {const files = await fs.readdir('./dist')// 检查必要文件const required = ['index.html', 'main.js', 'vendor.js']const missing = required.filter(file => !files.includes(file))if (missing.length) {throw new Error(`构建产物缺失: ${missing.join(', ')}`)}// 检查文件大小const stats = await Promise.all(files.map(async file => ({file,size: (await fs.stat(`./dist/${file}`)).size})))// 超出限制告警const limit = 1024 * 1024 // 1MBstats.forEach(({ file, size }) => {if (size > limit) {console.warn(`文件过大: ${file} (${(size / 1024 / 1024).toFixed(2)}MB)`)}})
}

2. 环境配置

然后是规范的环境配置管理:

// config/index.js
const configs = {dev: {api: 'http://dev-api.example.com',cdn: 'http://dev-cdn.example.com',features: {logger: true,mock: true}},test: {api: 'http://test-api.example.com',cdn: 'http://test-cdn.example.com',features: {logger: true,mock: false}},prod: {api: 'https://api.example.com',cdn: 'https://cdn.example.com',features: {logger: false,mock: false}}
}// 环境变量注入
function injectEnv(env) {const config = configs[env]// 写入环境变量文件const content = Object.entries(config).map(([key, value]) => `VITE_${key.toUpperCase()}=${JSON.stringify(value)}`).join('\n')fs.writeFileSync('.env.local', content)
}// 环境变量验证
function validateEnv() {const required = ['VITE_API', 'VITE_CDN']const missing = required.filter(key => !process.env[key])if (missing.length) {throw new Error(`环境变量缺失: ${missing.join(', ')}`)}
}

3. 自动化部署

最关键的是自动化部署流程:

# .github/workflows/deploy.yml
name: Deploy
on:push:branches: [main, test]pull_request:branches: [main]jobs:deploy:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v2- name: Setup Node.jsuses: actions/setup-node@v2with:node-version: '16'- name: Install Dependenciesrun: npm ci- name: Type Checkrun: npm run type-check- name: Testrun: npm test- name: Buildrun: |if [[ $GITHUB_REF == refs/heads/main ]]; thennpm run build:prodelif [[ $GITHUB_REF == refs/heads/test ]]; thennpm run build:testfi- name: Deployuses: azure/webapps-deploy@v2with:app-name: ${{ secrets.AZURE_WEBAPP_NAME }}publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}package: ./dist- name: Notifyif: always()uses: actions/github-script@v6with:script: |const { repo, owner } = context.repoconst run_id = context.runIdconst message = `部署 ${context.sha.slice(0, 7)} 完成分支: ${context.ref}状态: ${context.job.status}详情: https://github.com/${owner}/${repo}/actions/runs/${run_id}`await github.rest.issues.createComment({owner,repo,issue_number: context.issue.number,body: message})

4. 灰度发布

为了更安全的发布,我们实现了灰度发布机制:

// server/canary.js
class CanaryRelease {constructor(options = {}) {this.ratio = options.ratio || 0.1 // 灰度比例this.rules = options.rules || [] // 灰度规则this.versions = new Map() // 版本映射}// 添加新版本addVersion(version, url) {this.versions.set(version, url)}// 获取用户版本getVersion(req) {// 优先匹配规则for (const rule of this.rules) {if (rule.test(req)) {return rule.version}}// 按比例灰度const random = Math.random()if (random < this.ratio) {return Array.from(this.versions.keys()).pop() // 最新版本}return Array.from(this.versions.keys())[0] // 稳定版本}// 中间件middleware() {return (req, res, next) => {const version = this.getVersion(req)const url = this.versions.get(version)if (url) {res.redirect(url)} else {next()}}}
}// 使用示例
const canary = new CanaryRelease({ratio: 0.2,rules: [{test: req => req.query.version === 'new',version: 'v2'},{test: req => req.cookies.beta === 'true',version: 'v2'}]
})canary.addVersion('v1', 'https://stable.example.com')
canary.addVersion('v2', 'https://canary.example.com')app.use(canary.middleware())

实践效果

通过这套自动化部署流程:

  • 部署时间从 1 小时减少到 5 分钟
  • 人工操作失误完全消除
  • 发布过程可追溯、可回滚
  • 新版本平滑过渡,用户无感知

最让我印象深刻的是测试同学的反馈:"现在再也不用担心环境被搞混了!"

经验总结

前端部署就像是一条生产线,需要严格的流程和质量控制。关键是要:

环境隔离 - 不同环境配置要严格分开流程自动化 - 减少人工操作降低风险质量把控 - 层层把关确保代码质量监控反馈 - 及时发现和解决问题

写在最后

前端部署不仅仅是把代码放到服务器上,而是一个需要精心设计的完整流程。就像那句话说的:"磨刀不误砍柴工",投入时间建设自动化流程,最终会让团队受益良多。

有什么问题欢迎在评论区讨论,让我们一起探讨前端部署的最佳实践!

如果觉得有帮助,别忘了点赞关注,我会继续分享更多实战经验~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/491802.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyTorch3D 可视化

PyTorch3D是非常好用的3D工具库。但是PyTorch3D对于可用于debug&#xff08;例如调整cameras参数&#xff09;的可视化工具并没有进行系统的介绍。这篇文章主要是想介绍我觉得非常使用的PyTorch3D可视化工具。 1. 新建一个Mesh 从hugging face上下载一个glb文件&#xff0c;例…

RabbitMQ的核心组件有哪些?

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ的核心组件有哪些&#xff1f;】面试题。希望对大家有帮助&#xff1b; RabbitMQ的核心组件有哪些&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ是一个开源的消息代理&#xff08;Messag…

SM4笔记整理

文章目录 1. 介绍2. 算法定义3. 迭代运算3.1 轮函数F3.2 合成置换T 4. SM4秘钥生成4.1 具体步骤4.2 系统参数FK4.2 固定参数CK 5. 参考资料 以下内容为信息安全开发过程中&#xff0c;SM4对称加密算法的笔记。 对称加密算法汇总介绍&#xff1a;对称加密算法和模式 1. 介绍 …

如何使用Git or SVN--可视化工具

不会吧 现在还有人不会Git可视化工具 &#xff0c;作为一个从命令行转为可视化的开发者&#xff0c;深知这个可视化工具的重要性&#xff0c;之前在命令行去维护我们的工程是一个很头疼的事情 &#xff0c;后面也就有了可视化工具&#xff0c;市面上的工具的教程都不是很详细哥…

基于Clinical BERT的医疗知识图谱自动化构建方法,双层对比框架

基于Clinical BERT的医疗知识图谱自动化构建方法&#xff0c;双层对比框架 论文大纲理解1. 确认目标2. 目标-手段分析3. 实现步骤4. 金手指分析 全流程核心模式核心模式提取压缩后的系统描述核心创新点 数据分析第一步&#xff1a;数据收集第二步&#xff1a;规律挖掘第三步&am…

《Time Ghost》的制作:使用 DOTS ECS 制作更为复杂的大型环境

*基于 Unity 6 引擎制作的 demo 《Time Ghost》 开始《Time Ghost》项目时的目标之一是提升在 Unity 中构建大型户外环境的构建标准。为了实现这一目标&#xff0c;我们要有处理更为复杂的场景的能力、有足够的工具支持&#xff0c;同时它对引擎的核心图形、光照、后处理、渲染…

华为大数据_unittest单元测试框架解析与应用

一、引言 随着软件开发的复杂度日益增加&#xff0c;单元测试在软件质量保证体系中扮演着越来越重要的角色。unittest作为Python的标准单元测试框架&#xff0c;以其简单、易用和强大的特性&#xff0c;受到了广大开发者的青睐。本文旨在深入解析unittest框架的核心原理&#…

修改uniapp下拉刷新圆圈颜色

直接看图 修改前就是常规的绿色 自定义更符合我们的软件 直接说方法 修改 在App.vue的style样式里添加一行 .uni-page-refresh--refreshing .uni-page-refresh__path{stroke:#FF2442; }我是通过 不执行 uni.stopPullDownRefresh(); 下拉刷新 之后通过F12看出来的 希望可以帮…

大屏开源项目go-view二次开发3----象形柱图控件(C#)

环境搭建参考&#xff1a; 大屏开源项目go-view二次开发1----环境搭建(C#)-CSDN博客 要做的象形柱图控件最终效果如下图&#xff1a; 其实这个控件我前面的文章也介绍过&#xff0c;不过是用wpf做的&#xff0c;链接如下&#xff1a; wpf利用Microsoft.Web.WebView2显示html…

MAC虚拟机上安装WDA环境

MAC虚拟机上安装WDA环境 一、MAC虚拟机切换root权限二、macOS上安装xcode若你的macOS系统可以在appstore下载安装若你安装的macOS系统版本太低&#xff0c;无法在appstore上安装xcode 三、macOS上安装WebDriverAgent四、使用xcode配置WDA安装到手机上高版本系统支持 一、MAC虚拟…

解决 Git Permission denied 问题

前言 push项目时出现gitgithub.com: Permission denied (publickey). fatal: Could not read from remote repository.Please make sure you have the correct access rights and the repository exists.出现这个问题表示你在尝试将本地代码推送到GitHub时&#xff0c;没有提供…

【工具】linux matlab 的使用

问题1 - 复制图表 在使用linux matlab画图后&#xff0c;无法保存figure。 例如在windows下 但是在linux下并没有这个“Copy Figure”的选项。 这是因为 “ The Copy Figure option is not available on Linux systems. Use the programmatic alternative.” 解决方案&…

Oracle最佳实践-优化硬解析

前段时间参加oracle CAB&#xff0c;oracle高级服务部门做了一个数据库最佳实践的报告&#xff0c;其中就有一项就是解决未使用绑定变量但执行次数很多的SQL&#xff1b; 对于一个数据库来说如果不知道该如何优化&#xff0c;那么最简单最有效的优化就是减少硬解析&#xff0c;…

【开源免费】基于SpringBoot+Vue.JS在线竞拍系统(JAVA毕业设计)

本文项目编号 T 013 &#xff0c;文末自助获取源码 \color{red}{T013&#xff0c;文末自助获取源码} T013&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

socket编程UDP-实现滑动窗口机制与累积确认GBN

在下面博客中&#xff0c;我介绍了利用UDP模拟TCP连接、按数据包发送文件的过程&#xff0c;并附上完整源码。 socket编程UDP-文件传输&模拟TCP建立连接脱离连接&#xff08;进阶篇&#xff09;_udp socket发送-CSDN博客 下面博客实现了停等机制。 socket编程UDP-实现停…

【现代服务端架构】传统服务器 对比 Serverless

在现代开发中&#xff0c;选择合适的架构是至关重要的。两种非常常见的架构模式分别是 传统服务器架构 和 Serverless。它们各有优缺点&#xff0c;适合不同的应用场景。今天&#xff0c;我就带大家一起对比这两种架构&#xff0c;看看它们的差异&#xff0c;并且帮助你选择最适…

概率论得学习和整理24:EXCEL的各种图形,统计图形

目录 0 EXCEL的各种图形&#xff0c;统计图形 1 统计图形 / 直方图 / 其实叫 频度图 hist最合适(用原始数据直接作图) 1.1 什么是频度图 1.2 如何创建频度图&#xff0c;一般是只选中1列数据&#xff08;1个数组&#xff09; 1.3 如何修改频度图的宽度 1.4 hist图的一个特…

【第三节】Git 基本操作指南

目录 前言 一、获取与创建项目 1.1 git init 1.2 git clone 二、基本快照操作 2.1 git add 2.2 git status 2.3 git diff 2.4 git commit 2.5 git reset HEAD 三、 文件管理 3.1 git rm 3.2 git mv 四、Git 文件状态 5.1 工作目录 5.2 暂存区 5.3 本地仓库 5…

el-table 多表头+跨行跨列案例

效果&#xff1a; 代码&#xff1a; index.vue <template><div class"my-table"><el-tablev-loading"table.loading":data"table.data"bordersize"mini":header-cell-style"headerCellStyle":span-method&qu…

华为FreeBuds Pro 4丢了如何找回?(附查找功能使用方法)

华为FreeBuds Pro 4查找到底怎么用&#xff1f;华为FreeBuds Pro 4有星闪精确查找和离线查找&#xff0c;离线查找功能涵盖播放铃声、导航定位、星闪精确查找、上线通知、丢失模式、遗落提醒等。星闪精确查找是离线查找的子功能&#xff0c;当前仅华为FreeBuds Pro 4充电盒支持…