《拿下奇怪的前端报错》:nvm不可用报错`GLIBC_2.27‘‘GLIBCXX_3.4.20‘not Found?+ 使用docker构建多个前端项目实践
有些前端的小伙伴可能会好奇,nvm是什么?这里接简单介绍下,它是一个Nodejs版本管理工具。为什么需要它呢?当然是需要多个Nodejs版本的时候,那什么时候需要多个Nodejs版本?那肯定是在有点年头的公司了,例如vue2的很多依赖都是在Nodejs14年代的,如果你升级到Node20,那很可能会报错。如果你用vite创建新项目,那也肯定是没法在Node14下运行。(如果你问为啥要Nodejs,欢迎留言,或者看一部它的纪录片哈)
迭代过快虽然能够享受到各种新科技,但对于很多公司来说,去适配nodejs版本也是不太值得投入的成本。ε=(´ο`*)))唉,想想前端就累呀
报错信息具体内容
# node -v
node: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by node)
node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by node)
node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by node)
node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.28' not found (required by node)
node: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by node)
nodejs都不可用,更别说构建了,如果构建不出东西,在这个依赖框架的年代,就相当于白干啊!突然怀念jquery的时代了,(#^.^#)
触发场景
- 有老的vue项目,需要nodejs14 (这个必须的,18+就构建不了!)
- 有新的vue3项目,需要nodejs20+ (vite需要的,ε=(´ο`*)))唉,自己开发是挺爽,但没想到CI这里出问题了哈)
- 必须要jenkins上部署和构建(jenkins跑在linux上,之前我被windows server版docker搞的头发掉了一大撮)
- 构建物必须是一个docker镜像,这几个项目放在一个镜像(就是要一次构建多个项目)
好像上面是这个时代比较通用的了,于是便很自然的安装了nvm,构建不同项目之前,用nvm切换下。
问题分析
但是,当我构建vue3项目是,就遇到上面的报错了。呃,搜索一通,么得什么头绪,我发现切回去node16就可以了,啊,竟然是版本问题,后面发现是宿主机的centos版本太低了,我的天!我没想到一个前端竟然遇到这个问题,也算是长姿势了!
于是这时候就有个解决办法了,那就是让运维的部署点高版本的centos吧!提了个需求,但不知道何时才能实现,等等等
解决办法
看到这里,问题大概就是找到了,也可以解决了:那就是升级centos版本
解决问题思路扩展
在docker容器内构建项目
但是我从第一性原理开始想,为啥我需要安装这个Nodejs呢?既然产出物是前端代码,部署又不需要这个nodejs(只需要一个nginx镜像+那些构建物),构建的时候能不能使用Docker构建,只要用不同的镜像去构建,不就可以了?说干就干。
下面是Dockerfile构建脚本: 阶段1构建,注意不同的项目修改自己node:版本 (这里用到了docker的多阶段构建,想了解的可以自己去研究,或许后期我会抽空介绍它的好处)
# 构建阶段
FROM node:20.16-alpine as builder# 设置工作目录
WORKDIR /app# 复制package.json和package-lock.json(如果存在)
COPY package*.json ./# 安装项目依赖
RUN npm install# 复制项目文件到工作目录
COPY . .# 构建应用
RUN npm run build
这个构建的产出物在镜像内的/app/dist,如果是直接docker部署,可以使用第二个stage直接复制到新的镜像中,但此时为考虑到某些场景需要提取出这个目录,就需要一个辅助的nodejs方法:
1. 构建
2. 启动容器
3. 复制到目标目录
启动临时容器复制到宿主机目录
一个全功能辅助的nodejs脚本
下面这个方法是一个build.cjs脚本内容,构建的时候,定义好需要构建的模块,然后node build.cjs就可以了,这里不展开。
function buildRunCopy(imageName, dockerfileDir, containerDist, outputDir) {// 生成容器名称const containerName = `container-${imageName}`;// 构建 Dockerfile 路径和输出目录的绝对路径const dockerfilePath = path.resolve(dockerfileDir, "Dockerfile");const hostDir = path.resolve(outputDir);try {// 创建宿主机目录(如果不存在的话)if (!fs.existsSync(hostDir)) {fs.mkdirSync(hostDir, { recursive: true });}// 构建 Docker 镜像console.log("Building Docker image...");execSync(`docker build -t ${imageName} -f ${dockerfilePath} ${dockerfileDir}`,{stdio: "inherit",cwd: dockerfileDir,});console.log("Docker image built successfully.");// 运行 Docker 容器console.log("Running Docker container...");execSync(`docker run --name ${containerName} -d ${imageName}`);console.log("Docker container started successfully.");// 复制容器内的目录到宿主机目录execSync(`docker cp ${containerName}:/${containerDist} ${hostDir}`);console.log("Files copied successfully.");} catch (error) {console.error(`Error: ${error.message}`);throw error;} finally {// 停止并移除 Docker 容器try {console.log("Removing Docker container...");execSync(`docker rm -f ${containerName}`);console.log("Docker container removed successfully.");} catch (removeError) {console.error(`Error removing Docker container: ${removeError.message}`);}}
}
脚本函数用法举例
下面就是一个例子:将项目某个test-app下面的项目进行构建,并将其构建物从/app/dist复制到原项目下面的dist目录
// 构建 build.cjs const basePath = path.join(projectsBasePath, "test-app");const tmpDistFolder = path.join(basePath, "dist");console.info(`清理构建临时目录`);fs.rmSync(tmpDistFolder, { recursive: true, force: true });buildRunCopy("test-app", basePath, "/app/dist", basePath);
然后就可以实现使用docker构建项目了,宿主机的nodejs只需要跑这个脚本,构建过程用到的nodejs是来自于容器内的,想用啥版本直接修改Dockerfile文件就可了
看完记得活动下脖子,这算是我今天的前3.5个小时的总结了...
相关文章:
《拿下奇怪的前端报错》:nvm不可用报错`GLIBC_2.27‘‘GLIBCXX_3.4.20‘not Found?+ 使用docker构建多个前端项目实践
有些前端的小伙伴可能会好奇,nvm是什么?这里接简单介绍下,它是一个Nodejs版本管理工具。为什么需要它呢?当然是需要多个Nodejs版本的时候,那什么时候需要多个Nodejs版本?那肯定是在有点年头的公司了&#x…...
5.《DevOps》系列K8S部署CICD流水线之K8S通过Yaml部署GitLab
架构 服务器IP服务名称硬件配置192.168.1.100k8s-master8核、16G、120G192.168.1.101k8s-node18核、16G、120G192.168.1.102k8s-node28核、16G、120G192.168.1.103nfs2核、4G、500G操作系统:Rocky9.3 后续通过K8S部署Jenkins NFS的SC创建参考:2.《DevOps》系列K8S部署CICD流…...

[SAP ABAP] 创建数据库视图和维护视图
数据准备 学校表(ZDBT_SCH_437) 学生表(ZDBT_STU_437) 学校表(ZDBT_SCH_437)与学生表(ZDBT_STU_437)字段 学校表(ZDBT_SCH_437)与学生表(ZDBT_STU_437)行数据明细 1.创建数据库视图 使用SE11创建数据库视图 填写视图名称ZV_DATABASEV_437,点击创建按钮 选择数据库视…...
【最快最简单的排序 —— 桶排序算法】
最快最简单的排序 —— 桶排序算法 桶排序是一种排序算法,其工作原理是将数据分到有限数量的桶子里,然后对每个桶内的元素进行单独排序,最后依次把各个桶中的记录列出来。桶排序的效率取决于映射函数的选择和桶的数量。 桶排序适用于数据分…...

AI时代,服务器厂商能否打破薄利的命运?
文|刘俊宏 编|王一粟 AI大模型正在引发新一轮的“算力焦渴”。 近日,OpenAI刚发布的o1大模型再次刷新了大模型能力的上限。对比上一次迭代的版本,o1的推理能力全方位“吊打”了GPT-4o。更优秀的能力,来自与o1将思维…...
2024年9月python二级易错题和难题大全(附详细解析)(二)
2024年9月python二级易错题和难题大全(附详细解析)(二) 第1题第2题第3题第4题第5题第6题第7题第8题第9题第10题第11题第12题第13题第14题第15题第16题第17题第18题第19题第20题第1题 1、以下代码的输出结果是() x = 12 + 3 * ((5 * 8) - 14) // 6 print(x) A、25.0 B、6…...
4.结构型设计模式 - 第1回:引言与适配器模式 (Adapter Pattern) ——设计模式入门系列
一、引言 在现代软件开发中,设计模式是帮助我们解决复杂问题的工具,它们提供了在常见场景下重用已验证解决方案的途径。而结构型设计模式主要关注类与对象之间的组合方式,旨在通过增强灵活性和降低耦合度来改进代码的结构。 本次讨论的是结…...
解决mybatis plus 中 FastjsonTypeHandler无法正确反序列化List类型的问题
由于是根据自动映射类型,我们设置的字段类型是List 也就是反序列化的时候也只是用 FastjsonTypeHandler中的 Override protected Object parse(String json) { return JSON.parseObject(json, type); } 反序列化方法,这是type为List 反序列后我们并没…...

MacOS安装homebrew,jEnv,多版本JDK
1 安装homebrew homebrew官网 根据官网提示,运行安装命令 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"安装后,bash会提示执行两条命令 (echo; echo eval "$(/opt/homebrew/b…...

【HTTP】认识 URL 和 URL encode
文章目录 认识 URLURL 基本格式**带层次的文件路径****查询字符串****片段标识符** URL encode 认识 URL 计算机中非常重要的概念,并不仅仅是在 HTTP 中使用。用来描述一个网络资源所处的位置,全称“唯一资源定位符” URI 是“唯一资源标识符“严格的说…...

【AI学习笔记】初学机器学习西瓜书概要记录(二)常用的机器学习方法篇
初学机器学习西瓜书的概要记录(一)机器学习基础知识篇(已完结) 初学机器学习西瓜书的概要记录(二)常用的机器学习方法篇(持续更新) 初学机器学习西瓜书的概要记录(三)进阶知识篇(待更) 文字公式撰写不易&am…...
[SDX35+WCN6856]SDX35 + WCN6856 默认增加打包wifi配置hostapd_24g.conf和hostapd_5g.conf操作方法
SDX35 SDX35介绍 SDX35设备是一种多模调制解调器芯片,支持 4G/5G sub-6 技术。它是一个4nm芯片专为实现卓越的性能和能效而设计。它包括一个 1.9 GHz Cortex-A7 应用处理器。 SDX35主要特性 ■ 3GPP Rel. 17 with 5G Reduced Capability (RedCap) support. Backward compati…...

【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数
文章目录 什么是自动引用计数 内存管理/引用计数 概要 内存管理的思考方式 自己生成的对象,自己所持有 非自己生成的对象,自己也能持有 不再需要自己持有的对象时释放 无法释放非自己持有的对象 什么是自动引用计数 自动引用计数(AR…...

网络安全-LD_PRELOAD,请求劫持
目录 一、环境 二、开始做题 三、总结原理 四、如何防护 一、环境 我们这里用蚁剑自带的靶场第一关来解释 docker制作一下即可 二、开始做题 首先环境内很明显给我们已经写好了webshell 同样我们也可以访问到 我们使用这个蚁剑把这个webshell连上 我们发现命令不能执行&am…...
GO入门之值传递于引用(指针、内存地址)传递扫盲
GO入门之值传递于引用(指针、内存地址)传递扫盲 Go 语言中,值传递和引用(指针)传递是两个关键的概念。通过案例可以很好地展示两者的区别。 值传递与引用传递的区别: 值传递:传递的是变量的副…...

【渗透测试】-vulnhub源码框架漏洞-Os-hackNos-1
vulnhub源码框架漏洞中的CVE-2018-7600-Drupal 7.57 文章目录 前言 1.靶场搭建: 2.信息搜集: 主机探测: 端口扫描: 目录扫描: 3.分析: 4.步骤: 1.下载CVE-2018-7600的exp 2.执行exp: 3.写入木…...

sqli-lab靶场学习(三)——Less8-10(盲注、时间盲注)
Less8 第八关依然是先看一般状态 http://localhost/sqli-labs/Less-8/?id1 然后用单引号闭合: http://localhost/sqli-labs/Less-8/?id1 这关的问题在于报错是不显示,那没办法通过上篇文章的updatexml大法处理。对于这种情况,需要用“盲…...

Pybullet 安装过程
Pybullet 安装过程(windows) 1. 安装C编译工具2. 安装Pybullet 1. 安装C编译工具 pybullet 需要C编译套件,直接装之前检查下,要不会报缺少某版本MVSC的error,最好的方式是直接下载visual studio,直接按默认…...

Error when custom data is added to Azure OpenAI Service Deployment
题意:在向 Azure OpenAI 服务部署添加自定义数据时出现错误。 问题背景: I receive the following error when adding my custom data which is a .txt file (it doesnt matter whether I add it via Azure Cognitive Search, Azure Blob Storage, or F…...

libreoffice word转pdf
一、准备一个word文件 运行: cd /root libreoffice --headless --convert-to pdf --outdir /root/output doc1.docx 发现中文乱码: 此时我们需要给linux 上添加中文字体: centos7 添加中文字体 再次运行正常: libreoffice --h…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...