<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>工程化 on Saiga</title>
    <link>http://localhost:1313/categories/%E5%B7%A5%E7%A8%8B%E5%8C%96/</link>
    <description>Recent content in 工程化 on Saiga</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <managingEditor>wuwenzen@outlook.com (wuwj)</managingEditor>
    <webMaster>wuwenzen@outlook.com (wuwj)</webMaster>
    <lastBuildDate>Sat, 28 Sep 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="http://localhost:1313/categories/%E5%B7%A5%E7%A8%8B%E5%8C%96/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>写几个小脚本帮自己省时间：前端 CLI / 脚手架实践</title>
      <link>http://localhost:1313/posts/2024-09-28-cli-and-scaffolding-tools/</link>
      <pubDate>Sat, 28 Sep 2024 00:00:00 +0000</pubDate><author>wuwenzen@outlook.com (wuwj)</author>
      <guid>http://localhost:1313/posts/2024-09-28-cli-and-scaffolding-tools/</guid>
      <description>&lt;p&gt;有段时间我发现自己经常在做几件很机械的事：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;新建一个页面：建目录、复制模板、改标题、改路由&lt;/li&gt;&#xA;&lt;li&gt;加一个接口：建 service 文件、写类型、写请求封装&lt;/li&gt;&#xA;&lt;li&gt;搭一个模块：列表页 + 详情页 + 编辑页，一遍遍重复&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;于是索性写了一组小 CLI 工具，把这些动作变成命令行：&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;code&gt;npx fe-tools create-page&lt;/code&gt;&lt;br&gt;&#xA;&lt;code&gt;npx fe-tools create-api&lt;/code&gt;&lt;br&gt;&#xA;&lt;code&gt;npx fe-tools create-module&lt;/code&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;这篇文章就简单记录一下这几个脚本的思路。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;1-create-page新页面一条命令&#34;&gt;1. &lt;code&gt;create-page&lt;/code&gt;：新页面一条命令&lt;/h2&gt;&#xA;&lt;p&gt;很多中台项目新增页面的套路都差不多：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;在 &lt;code&gt;views&lt;/code&gt; 下建目录&lt;/li&gt;&#xA;&lt;li&gt;填一个基础骨架组件&lt;/li&gt;&#xA;&lt;li&gt;在路由里挂载&lt;/li&gt;&#xA;&lt;li&gt;有的还要加到菜单配置里&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;用 Node.js 写了一个 &lt;code&gt;create-page&lt;/code&gt; 命令：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;npx fe-tools create-page&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;命令执行后，做几件事：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;命令行交互询问：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;页面英文名（路由 path）&lt;/li&gt;&#xA;&lt;li&gt;页面中文标题&lt;/li&gt;&#xA;&lt;li&gt;页面类型：列表 / 表单 / 详情 / 组合&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;基于模板生成对应文件，例如：&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-vue&#34; data-lang=&#34;vue&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;template&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;PageWrapper&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;title&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;投资人概览&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;!--&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;TODO&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;填充页面内容&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;--&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;PageWrapper&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;template&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;setup&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;lang&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// 预留接口调用和状态管理位置&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;&lt;/span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;script&lt;/span&gt;&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start=&#34;3&#34;&gt;&#xA;&lt;li&gt;自动往某个路由模块里追加配置&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;这样新页面出现的那一刻就已经可以访问，只需要填内容。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;2-create-api接口封装生成器&#34;&gt;2. &lt;code&gt;create-api&lt;/code&gt;：接口封装生成器&lt;/h2&gt;&#xA;&lt;p&gt;写接口封装时经常要做：&lt;/p&gt;</description>
    </item>
    <item>
      <title>把多个前端项目合进一个 Monorepo 是怎样的体验</title>
      <link>http://localhost:1313/posts/2023-01-15-monorepo-migration/</link>
      <pubDate>Sun, 15 Jan 2023 00:00:00 +0000</pubDate><author>wuwenzen@outlook.com (wuwj)</author>
      <guid>http://localhost:1313/posts/2023-01-15-monorepo-migration/</guid>
      <description>&lt;p&gt;之前团队的前端项目是这样管理的：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;每个系统一个 Git 仓库；&lt;/li&gt;&#xA;&lt;li&gt;各自有一套构建脚本、一份依赖清单；&lt;/li&gt;&#xA;&lt;li&gt;公共组件、工具要么复制粘贴，要么用「半私有」的 NPM 包。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;结果就是：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;组件 bug 修一份，要手动同步 N 个仓库；&lt;/li&gt;&#xA;&lt;li&gt;依赖升级经常有「版本错乱」；&lt;/li&gt;&#xA;&lt;li&gt;CI 流水线一堆重复配置。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;于是我们决定把几个核心前端项目合到一个 Monorepo 里。&lt;br&gt;&#xA;这篇文章就是那次迁移的实战记录：&lt;strong&gt;工具选择、包划分、依赖管理、CI 改造，全流程。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;1-为什么要搞-monorepo&#34;&gt;1. 为什么要搞 Monorepo？&lt;/h2&gt;&#xA;&lt;p&gt;总结下来就是三点：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;公共代码复用&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;组件库、Hooks、工具函数不用再复制粘贴；&lt;/li&gt;&#xA;&lt;li&gt;bug 修一次，多项目同步升级。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;一致的工程规范&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;统一 ESLint/Prettier/Commit 规范；&lt;/li&gt;&#xA;&lt;li&gt;统一构建脚手架和发布流程。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;协同开发体验好&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;打开一个仓库就能看到相关项目；&lt;/li&gt;&#xA;&lt;li&gt;修改组件立刻能在多个应用里验证。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;当然，Monorepo 不是银弹，仓库会变大、CI 要更精细。&lt;br&gt;&#xA;所以「是否值得」的标准是：&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;项目之间有明显共享，且会长期共同演进。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;2-工具选型pnpm--turborepo&#34;&gt;2. 工具选型：pnpm + Turborepo&lt;/h2&gt;&#xA;&lt;p&gt;我们调研了一圈：Lerna、Nx、Yarn Workspaces、pnpm Workspace、Turborepo……&lt;br&gt;&#xA;最后选的是：&lt;strong&gt;pnpm Workspace + Turborepo&lt;/strong&gt;，原因：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;pnpm：硬链接节省磁盘空间、依赖管理清晰、速度快；&lt;/li&gt;&#xA;&lt;li&gt;Turborepo：任务编排 + 缓存好用，学习成本相对较低。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h3 id=&#34;21-仓库结构&#34;&gt;2.1 仓库结构&lt;/h3&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;repo-root&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── apps&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── manager-web        &lt;span style=&#34;color:#75715e&#34;&gt;# 管理端&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── investor-web       &lt;span style=&#34;color:#75715e&#34;&gt;# 投资人 Web&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── mini-program       &lt;span style=&#34;color:#75715e&#34;&gt;# 小程序（uni-app 等）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── packages&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── ui-components      &lt;span style=&#34;color:#75715e&#34;&gt;# 通用 UI 组件库&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   ├── shared-utils       &lt;span style=&#34;color:#75715e&#34;&gt;# 工具函数&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── eslint-config      &lt;span style=&#34;color:#75715e&#34;&gt;# 统一 ESLint 配置&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── package.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── pnpm-workspace.yaml&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── turbo.json&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;pnpm-workspace.yaml&lt;/code&gt;：&lt;/p&gt;</description>
    </item>
    <item>
      <title>给前端项目接上 CI/CD：自动构建与预发布环境</title>
      <link>http://localhost:1313/posts/2021-10-20-ci-cd-for-frontend/</link>
      <pubDate>Wed, 20 Oct 2021 00:00:00 +0000</pubDate><author>wuwenzen@outlook.com (wuwj)</author>
      <guid>http://localhost:1313/posts/2021-10-20-ci-cd-for-frontend/</guid>
      <description>&lt;p&gt;以前做前端上线，经常是这样的：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;本地 &lt;code&gt;npm run build&lt;/code&gt; 打包；&lt;/li&gt;&#xA;&lt;li&gt;用 FTP 或手动拷贝把 dist 丢到服务器；&lt;/li&gt;&#xA;&lt;li&gt;出了问题再手动覆盖回去。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这种方式有几个明显缺点：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;完全依赖人的操作习惯，出错难追踪；&lt;/li&gt;&#xA;&lt;li&gt;没有固定的「预发布环境」，测试体验不好；&lt;/li&gt;&#xA;&lt;li&gt;回滚麻烦，基本靠「手快」。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这篇文章记录的是：&lt;strong&gt;一次给前端项目接上 CI/CD 的实际过程&lt;/strong&gt;，目标是：&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;提交代码 → 自动构建 → 部署到预发布 → 人工验证 → 一键上线 &amp;amp; 可快速回滚。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;1-流程目标先画出来&#34;&gt;1. 流程目标先画出来&lt;/h2&gt;&#xA;&lt;p&gt;先不管用什么平台（GitHub Actions、GitLab CI、Jenkins…），流程大致分为几步：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;CI 阶段（持续集成）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;安装依赖；&lt;/li&gt;&#xA;&lt;li&gt;跑 lint / 单测；&lt;/li&gt;&#xA;&lt;li&gt;打包构建。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;CD 阶段（持续交付/部署）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;构建产物上传到制品库或对象存储；&lt;/li&gt;&#xA;&lt;li&gt;自动部署到预发布环境；&lt;/li&gt;&#xA;&lt;li&gt;人工验证无问题后，再部署到生产；&lt;/li&gt;&#xA;&lt;li&gt;所有版本有记录，可一键回滚。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;把这张「大图」先画给团队看，大家对齐预期后，再来谈具体实现。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;2-以-github-actions-为例写一个最小流水线&#34;&gt;2. 以 GitHub Actions 为例写一个最小流水线&lt;/h2&gt;&#xA;&lt;h3 id=&#34;21-基础-ci安装--构建&#34;&gt;2.1 基础 CI：安装 + 构建&lt;/h3&gt;&#xA;&lt;p&gt;&lt;code&gt;.github/workflows/ci.yml&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Frontend CI&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;on&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;pull_request&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#ae81ff&#34;&gt;main, develop ]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;push&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#ae81ff&#34;&gt;develop ]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;jobs&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;build&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;steps&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Checkout code&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Use Node.js&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/setup-node@v3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;with&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;node-version&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;18&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Install dependencies&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;run&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;npm ci&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Lint&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;run&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;npm run lint&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Build&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;run&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;npm run build&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Archive production artifacts&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/upload-artifact@v3&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;with&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;dist&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#f92672&#34;&gt;path&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;dist&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样每次 PR / 推送到 develop，都能自动帮你检查：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
