记一次k8s下容器启动失败,容器无日志问题排查

问题

背景

本地开发时,某应用增加logback-spring.xml配置文件,加入必要的依赖:

<dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>8.0</version>
</dependency>

本地可以正常启动。

但是发布到测试环境后,容器启动失败
在这里插入图片描述
其状态CrashLoopBackOff,不管是通过执行kubectl logs <pod> -n <ns>命令查看日志,还是在KubeSphere查看容器日志,都没有任何日志输出。

排查

KubeSphere看到容器的状态为
在这里插入图片描述
容器的事件:
在这里插入图片描述
信息如下:

Warning  Unhealthy  75s (x10 over 5m15s)  kubelet            Startup probe failed: Get "http://172.20.0.95:8012/health": dial tcp 172.20.0.95:8012: connect: connection refused
Back-off restarting failed container fileview in pod 

使用k9s查看日志:
在这里插入图片描述
各种无头苍蝇乱排查:

  • 删除容器,自动重启,不行;
  • 修改探针时间,不行;
  • kubectl describe pod <pod_name> -n <ns>,没看出问题。

总之,看不到任何有效信息,无法定位问题。

workaround

通过KubeSphere,打开【应用负载】-【工作负载】,搜索【fileview】,【编辑YAML】,使用一个有效的之前的镜像版本,即回滚:
在这里插入图片描述
版本号,在Harbor镜像仓库里,根据代码提交和流水线构建日期,选择一个变更前的版本。然后删除容器组里的现有容器,会自动重启。

然后重启成功!!

说明还是由于代码提交导致测试环境里的容器启动失败。

Git Commit

代码提交记录如下:
在这里插入图片描述
新增的配置文件logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位毫秒。当scan为true时,此才能属性生效。默认时间间隔为30s。 -->
<configuration scan="true" scanPeriod="30 seconds"><!--  彩色日志依赖  --><conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/><conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/><!-- 线上日志文件路径--><property name="JSON_FILE_PATH" value="/logs/service/fileview"/><!--  控制台彩色日志格式  --><property name="CONSOLE_LOG_PATTERN"value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %green([traceId=%X{traceId} spanId=%X{spanId} sampled=%X{sampled}]) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><!--  日志文件日志格式  --><property name="FILE_LOG_PATTERN"value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} [%X{traceId}] ${PID:- } --- [%15t] %-40.40logger{39}:[%5.5line] - %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><!--  json日志格式  --><property name="JSON_LOG_PATTERN"value='{"localtime": "%date{yyyy-MM-dd HH:mm:ss.SSS}","level": "%level","pid": "${PID:-}","thread": "%thread","traceId": "%X{traceId}","class": "%logger","method": "%method","line": "%line","message": "%message","stack":"%wEx"}'/><!-- 控制台输出 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>UTF-8</charset></encoder></appender><!-- 以JSON格式写入log文件 --><appender name="JSON_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!--日志文件输出的文件名--><FileNamePattern>${JSON_FILE_PATH}/log_%d{yyyyMMdd}_%i.log</FileNamePattern><!--日志文件最大大小--><maxFileSize>200MB</maxFileSize><!--日志文件保留天数--><maxHistory>5</maxHistory><!-- 每个日志文件到200MB的时候开始切分,最多保留5天,但最大到5GB,哪怕没到5天也要删除多余的日志 --><totalSizeCap>5GB</totalSizeCap><!--启动项目触发删除检测  --><cleanHistoryOnStart>true</cleanHistoryOnStart></rollingPolicy><encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"><providers><pattern><pattern>${JSON_LOG_PATTERN}</pattern></pattern></providers></encoder></appender><!--本地调试打印控制台彩色日志--><root level="INFO"><appender-ref ref="CONSOLE"/></root><springProfile name="dev,uat,test,pre,gray,future,prd,prod"><root level="INFO"><appender-ref ref="JSON_FILE"/></root></springProfile>
</configuration>

在本地开发环境Debug模式启动应用时,可以正常启动。

另外,上面这个配置文件,引入一个LoggingEventCompositeJsonEncoder,因此需要引入logstash-logback-encoder依赖。

但没有注意到:Spring Boot并没有加载此文件logback-spring.xml,也没有重视这一点。

事实上,针对这次提交涉及的4个文件,到底是哪个改动引发问题,定位时,也耗费掉不少时间。

只是这里直接将问题定位为logback配置文件。

Docker

既然本地启动成功,测试环境启动失败。能不能在本地模拟测试环境?

于是花费一点时间,在Windows开发环境下安装Docker Desktop。

IDEA在某个版本后自带Docker开发插件:
在这里插入图片描述
稍微摸索一下,就知道如何使用Docker插件,填写镜像地址,点击Pull接口
在这里插入图片描述
镜像拉取成功后,点击右侧的Create Container:
在这里插入图片描述
容器启动失败,报错日志:

Logging system failed to initialize using configuration from 'null'
2024-12-29T08:31:31.991172257Z java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Could not create component [encoder] of type [net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder] java.lang.ClassNotFoundException: net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder
2024-12-29T08:31:31.991194340Z ERROR in ch.qos.logback.core.joran.spi.Interpreter@36:24 - no applicable action for [providers], current ElementPath  is [[configuration][appender][encoder][providers]]
2024-12-29T08:31:31.991197106Z ERROR in ch.qos.logback.core.joran.spi.Interpreter@37:26 - no applicable action for [pattern], current ElementPath  is [[configuration][appender][encoder][providers][pattern]]
2024-12-29T08:31:31.991199506Z ERROR in ch.qos.logback.core.joran.spi.Interpreter@38:30 - no applicable action for [pattern], current ElementPath  is [[configuration][appender][encoder][providers][pattern][pattern]]
2024-12-29T08:31:31.991201798Z ERROR in ch.qos.logback.core.ConsoleAppender[JSON] - No encoder set for the appender named "JSON".

这说明什么??

说明在以容器方式启动应用时,应用加载logback配置文件失败。

此时,才开始重视前文提到的:应用启动时,Spring Boot并没有加载logback-spring.xml文件。

logback

现在来解决,为啥本地开发环境Debug模式启动应用,Spring Boot为啥没有加载logback-spring.xml文件。

应用的目录结构如下:
在这里插入图片描述
因为application.properties文件在config目录下,于是不带思考地,把logback-spring.xml文件也放在config目录下。

logback-spring.xml文件移到resources目录下,Spring Boot还是不能加载logback-spring.xml文件。

把文件重命名为为logback.xml,终于可以加载。

JDK版本

本地启动,应用不再报错,发布到测试环境,容器启动还是失败。

不过,终于可以看到容器日志!!!具体的报错信息(经过换行处理,方便阅读):

Exception in thread "main" java.lang.UnsupportedClassVersionError: 
net/logstash/logback/encoder/LoggingEventCompositeJsonEncoder has been compiled by a more recent version of the Java Runtime (class file version 55.0), 
this version of the Java Runtime only recognizes class file versions up to 52.0

很熟悉的报错,是不是:

  • 52.0对应于JDK 8版本
  • 55.0对应于JDK 11版本

此应用的Dockerfile如下:

FROM harbor.aaaa.com/library/fileview:4.4.0-betaADD target/kkFileView-*.tar.gz /opt/
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-4.4.0-beta/bin
ENTRYPOINT ["java", "-Dfile.encoding=UTF-8", "-Dspring.config.location=/opt/kkFileView-4.4.0-beta/config/application.properties", "-jar", "/opt/kkFileView-4.4.0-beta/bin/kkFileView-4.4.0-beta.jar"]

基础镜像是fileview:4.4.0-beta,看不出Java版本,默认应该就是JDK 8。

登录到Harbor镜像仓库,查看镜像信息,果然是JDK8:

{"ArgsEscaped": true,"Cmd": ["/bin/bash"],"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk1.8.0_251/bin","JAVA_HOME=/usr/local/jdk1.8.0_251","CLASSPATH=/usr/local/jdk1.8.0_251/lib/dt.jar:/usr/local/jdk1.8.0_251/lib/tools.jar","LANG=zh_CN.UTF-8","LC_ALL=zh_CN.UTF-8"],"Labels": {"org.opencontainers.image.ref.name": "ubuntu","org.opencontainers.image.version": "20.04"}
}

其构建历史(无关信息)为:

ARG RELEASE
ARG LAUNCHPAD_BUILD_ARCH
LABEL org.opencontainers.image.ref.name=ubuntu
LABEL org.opencontainers.image.version=20.04
ADD file:e7cff353f027ecf0a2cb1cdd51714de3b083a11a0d965f104489f9a7e6925056 in /
CMD ["/bin/bash"]
COPY fonts/* /usr/share/fonts/chinese/ # buildkit
COPY server-jre-8u251-linux-x64.tar.gz /tmp/server-jre-8u251-linux-x64.tar.gz # buildkit
COPY LibreOffice_7.5.3.2_Linux_x86-64_deb.tar.gz /tmp/libreoffice_deb.tar.gz # buildkit
RUN RUN apt-get clean && apt-get update && sed -i 's/http:\/\/archive.ubuntu.com/https:\/\/mirrors.aliyun.com/g' /etc/apt/sources.list && sed -i 's/# deb/deb/g' /etc/apt/sources.list && apt-get install -y --reinstall ca-certificates && apt-get clean && apt-get update && apt-get install -y locales language-pack-zh-hans && localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8 && locale-gen zh_CN.UTF-8 && export DEBIAN_FRONTEND=noninteractive && apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && apt-get install -y fontconfig ttf-mscorefonts-installer ttf-wqy-microhei ttf-wqy-zenhei xfonts-wqy && apt-get install -y wget && cd /tmp && tar -zxf /tmp/server-jre-8u251-linux-x64.tar.gz && mv /tmp/jdk1.8.0_251 /usr/local/ && apt-get install -y libxrender1 libxinerama1 libxt6 libxext-dev libfreetype6-dev libcairo2 libcups2 libx11-xcb1 libnss3 && tar -zxf /tmp/libreoffice_deb.tar.gz && cd /tmp/LibreOffice_7.5.3.2_Linux_x86-64_deb/DEBS && dpkg -i *.deb && rm -rf /tmp/* && rm -rf /var/lib/apt/lists/* && cd /usr/share/fonts/chinese && mkfontscale && mkfontdir && fc-cache -fv # buildkit
ENV JAVA_HOME=/usr/local/jdk1.8.0_251
ENV CLASSPATH=/usr/local/jdk1.8.0_251/lib/dt.jar:/usr/local/jdk1.8.0_251/lib/tools.jar
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/jdk1.8.0_251/bin
ENV LANG=zh_CN.UTF-8
ENV LC_ALL=zh_CN.UTF-8
CMD ["/bin/bash"]

本地开发环境切换到JDK 8,debug模式启动应用,果然启动报错:
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.impl.StaticLoggerBinder

但是,为啥和测试环境的报错信息不一样呢??

org.slf4j.impl.StaticLoggerBinder这个类是在logback-classic-1.2.3.jar里引入的:
在这里插入图片描述
不管了,开发任务太重了。没有时间去仔细探究。

降低logstash-logback-encoder版本8.0到6.6:

<dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>6.6</version>
</dependency>

不再报错:Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class org.slf4j.impl.StaticLoggerBinder

提交代码,触发流水线构建,发布到测试环境,启动成功。

logback.xml还是logback-spring.xml

问题虽然解决。

但是还留有不少疑问,此应用分明是一个Spring-Boot应用啊,为啥不能加载logback-spring.xml
在这里插入图片描述
可以加载logback.xml
在这里插入图片描述
另外,虽然可以加载文件,但是应用启动时会打印出一些ERROR日志:
在这里插入图片描述
报错日志如下:

13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@72:65 - no applicable action for [springProfile], current ElementPath  is [[configuration][springProfile]]
13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@73:28 - no applicable action for [root], current ElementPath  is [[configuration][springProfile][root]]
13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@74:39 - no applicable action for [appender-ref], current ElementPath  is [[configuration][springProfile][root][appender-ref]]
13:09:22,777 |-ERROR in ch.qos.logback.core.joran.spi.Interpreter@75:44 - no applicable action for [appender-ref], current ElementPath  is [[configuration][springProfile][root][appender-ref]]

请教DeepSeek,给出的一个比较靠谱的解释是这样的:
在这里插入图片描述

反思

  1. Q:为啥本地可以启动成功,测试环境不行?
    A:使用的JDK版本不一样。只有这一个服务最特殊,使用JDK 8版本,其他应用都是使用OpenJDK 11版本。
  2. Q:为啥测试环境的报错信息是UnsupportedClassVersionError,也就是使用的JDK版本引入一个更高JDK版本编译的依赖;而本地开发环境的报错是:NoClassDefFoundError?
    A:不知道。
  3. Q:为啥不能加载logback-spring.xml文件?可以加载logback.xml文件,但是有报错信息:no applicable action for [springProfile]
    A:唯一(有可能的)合理的解释,这依旧是一个Spring应用,虽然放在根目录下面的启动类,有@SpringBootApplication注解。

    Spring应用默认加载logback.xml文件,Spring Boot应用默认加载logback-spring.xml文件?让Spring去加载logback-spring.xml文件(经过重命名处理后可以加载logback.xml,但是文件里依旧有一些springProfile配置项),于是会报错no applicable action for [springProfile]。好像可以自圆其说。
  4. Q:Spring应用和Spring Boot应用的区别是什么?分界线是什么?@SpringBootApplication注解吗?
    A:不知道,此问题并不是没有意义的。
    在这里插入图片描述

参考

  • ChatGPT
  • DeepSeek

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

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

相关文章

【PPTist】批注、选择窗格

前言&#xff1a;本篇文章研究批注和选择窗格两个小功能 一、批注 批注功能就是介个小图标 点击可以为当前页的幻灯片添加批注&#xff0c;还能删除之前的批注 如果我们增加了登录功能&#xff0c;还可以在批注上显示当前的用户名和头像&#xff0c;不过现在是写死的。 左侧…

使用Paddledetection进行模型训练【Part1:环境配置】

目录 写作目的 安装文档 环境要求 版本依赖关系 安装说明 写作目的 方便大家进行模型训练前的环境配置。 安装文档 环境要求 PaddlePaddle &#xff1e;&#xff1d;2.3.2OS 64位操作系统Python 3(3.5.1/3.6/3.7/3.8/3.9/3.10)&#xff0c;64位版本pip/pip3(9.0.1)&am…

C++ scanf

1.scanf概念解释&#xff1a; C语言兼容C语言中的基本语句语法,scanf语句是C语言中的输入语句,在C语言环境中也可以使用。对于大数据的输入使用scanf比C的输入cin效率高、速度快。 scanf称为格式输入函数,其关键字最末一个字母f即为是格式"(format)之意",其意义是按指…

数学建模入门——描述性统计分析

摘要&#xff1a;本篇博客主要讲解了数学建模入门的描述性统计分析&#xff0c;包括基本统计量的计算、数据的分布形态、数据可视化和相关性分析。 往期回顾&#xff1a; 数学建模入门——建模流程-CSDN博客 数学建模入门——数据预处理&#xff08;全&#xff09;-CSDN博客 …

30、论文阅读:基于小波的傅里叶信息交互与频率扩散调整的水下图像恢复

Wavelet-based Fourier Information Interaction with Frequency Diffusion Adjustment for Underwater Image Restoration 摘要介绍相关工作水下图像增强扩散模型 论文方法整体架构离散小波变换与傅里叶变换频率初步增强Wide Transformer BlockSpatial-Frequency Fusion Block…

Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s

前言&#xff1a;纯个人记录使用。 搭建 Zero to JupyterHub with Kubernetes 上篇 - Kubernetes 离线二进制部署。搭建 Zero to JupyterHub with Kubernetes 中篇 - Kubernetes 常规使用记录。搭建 Zero to JupyterHub with Kubernetes 下篇 - Jupyterhub on k8s。 官方文档…

Matlab回归预测大合集(不定期更新)-188

截至2025-1-2更新 1.BP神经网络多元回归预测&#xff08;多输入单输出&#xff09; 2.RBF神经网络多元回归预测&#xff08;多输入单输出&#xff09; 3.RF随机森林多元回归预测&#xff08;多输入单输出&#xff09; 4.CNN卷积神经网络多元回归预测&#xff08;多输入单输…

【读书与思考】历史是一个好东西

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】【读书与思考】 导言 以后《AI日记》专栏我想专注于 AI 相关的学习、成长和工作等。而与 AI 无关的一些读书、思考和闲聊&#xff0c;我打算写到这里&#xff0c;我会尽量控制自己少想和少写。 下图的一些感想…

Git使用mirror备份和恢复

Git使用mirror备份和恢复 使用到的命令总结备份1.进入指定代码仓库&#xff0c;拷贝地址2.进入要备份到的文件夹&#xff0c;右键打开git命令行&#xff0c;输入以下命令3.命令执行完成后会生成一个新文件夹 恢复1.在gitee上创建代码仓库![请添加图片描述](https://i-blog.csdn…

人工智能的可解释性:从黑箱到透明

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​​ ​ 人工智能&#xff08;AI&#xff09;的快速发展和广泛应用&#xff0c;带来了许多革新的成果&#xff0c;但也引发了对其透明性和可解释…

Nacos注册中心介绍及部署

文章目录 Nacos注册中心介绍及部署1. 注册中心简介2. 注册中心原理3. Nacos部署-基于Docker3.1 Nacos官网下载3.2 基础数据信息3.3 环境信息3.4 docker安装部署3.5 测试3.5 测试 Nacos注册中心介绍及部署 1. 注册中心简介 Spring Cloud注册中心是Spring Cloud微服务架构中的一…

Nginx与frp结合实现局域网和公网的双重https服务

背景&#xff1a; 因为局域网内架设了 tiddlywiki、 Nextcloud 等服务&#xff0c;同时也把公司的网站架设在了本地&#xff0c;为了实现局域网直接在局域网内访问&#xff0c;而外部访问通过frps服务器作为反向代理的目的&#xff0c;才有此内容。 实现的效果如下图琐事 不喜欢…

zephyr移植到STM32

Zephy如何移植到单片机 1. Window下搭建开发环境1.1 安装Choncolatey1.2 安装相关依赖1.3创建虚拟python环境1.4 安装west1.4.1 使用 pip 安装 west1.4.2 检查 west 安装路径1.4.3 将 Scripts路径添加到环境变量1.4.4 验证安装 1.5 获取zephyr源码和[安装python](https://so.cs…

【分糖果——DFS】

题目 代码1 #include <bits/stdc.h> using namespace std; set<string> s; void dfs(int num1, int num2, int u, string ans) {if (u 7){if (num1 num2 > 5)return;ans (char)((num1) * 17 num2);s.insert(ans);return;}for (int i 0; i < num1; i){f…

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码

【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码 一、前言 官方文档关于屏幕录制的API和示例介绍获取简单和突兀。使用起来会让上手程度变高。所以特意开篇文章&#xff0c;讲解屏幕录制的使用。官方文档参见&#xff1a;使用AVScreenCaptureRecorder录屏写文件(ArkTS) 二、方…

解决在VS2019/2022中编译c++项目报错fatal error C1189: #error : “No Target Architecture“

解决在VS2019/2022中编译c项目报错fatal error C1189: #error : “No Target Architecture” 报错原因 在winnt.h中&#xff0c;不言而喻&#xff0c;一目了然&#xff1a; 代码节选&#xff1a; #if defined(_AMD64_) || defined(_X86_) #define PROBE_ALIGNMENT( _s ) TY…

Python教程丨Python环境搭建 (含IDE安装)——保姆级教程!

工欲善其事&#xff0c;必先利其器。 学习Python的第一步不要再加收藏夹了&#xff01;提高执行力&#xff0c;先给自己装好Python。 1. Python 下载 1.1. 下载安装包 既然要下载Python&#xff0c;我们直接进入python官网下载即可 Python 官网&#xff1a;Welcome to Pyt…

实现AVL树

目录 AVL树概念 AVL树结构 AVL树插入 LL型 - 右单旋 RR型 - 左单旋 LR型 - 左右双旋 RL型 - 右左双旋 插入代码实现 AVL树测试 附AVL树实现完整代码 AVL树概念 前面的博客介绍了搜索二叉树&#xff0c;二叉搜索树-CSDN博客 在某些特定的情况下&#xff0c;⼆叉搜索树…

极客说|微软 Phi 系列小模型和多模态小模型

作者&#xff1a;胡平 - 微软云人工智能高级专家 「极客说」 是一档专注 AI 时代开发者分享的专栏&#xff0c;我们邀请来自微软以及技术社区专家&#xff0c;带来最前沿的技术干货与实践经验。在这里&#xff0c;您将看到深度教程、最佳实践和创新解决方案。关注「极客说」&am…

React+redux项目搭建流程

1.创建项目 create-react-app my-project --template typescript // 创建项目并使用typescript2.去除掉没用的文件夹&#xff0c;只保留部分有用的文件 3.项目配置&#xff1a; 配置项目的icon 配置项目的标题 配置项目的别名等&#xff08;craco.config.ts&…