Skip to content
/ proj Public

Do something "deep, lasting, and meaningful". 做一些“深入、持久、有意义”的事情

Notifications You must be signed in to change notification settings

warmhug/proj

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

98 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

layout title show_title permalink
default
日常学习记录
false
/

.

网易 科技 财经 国际 pmbaobao 人人PD 热榜 36kr热榜

oschina yuque 极客公园 少数派 凤凰网 威锋网 蜻蜓 什么值得买 奇绩创坛 壹心理

时代周刊 纽约时报 华尔街日报 https://youtube.com https://instagram.com https://whatsapp.com

科技周刊 hacknews中文 https://feedme.icu https://github.com/ccbikai/hacker-news 设计工具排名 https://coolshell.cn

中国技术先锋 2024 中国技术品牌影响力企业 https://segmentfault.com/a/1190000045534050 2023 中国技术品牌影响力 及 新锐技术企业 https://segmentfault.com/a/1190000044503608 2022 中国技术品牌影响力 及 新锐技术企业 https://segmentfault.com/a/1190000043210594 2021 中国新锐技术先锋企业 https://segmentfault.com/a/1190000041274038 2020 中国技术先锋年度评选的初心和起源 https://segmentfault.com/a/1190000038317016

2022-04 《美国公布:长达35页的2045年新兴科技趋势报告》 https://mp.weixin.qq.com/s/ox6NHtK4usvKJ1gpk8uY8A

2021-12《CEM如何助力企业流量新增长?》https://mp.weixin.qq.com/s/aNT3V-zPTbVWHh4s-njyRg 安道全

2019中国开源软件榜 2018前端技术清单

前端

const aa = [...new Set([1, 2, 3])]; 这个 js 写法在不同的 webpack 编译目标下, 表现一致吗? 使用 aa.valueOf() 验证: 在最新的 chrome 浏览器里结果是 (3) [1, 2, 3] 但在 webpack 编译后结果是 [Set(3)] 2025-08-12

@types/update-notifier:6.0.8,command-exists:1.2.9,diff:7.0.0,dotenv:16.6.1,gaxios:6.1.1,glob:10.4.1,highlight.js:11.11.1,ink:6.0.1,ink-big-text:2.0.0,ink-gradient:3.0.0,ink-link:4.1.0,ink-select-input:6.2.0,ink-spinner:5.0.0,ink-text-input:6.0.0,lowlight:3.3.0,mime-types:2.1.4,open:10.1.2,react:19.1.0,read-package-up:11.0.0,shell-quote:1.8.2,string-width:7.1.0,strip-ansi:7.1.0,strip-json-comments:3.1.1,update-notifier:7.3.1,yargs:17.7.2,@google/genai:1.4.0,@modelcontextprotocol/sdk:1.11.0,@opentelemetry/api:1.9.0,@opentelemetry/exporter-logs-otlp-grpc:0.52.0,@opentelemetry/exporter-metrics-otlp-grpc:0.52.0,@opentelemetry/exporter-trace-otlp-grpc:0.52.0,@opentelemetry/instrumentation-http:0.52.0,@opentelemetry/sdk-node:0.52.0,@types/glob:8.1.0,@types/html-to-text:9.0.4,google-auth-library:9.11.0,html-to-text:9.0.5,ignore:7.0.0,micromatch:4.0.8,simple-git:3.28.0,undici:7.10.0,ws:8.18.0 帮我查下这些 npm 包, 是否有 未经用户操作 而是自身主动地发起 "log请求,或者三方的cookie设置" 等不利于企业信息安全的行为. 或者是否有类似木马和病毒的行为. https://chatgpt.com/c/688894a7-05cc-8008-87e0-c5ef572475b7 https://chat.deepseek.com/a/chat/s/a84bb58a-3f19-47f5-aec8-9ed298db0e71 https://gemini.google.com/app/17702d037ff7ca2c 2025-07-29

https://webkit.org/blog/16458/announcing-interop-2025/ https://antfu.me/posts/move-on-to-esm-only 2025-02 技术趋势

markdown 转html 用十几行正则就可以为什么要搞那么复杂? https://www.zhihu.com/question/443343954/answer/3375039874 2024-12

2024-05 阿侎 命令模式undo/redo https://zhuanlan.zhihu.com/p/698816530

2023年前端技术盘点与2024年技术展望 https://mp.weixin.qq.com/s/LiygBJqMN8U_vSpAjxMibQ

2022-02 本杰 《协同文档工作机制简介》 https://mp.weixin.qq.com/s/BtoM_4Gy5v4I0okpMukATg

gmtc https://gmtc.infoq.cn/2022/beijing/schedule 重庆前端交流会 https://zhuanlan.zhihu.com/p/581717444 前端领域的 “干净架构” 徐飞 业务中的前端组件化体系 2022

2021 大前端技术回顾及未来展望


Stack Overflow Developer Survey stateofjsstateofcss stateofreact https://risingstars.js.org https://github.com/enaqx/awesome-react https://github.com/brillout/awesome-react-components https://www.react-next.com

https://experiments.withgoogle.com/collection/chrome https://www.chromestatus.com/features https://webkit.org GitHub登录 https://codesandbox.io https://codepen.io

html css HTTP

2018 2021 2025

https://prettier.io/playground/

  • html 规则检测 https://validator.w3.orghttp://infohound.net/tidy

  • html head 里的 js css 如何放置 head 里能放什么 https://github.com/joshbuchea/HEAD

  • iframe 有哪些问题 https://afantasy.ninja/2018/07/15/dive-into-iframe

    • 高度改变麻烦、弹框、iframe 里再嵌套 ifr。
    • 移动端页面、打开(全屏)嵌入的 iframe 页面,点浏览器返回、返回不到业务页面、需要销毁 iframe。
    • 浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。
    • 里边 弹出框 的位置、难居中,浏览器 resize 时自动居中 更难处理。
    • 主文档和 iframe 文档如果不同域、免登录处理麻烦,涉及 cookie 透传。
    • 需要完全重新加载,比较慢。
    • iframe 自适应高度:给定高度、内部滚动
  • div/span 都是容器元素, p dt 标签里不能有块(block)标签, button 里面不要嵌套 a 标签。

  • img script 的 src、css 的 href 都不能为空。 DOM 的 attribute 和 property 区别。

  • a 伪类需遵循 css2 规范中的 L-V-H-A (a:link visited hover active) 顺序。

  • 没有 css-parent-selector 。 BEM命名方式。 如何提升 CSS 选择器性能 http://www.jianshu.com/p/268c7f3dd7a6

  • anchor-positioning-api

  • CSS 选择器优先级(id>class>标签>伪类)?伪类和伪元素区别?BFC/IFC 介绍?

  • 浮动以及清除浮动?页面布局方法?flex一维 CSS Grid 二维。元素垂直居中方法?

  • border-box 作用?display/position 作用(absolute会变为块元素)?z-index 在节点 position 值是什么生效(relative/absolute/fixed)?

  • 子元素的 margin-top 设置影响父元素位置?页面兼容性问题?响应式布局怎么实现?

  • CSS优化方法?减少DOM操作,减少重绘和重排,合理使用选择器,减少@import使用。

  • h5高清方案(rem) 优缺点? css 实现 loading,三角形? css-module 的作用? css 样式初始化为了什么?

  • https://www.iconfont.cn/

  • css 时间函数 http://www.smashingmagazine.com/2014/04/15/understanding-css-timing-functions

  • css 长度 https://css-tricks.com/the-lengths-of-css

    • 绝对长度: px inch cm mm。 rem: 相对 root 的 font-size 大小 em: 基于大写字母 M 的尺寸 ex: 基于 x 字母高度 1vh 等于 1/100 的视口高度

------ browser

  • URL 编码,为什么要编码?

  • 浏览器在自动选择编码方式的时候不会优先根据 html 源码中的所展示的<meta charset="utf-8" />代码来决定选择什么编码方式,而是优先根据“响应标头-response header”中的键为“Content-Type”的值来自动选择判断。

  • ua 检测 / 特性检测

  • 浏览器解析和CSS(GPU)动画优化 https://segmentfault.com/a/1190000008015671

    • css 动画中尽量只使用 transform 和 opacity ,这不会发生重排和重绘。
    • 有动画的元素样式,给定尺寸、设置为 display block(如果设置 display flex 子元素尺寸会动态变化、影响动画效果)
  • WebAssembly

  • PWA

    • Service Worker 需要运行于 HTTPS 或本地 localhost 环境,是继 Web Worker 后又一个新的线程。来实现离线页面功能。 Service Worker 是独立于页面的一个运行环境,它在页面关闭后仍可以运行。Web Worker 在页面关闭后不再运行。
  • https://developer.chrome.com/blog/introducing-popover-api/ Web Authentication 在Web上使用Touch ID 和 Windows Hello 登录

  • 浏览器 eventLoop 机制 microtask marcotask 执行顺序?setTimeout 宏队列先执行,promise 微队列。

  • 优化:压缩资源、异步加载、预加载、缓存、使用gzip、减少cookie、减少重定向、减少请求数。

  • JSONP 的原理以及 cors 怎么设置?跨域的方法有哪些?jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面。

  • web worker 突破同源限制?importScripts。 不好地方:(协程)解决并行计算,数据共享和精确控制线程生命周期方面存在缺陷。

  • SPA 实现方法?产生的问题:切换路由后会把上个路由状态生成的html全部销毁掉,再切回来恢复不到原来的样子。客户端渲染和服务端渲染,哪个快?

  • 移动: 点击穿透/300ms延迟?Fastclick。首频渲染、网络性能?手势库?有没有用过RN PWA?

  • 数据可视化: 3d 编辑器功能?技术点 svg 3dgis canvas webgl,svg 转 webgl 怎么实现?

drag-drop

  • drag 事件 不支持 ie8、Safari 5.1 ie<=9 只能对 a href="" 、img、文本 添加drag事件。 ie9上通过 selectstart hack方法对任何元素添加事件。 在ie<=8版本上,需要把dragenter/drageover/drop事件绑定到具体的元素上,而不能绑定到document做委托处理。
  • 使用 drag-drop API的优势(相对于用mousedown/mousemove): 如果拖动元素所在的容器尺寸小,拖动过程产生滚动条、会自动触发滚动条移动。 不用再 clone 出一个要拖动的元素; 不用计算涉及到的元素的位置和尺寸。 传统拖动做法
  • 在 touchstart / mousedown 中记录起始位置,并开始监听 touchmove touchend / mousemove mouseup
  • 在 touchmove mousemove 中计算当前位置和起始位置之间的 offset,并进行拖拽操作
  • 在 touchend mouseup 中取消监听 touchmove 和 touchstart,并进行释放操作

--- 安全 2018 - 2017

xss/csrf 原理和防御方法。CORS 的 POST 跨域如何带cookie https://www.jianshu.com/p/13d53acc124f csrf 详解csrf漏洞wiki中文 XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

ajax里如何更新csrf token ,最后的一段评论提到:csrf-token的目的是,让攻击者不能伪造请求(如通过img发起的请求会带上cookie)。因此,csrf-token不需要每个请求都改变,只需要确保对于每个session不一致即可,同一个session内不变没有问题。 jsonp请求也需要「防止csrf漏洞」,例如可以用jsonp获取通讯录列表。 ajax 方式的 csrf token 放到 post 提交的 body 里、随其他数据一起提交。

a 标签中 target="_blank" 的安全漏洞 详细地解释了该漏洞的攻击方法和原理。并在文末给出了防范该漏洞的解决办法:给 a 标签增加 rel="noopener noreferrer nofollow"。

反爬虫 https://segmentfault.com/a/1190000017899193 循序渐进学加密 https://segmentfault.com/a/1190000019437132 蚂蚁内容风险识别接口服务 撞库 人机识别服务 IFAA 生物认证 https://tech.antfin.com/products/IFAA

安全资讯网站博客

------ HTTP

2018 2022 2024

HTTP 长轮询/长连接 一种轮询方式是否为长轮询,是根据服务端的处理方式来决定的,与客户端没有关系。轮询的长短,是服务器通过编程的方式手动挂起请求来实现的。

HTTP GET/DELETE/PUT 幂等性(无副作用) DNS 缓存. http1.1,keep-alive 是默认的 只需一次 TCP 握手. PC 上的 RTT 大概是 50ms, wifi 为 100ms, 3G 为 200ms,2G 为 400ms. 丢包: 丢的是 tcp 包?服务器怎么知道丢了,丢了哪些内容 (如 get 请求内容一部分丢了)?浏览器会重新发送,还是自动重发? 合并 HTTP 请求是否真的有意义? 浏览器针对每个域名并发建立的最大 TCP 连接数基本都是 6 个,然后每个连接上串行发送若干个请求。HTTP1.1 协议规定请求只能串行发送。

http pipelining pipeline 原理是 客户端可以并行发送多个请求,但是服务器的响应必须按次序返回。一些服务器和代理不支持 pipeline;在 pipeline 中的前一个链接可能会阻塞后边的链接;减缓页面加载速度。Chrome 默认禁止了 pipelining。原因

名词:TCPUDP套接字SocketipURIURLURN 消息摘要和数字签名RSA算法DSA认证问题证书签名代码签名AES密匙GSS-APISASLSSL

IP地址和端口号组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础。 半关闭提供了这样一种能力:套接字连接的一端可以终止其输出,同时仍旧可以接收来自另一端的数据。该协议只适用于一站式(one-shot)的服务,如http服务。

--- Session与Cookie

Session 默认有效期是关闭浏览器,为什么session会消失,主要原因是浏览器端cookie内保存的 sessionID 失效了,因为session是基于cookie的,所以关闭浏览器会失效。浏览器关闭,session是不会马上消失的。如何延长session声明周期,解决方案:延长cookie 和 session 的生存时间

Cookie可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果数量很多,这就增加了客户端与服务端的数据传输量,而Session解决了这个问题。

同一个客户端每次和服务端交互时,不需要都传回所有的Cookie值,而是只要传回一个id,这个id是客户端第一次访问服务器时生成的,而且每个客户端是唯一的。这个id通常是name为JSESIONID的一个Cookie。

由于Cookie是存储在客户端浏览器里的,不安全很容易被修改。相比之下,Session是将数据保存在服务端,只是通过Cookie传递一个SessionID而已,所以Session更适合存储用户隐私和重要的数据。

分布式Session框架可以解决的问题:Session配置的统一管理;Cookie使用的监控和统一规范管理;Session存储的多元化;Session配置的动态修改;Session加密key的定期修改;充分的容灾机制,保持框架的稳定性;Session各种存储的监控和报警支持;Session框架的可扩展性;跨域名Session与Cookie的共享。

由于应用是一个集群,所以不可能将创建的Session都保存在每台应用服务器的内存中,因为如果每台服务器有几十万的访问用户,服务器的内存肯定不够用,即使够用,这些Session也无法同步到这个应用的所有服务器中。所以要共享这些Session必须将他们存储在一个分布式缓存中,可以随时写入和读取,而且性能要很好才能满足要求,如MemCache、淘宝的Tair。

跨域名共享Cookie问题,Cookie是有域名限制的,一个域名下的Cookie不能被另一个域名访问。所以,如果在一个域名下已经登陆成功,如何访问到另外一个域名的应用且保证登陆状态仍然有效呢?

--- 2019

  • 从输入URL到页面加载完成 http://fex.baidu.com/blog/2014/05/what-happen/

  • HTTP 协议,http2.0,http 301 / 302 / 304 的区别。

  • TCP 是运输层而 HTTP 是应用层,HTTP需要支持「分块传输编码」。分块传输编码可以在响应数据未完全生成时进行数据传输,此时还无法确定响应信息的具体大小。如果分块中所包含信息的长度为 0,则表示响应信息的结束。

  • SPDY / HTTP 2 核心优势就是多路复用,简单说来就是将多个请求通过一个 TCP 连接发送。浏览器能不能将 100 个请求通过一个 TCP 连接发送?会出现什么问题?那就是 TCP 协议的 head of line blocking,队头阻塞。

  • http2讲解htt2 and UDP

  • 200、304 状态图 https://img2018.cnblogs.com/blog/907596/201903/907596-20190302011346217-1805589363.png (文章 https://www.cnblogs.com/kevingrace/p/10459429.html)

  • 输入域名并按下回车后 第一步,浏览器会检查缓存中有没有这个域名对应的解析过的 IP 地址,有就结束,没有进入下一步

  • 第二步,浏览器查找操作系统缓存中是否有。操作系统也有一个域名解析过程,在 hosts 文件里设置可以将任何域名解析到任何能够访问的 IP 地址。如果指定了,浏览器会使用这个 IP 地址。(早期 Windows 中的域名被入侵黑客劫持问题)

  • 前两步都是在本机完成的,如果无法完成解析,就会请求域名服务器了。我们的网络配置中都会有「DNS 服务器地址」,操作系统会把域名发送给 LDNS,也就是本地区的域名服务器。大约 80% 的域名解析到这里完成。

  • 第四步,如果 LDNS 没命中,就到 Root Server 域名服务器请求解析。然后 gTLD ServerName Server 域名服务器,返回该域名对应的 IP 和 TTL 值 被 Local DNS Server 缓存,解析结果返回给用户、缓存到本地系统缓存中、域名解析过程结束。(这中间还有 GTM 负载均衡控制等)

  • 可以用 nslookupdig www.taobao.com 等命令,跟踪解析过程

JS / Libs

2018 2022 2024

------ 基础

------ 库/框架

A Guide to Server-Side Rendering https://www.builder.io/m/explainers/server-side-rendering

2025 react-libraries https://www.robinwieruch.de/react-libraries/

Vue.js 作者宣布成立 VoidZero https://mp.weixin.qq.com/s/xT7SRffAcUqLFf7Ou4I5Og 2024-11

cssinjs https://mp.weixin.qq.com/s/cepGi8Jhe4RnyfNaoN_zfw react19 cssinjs 问题 https://juejin.cn/post/7359876671137071156 探索:业务中推行 tailwindcss 和 emotion,设计上 design token 抽象。 2024-10 cssinjs

CSS in React Server Components https://sorrycc.com/css-in-rsc 原文:https://www.joshwcomeau.com/react/css-in-rsc/ 2024-04

  • React16 / 17 / 18版本新特性 https://blog.csdn.net/momei1942/article/details/129699873

  • React18: 并发控制的更好更灵活,定时器等异步函数setState批处理、Suspense 流式 html SSR、useTransition 延迟/过渡更新。

  • 看过 框架或库 源码? react 使用注意事项 https://github.com/mithi/react-philosophies React 技术揭秘 https://react.iamkasong.com/

  • react diff 原理?生命周期?受控组件和非受控组件?父组件和子组件的通信方式?render-props 高阶组件 (代替mixin及ref问题)?

  • react 应用性能优化?列表 key / shouldComponentUpdate / PureComponent (父子组件 props state 不变时不render 为什么不建议用?) / memoization

  • react setState 是同步的还是异步的? 异步。 子组件和父组件 componentDidMount 哪一个先执行?子组件先。

  • prop 的变化 同步到 state 的方法?

  • react 渲染器了解一下? https://juejin.cn/post/6844903753242378248

  • React Fiber 架构 https://xueshiming.cn/2021/05/08/React%20%E4%B9%8B%20Fiber%20%E6%9E%B6%E6%9E%84/

  • React-Fiber 并发模式、区分任务优先级、调度协调 中断/恢复任务,浏览器60fps渲染 10毫秒自己执行 5毫秒空闲时间。

  • react 需要遍历或修改 children,要使用React.Children.forEach / React.Children.map 方法,而不要用Array.isArray(children) / children.forEach等方法。

  • setState 是异步的 示例 会引起不必要的 render。

  • 真实 DOM 和 react 虚 dom 讨论

    • dom 对象是很庞大的(上边有很多属性),其创建的开销比较大,已有的 dom 对象上做更新开销并不大,众多框架都在围绕此做优化,比如用key是否变化来判断对 dom 的操作是 “更新” 还是 “销毁重建”。 dom批量更新:dom操作如,1.删除一个元素,2.增加一个元素,3.在增加的元素上改变一个属性。如果用 dom-api,会有多次 repaints reflows 比较耗性能。 如果放到「虚拟 dom」上操作,会把这三个过程最终的结果,一次更新到实际 dom 树上,只用操作一次实际 dom。 virtual-dom 里一次 digest 中的 diff 只需一次,但是会随着 ui 的规模复杂度,性能损耗严重。

react hooks

redux 概念

  • 为什么是 企业级前端开发框架? 实现 双向绑定 的原理?
  • 单双向数据流区别?https://pomb.us/build-your-own-react
  • data-flow, 不可变的数据更新模式 immutable-update-patterns.
  • actions 其实就是 mutations,即 ui 或者 server 的 response.
  • action creator 调用 dispatcher (passive pub-sub systems) 传递 mutations.
  • store 监听 actions 再去 mutate data (只有store能决定怎么更新数据).
  • component 监听 store, 获取需要的数据. redux 基本流程
  • 为什么用单一的 store? 子组件 connect 后可使用 store 了? context。 immutable-js ? immerjs
  • redux-saga 典型流程: form 表单提交,触发 FORM_POST action,saga 里 yield put POST_SUCCESS 触发 action,改变页面状态或拉取新数据,触发 UI CHANGE 的 action,过程中用 yield select 从 state 里选取需要的参数。 Reactive programming vs Passive programming

redux / umi

  • 框架的“双向绑定”意思是 view -> state -> view 变化的绑定,而不是 state1 <-> state2 变化的绑定、同样功能的 state 只用定义一个、有多个就会导致 state 变更检测的死循环。
  • umi 某个 router 多处复用方案 umi/1830umi/4569
  • subscriptions 怎么获取到 model 中的 state issues/1600
  • 多个请求并行发起 redux-saga/issues/1800redux-saga/pull/759dva/issues/1009
  • 如何请求多个数据源并渲染?如

弹窗 modal 里高度需要设置、内容长时“内滚动”。 一行多列 card 卡片,每个卡片 高度需要设置成一样。 某个操作 触发多次 ajax 请求、再 setState 页面,导致卡顿? 一个页面有多个“富文本实例”同时初始化、比较耗时?导致页面卡顿? 2020 性能和体验

------ 小程序/RN 2022

小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了 WebView 进行渲染;逻辑层采用 JsCore 线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个 WebView 线程,这两个线程的通信会经由微信客户端做中转,逻辑层发送网络请求也经由 Native 转发。 目的:安全可控,沙箱隔离,限制 DOM 和 BOM 能力。逻辑层和渲染层是独立的,二者不会互相阻塞,因此性能更优(小程序限制了 JS 操作 DOM 的能力,因此不用担心二者的不同步问题)在浏览器网页中,虽然 JS 执行和 UI 渲染也是处于两个线程,但是 JS 线程和 UI 线程是互斥的。

小程序采用的是混合架构,可通过 html 里的 a 标签启动新的 webview 窗口、调用 popWindow 关闭窗口。基本页面元素是 html 渲染,弹窗类 loading toast ActionSheet 和 本地存储、系统或用户信息,使用客户端原生实现。

而 react-native 只是采用 js/html 写法,背后完全是 客户端原生 渲染。 微信小程序和 RN 的区别:双线程架构,渲染层一个主要是 webview 一个完全 native。 微信的支付 小程序云等开放API、小程序安全管控。

小程序框架

  • taroremaxalibaba/raxflutter
  • 编译时:约定了一套自己的 DSL ,在编译打包的过程中,利用 babel 工具通过 AST 进行转译,生成符合小程序规则的代码。
    • 容易出现 BUG、开发限制过多、跟不上 react vue 更新。早期的 Taro 1/2 采用的这种方案。
  • 运行时:在小程序的逻辑层中运行起来 React 或 Vue 的运行时,然后通过适配层,实现自定义渲染器。
    • 有天然优势,remax taro3 这样实现。

React component -> React Reconciler(调和器、实现了 Diff/Fiber 算法) -> React Renderer(可以是dom也可以是js对象等)。 跨端小程序框架 remax taro3 自己实现了一套可以在 React 中用的,且能渲染到小程序页面的自定义渲染器。 在 react reconciler resetAfterCommit 函数中、调用小程序的 setData 方法。 小程序环境中,不支持直接创建DOM、仅支持模板渲染,用递归模板的方式,用相对静态的小程序模板语言实现了动态的模板渲染的特性。

小程序 API

const { Ali } = window;
const { isAlipay } = Ali;
window.AlipayJSBridge;
document.addEventListener('AlipayJSBridgeReady', callback, false);
Ali.httpRequest({ url: '', method: 'POST' }, (result) => {});
Ali.rpc({ operationType: '', requestData: [] }, (result) => {});
Ali.call('imageViewer', { enablesavephoto: true, images: [], init: index });
Ali.showLoading(param);
Ali.showToast({ content: '' });
Ali.showActionSheet({ content: '' }, (result) => {});
AlipayJSBridge.call('popWindow');
AlipayJSBridge.call('setTitle', { title: 'xxx' });
AlipayJSBridge.call('getSystemInfo', { }, (result) => {});

TypeScript

这么写的 export type * from 'xxx'; 报错: error TS1383: Only named exports may use 'export type'. ts不允许这么写. 在 compilerOptions 里加上 "skipLibCheck": true, 忽略. 2025-07-01

@types/node @types/react 版本 需要和 typescript react 版本匹配. 2025-04

Why Go microsoft/typescript-go#411 2025-03

monorepo 项目根目录 tsconfig 里已配置 "paths": { "@xx/monoaid": ["./common/monoaid/src/index.ts"] } 根目录有个 build.mjs 文件,内容有 import { xx } from '@xx/monoaid'; 使用 node ./build.mjs 运行报错 Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@xx/monoaid' 这是因为 TypeScript 的 paths 配置只影响 TypeScript 编译器和工具(如 IDE 的代码提示),而不会直接影响运行时(Node.js)。Node.js 不会解析 tsconfig.json 中的 paths,所以它找不到 @xx/monoaid 模块。 2024-12

TypesSript 装饰器源码分析 使用 TypeScript 实现依赖注入 如何实现一个 TypeScript 的宏 让 babel 帮你编译 typescript https://github.com/zzj3720 (github/toeverything) conditional type 中的联合类型与 never TypeScript专栏 2019

# pnpm tsc 当存在多个版本 typescript 查看当前使用的是哪个
pnpm exec tsc -v  # pnpx tsc -v 会报错
pnpm exec which tsc  # 查看
ls -l ./node_modules/.bin/tsc

pnpm exec tsc --build --traceResolution > a.log

# 查看当前项目 typescript 版本
npx tsc -v
npx tsc --showConfig
# 输出 resolution 日志
npx tsc --traceResolution
# 如果遇到 react 问题, 搜 Resolving module 'react' from
npx tsc -p tsconfig.json --traceResolution

# 遇到ts类型报错 Cannot find module '@xx' or its corresponding type declarations.
# 打开报错的 ts 文件, 按 Cmd+Shift+P 输入 TypeScript: Go to Project Configuration 它会跳转到当前文件生效的 tsconfig

TypeScript 的模块解析机制, 查找类型声明的顺序是:

  • 当前包的 node_modules/@types
  • 往上级目录递归找 node_modules/@types
  • global 的类型(如果 tsconfig 配置了) 如果只限制在当前包查找, 在 tsconfig.json compilerOptions 配置 paths.

https://www.typescriptlang.org/tsconfig/ tsconfig.json 配置

// 比如是 monorepo 根目录的 tsconfig.json
{
  "compilerOptions": {
    // baseUrl 的 . 和 ./ 一样 ,
    "baseUrl": "./",
    "target": "es5",
    "module": "esnext",
    "moduleResolution": "Node",
    "strict": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "declaration": true,
    "strictBindCallApply": false,
    "importHelpers": true,
    // debug
    "explainFiles": true,
    "traceResolution": true,
    //
    "typeRoots": ["./typings", "./vendor/types"],
    "types": ["node", "jest", "express"],
    //
    "paths": {
      "tslib": ["node_modules/tslib/tslib.d.ts"],
      "*": ["./node_modules/*", "*"],
      "@/*": ["src/*"],
      "@@/*": ["src/.space/*"],
      "@xx/yy": ["src/index.ts"]
    }
  },
  "include": ["src/**/*", "tests/**/*"]
}

// monorepo 子目录 ./packages/_demo/tsconfig.json 内容如下,
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "noEmit": true,
    "paths": {
        // 注意 虽然是在 packages/_demo 子目录里, 但这里 compilerOptions - paths 路径写法是相对 项目根目录 .
        // 如果再设了 baseUrl: "./" 才是相对 packages/_demo 解析
        // 即 compilerOptions.baseUrl 和 paths 的解析是以:最终(合并后的) tsconfig.json 中的 baseUrl 为准。 https://chatgpt.com/c/6846814a-2dd0-8008-b63c-d61d4825318f
      "myswr": ["./packages/swr/index.tsx"],
    }
  },
  // 如果是自建的 以 点 开头的目录, 在 unix 系统里会被当做 配置文件 而默认不被 vscode 等解析.
  // 比如 .xx 在 include 里不能只写 ".xx" 而是 ".xx/**/*"
  "include": ["./src", "./.i18n/**/*"]
}

搭建 文档/图

------ 搭建

去哪儿网前端代码自动生成技术实践 https://docmost.com/

阿里低代码引擎LowCodeEngine正式开源 官网github

https://www.wix.com/ https://soloist.ai/

无代码nocobase 博客

网易云音乐低代码体系建设思考与实践

从实现原理看LowCode

https://github.com/imcuttle/mometa 百度amis https://aisuda.bce.baidu.com/amis

AECP 开发平台架构 https://img.alicdn.com/imgextra/i2/O1CN01VFIoNq1E0PCIklFol_!!6000000000289-2-tps-2482-1410.png

2020/01/13/the-no-code-delusion无代码编程介绍 antd-lowcode

Markdown + 卡片 可视化搭建、 宜搭、云凤蝶阿里云外网建站。微软 Power Platform。AWS honeycodemendix

SaaS行业导航、SaaS 平台:氚云搭搭云明道云appsheetfiberyopenchakratumult(YC投资)

grapesjsnoflojspagedraw、Google Web Designer (类似 Dreamweaver) 2013 发布 2017 停止更新。

What's Salesforce? 、Salesforce Lightning

云上编排(cloudcraft/阿里ros/华为云aos/Terraform/PAD图)、图编排(相关)

GUI 研发:umi-uiangular-console

表单: formilybuild forms from JSON Schemareact-final-formAForm模型驱动生成表单

------ 文档 / 图

https://github.com/GraphiteEditor/Graphite https://editor.graphite.rs/ rust 图片编辑器

基于 OnlyOffice 的本地网页文档编辑器 https://github.com/ranuts/document https://www.onlyoffice.com/

https://github.com/plait-board/drawnix https://github.com/pages-cms/pages-cms https://github.com/warmhug/demo/blob/main/.pages.yml

https://liveblocks.io/blog/which-rich-text-editor-framework-should-you-choose-in-2025

https://github.com/yshavit/mdq 2024 https://affine.pro/ (字节刘义)

2020-11 孟方(游圣) aliyun/cadt

Roam Research 介绍介绍1foam

https://github.com/thinkerchan/notion2mdNotion 编辑器原理腾讯在线 Excel 技术 语雀 实时保存 方案 (平侠/遇春 2021-01)、语雀后端技术隆昊《富文本编辑器的技术演进》有道云笔记富文本编辑器技术演进

飞书在线文档协同、 实时协作技术 ot-vs-crdt / xi-editor-CRDTs / are-crdts-suitablevs code 多人协作CKEditor 多人协作automergecrdt

文档协同的三元结构-浩初resume生成

阿里云媒体管理微软Google/微软、 Google 示例、 转换 sheetson

生成/查看 PPT: PptxGenJSapache_poi_ppt(java)、 nodepptViewerJSoffice sdk

微软: office (task)、teams

Google: gsuite (google-forms/教程) alerts classroom

notioncraft.doairtablequipcoda.io、slack。 wolai (介绍)。 mathigon(互动教程)。

腾讯文档 docs.qq.com、 头条 larksuite (lark 出海)、 teambitionwps (稻壳模板docer)、 xiezuocat(AI纠错)、sheetui(表格转网页)、Luckysheethandsontableprezimilanote

产品设计工具: 白板(muralmiro)、 原型(xiaopiuxiaopiu/prdjustinmind)、知乎(invisionmodao会议桌)、流程图和图表、在线培训工具

其他: mubuslides.comppt.baomituzohovismedeckdeckgowiteboardwireflowpresentabatnoter https://evernote.com

--- 画图 (web/客户端)

如何画好一张架构图? atatech/articles/173778 流程图 https://baike.baidu.com/item/%E6%B5%81%E7%A8%8B%E5%9B%BE 八种常见的业务设计和架构模型 https://www.sohu.com/a/384776040_246648 B端产品设计3大流程图 http://www.woshipm.com/pd/3873765.html 海兔设计系统 DSM yuque.antfin-inc.com/afx-es/data-ai/weekly-2020-05-16 软件设计/业务设计/流程图/架构图/UX设计/BPMN/脑图 https://online.visual-paradigm.com/diagrams/templates/brainstorming

https://tldraw.dev/ SVG-to-Canvas (canvas-to-SVG) Parser skeditor canvaskit-wasm

figma (FigmaToCode) figma 技术 / figma c++ / figma 插件技术 react-sketchapp

excalidrawdrawio(mxgraph)、vscode-drawioplantumlplanttextcloudskewdiagram-jsdiagram.codesmermaid-jsnomnomlvisjs(timeline)、react-diagramsroughjsrete.js/flume/nodered(可视化节点)、diagrams(graphviz)、 text-to-diagramreactflow。 废弃: diagram-maker

平台/端: processon、visio、mindnode lite、visual-paradigmithoughtsgliffyterrastructedrawsoftfreedgowebsequencediagramschartmagethebrainasciiflow(textik)、omnigraffleflowchartphotopea​、PPTist

收费: isoflowgojsjointjsjsplumbtoolkityworksmindfusion-diagramjsplumb

系统: drawio-aws-cloudcraft、(placeholdermermaidnetworkorg)

测试 监控

https://code.visualstudio.com/docs/copilot/guides/test-with-copilot https://docs.github.com/zh/copilot/using-github-copilot/guides-on-using-github-copilot/writing-tests-with-github-copilot 2025-06-05 使用 GitHub Copilot 编写测试

前端应用各类测试区别 https://kentcdodds.com/blog/static-vs-unit-vs-integration-vs-e2e-tests https://kentcdodds.com/blog/why-i-never-use-shallow-rendering https://kentcdodds.com/blog/avoid-the-test-user 已废弃 https://enzymejs.github.io/enzyme/ 2025-05-30

目前最流行的前端开发的测试框架工具有哪些? https://chatgpt.com/c/68371d58-3420-8008-8991-9b2df8b537a8 2025-05-28


https://midscenejs.com/zh/

https://httparchive.org/reports/page-weight 语言性能 jsperf / benchmarks https://jsben.ch/browse heavy tasks on the main thread

Headless BI https://cube.dev/ https://github.com/GoogleChromeLabs/quicklink https://superset.apache.org/

ICBU前端性能度量 https://mp.weixin.qq.com/s/XAdNOovCQxh5xuGVOSEz3w

https://web.dev/articles/vitals?hl=zh-cn Web vitalsthresholdsChrome的First Paint触发的时机探究window.onload vs document.onload

如何根治 Script Error. JavaScript Errors Handbook如何捕获前端错误搞定前端错误捕获和上报错误监控总结

为什么大厂前端监控都在用GIF做埋点? https://mp.weixin.qq.com/s?__biz=MzAxODE4MTEzMA==&mid=2650099077&idx=1&sn=813d2c96cd940dc95b0f47585b989c2f

AEM 表单分析 AEM: 稳定性(脚本/接口/资源异常)、流畅性(加载/卡顿/动画掉帧)、用户流量(pv uv 活跃用户 新用户/点击率 点击热点 / 停留黏性/来源去向/设备)、行为分析(页面流/操作流/留存跳失率/访问链路/表单分析)、满意度(问卷/反馈/录屏/主观分析)。告警/多维指标(用户纬度年龄性别籍贯)/自定义看板/乐高搭建报表页。

chrome-performance-devtool Google lighthouse、类似服务 web.dev/measurewebpagetestpagespeed insights

arms / quick a+ / spm / aplus / retcode / clue。

arm aem 对任何请求(包括图片)都做埋点,导致业务接口被阻塞,页面性能下降一倍。采用合并、延迟上报埋点方式,把所有打点请求都延迟推入单独的队列维护,当页面完全加载完成后再从队列中依次取出数据进行上报。下掉非必要埋点。 2022-01~04

iceworks-doctor vscode-codemetrics

jsinspectjscpd 代码圈复杂度Cyclomatic Complexity

研发效能度量引发的血案10 倍程序员神话代码质量

------ 测试

静态分析与代码质量工具:SonarQube、CodeClimate 等,有助于在构建前发现问题,减少后续测试和修复时间。 SonarQube Codeowners

https://github.com/jsdom/jsdom https://github.com/mobile-dev-inc/Maestro https://lightpanda.io/

CI/CD、JS 覆盖率工具 istanbul。 测试-漏测率。 阿里MTC无线测试中心、蚂蚁云测平台[Solomon]

基础理论: 前端测试体系建设与最佳实践测试金字塔

codecov.io 覆盖率分析对比工具 支持所有语言,对 GitHub commit 的覆盖率做记录、前后对比。

代码测试覆盖率分析 Statements 与 Lines 的区别:一行可能有多个语句

百分百测试覆盖率真的有意义吗? 各种 corner cases(比如除0、IO error handling) 很难做到 100% 覆盖。 覆盖率数据只能代表你测试过哪些代码,不能代表你是否测试好这些代码。 不能盲目追求代码覆盖率,而应该想办法设计更多更好的案例,哪怕多设计出来的案例对覆盖率一点影响也没有。

--- E2E测试 2024-02

自动化测试 https://github.com/puppeteer/puppeteer / https://www.selenium.dev/ https://livebook.manning.com/book/unit-testing/chapter-1/ 我们为什么需要单元测试? https://mp.weixin.qq.com/s/F60MjrCnNsFmZV9jT75AVg

TDD(Test-Driven Development)很强大,但不一定适用所有的团队,推广难度很大,学习曲线很高。 TDD事实上由两个方面组成:测试先行,以及演进式设计;测试先行是非常重要的工程实践,做不到TDD,可以做到测试先行。在Kent Beck的经典名著《解析极限编程》中,提到:尽早测试,经常测试,自动测试!测试先行的本质能力要求是接口的设计能力——能否清晰的定义出设计单元的边界。 什么是有效的单元测试?一味追求代码覆盖率,往往写出无效的单元测试。一个测试应当只检查一件事。避免条件逻辑。不要写永不失败的测试。避免冗余测试。避免Mock不确定的依赖:时间、随机数、并发性、基础设施、现存数据、持久化、网络等等。 可测试的代码和设计:使用new要当心;避免构造函数中包含逻辑;避免复杂的私有方法;组合优于继承;可测试的代码是否违背了SOLID中的开闭原则?可测试的代码就是解耦了的代码;可测试的代码帮助我们实现更好的抽象。 在实现测试金字塔时,你也应该牢记这两条基本法则:

  1. 如果一个更高层级的测试发现了一个错误,并且底层测试全都通过了,那么你应该写一个低层级测试去覆盖这个错误;
  2. 竭尽所能把测试往金字塔下层赶; 任何测试,如果它的运行速度不快,结果不稳定,或者要用到被测试单元的一个或多个真实依赖,就是集成测试。 集成测试不够稳定,运行时间长等问题,如果不做隔离,日常开发浪费时间和精力维护,最后导致开发人员不再信任测试。 把单元测试当成是“一等公民”,在Code Review的过程中,互相学习、分享最佳实践,消除无效的单元测试。 愿意主动增加单元测试来保护自己的代码,那么单元测试这件事就算比较成功了。 关于单元测试这件事,我觉得最重要永远是写单元测试的人,优秀的团队文化非常重要,没有什么能够真正衡量单元测试做的好坏,有的只是程序员的职业操守。 <如何写出有效的单元测试> https://mp.weixin.qq.com/s/U6z-sjb29luOI3E6pE9kMw

TDD 更适合配合单元测试,更适合通用组件/工具函数和纯函数库,比如 lodash、aHooks、ant-design等。 BDD(Behavior-Driven Development) BDD思想就是写单元测试就像写产品需求,而不关心内部逻辑,每一个用例阅读起来就像一篇文档。更适合配合集成测试,测试关键业务流程代码。

  • 因为以功能性的集成测试为主,因此不是那么关注每个函数功能,测试覆盖率比较低
  • 难保证代码质量,没有 TDD 那么严格的保证代码质量,极端边界条件难覆盖 <内网>

测试金字塔的历史可以追溯到2009年。随着技术的快速发展,人们在应对不同的开发需求时,也可能需要不同的测试模型。由Kent C. Dodds提出的测试奖杯(https://twitter.com/kentcdodds/status/960723172591992832)就是一种针对前端开发所构建的测试模型。与金字塔相比,单元测试处于次要地位,而且可以被ESLint和JSHInt等静态测试工具所取代。它们通过扫描代码,便可发现诸如:使用了不安全的语句、或未遵守变量命名规则等潜在问题。 https://www.testingjavascript.com/ <测试金字塔模型全解析> https://www.easemob.com/news/8530 英文 https://dzone.com/articles/the-testing-pyramid-how-to-structure-your-test-sui

覆盖率是金字塔的核心,底层是最宽的,象征着UT覆盖率应该是最高的,越往上越低,这一点大家都能达成共识。但是有一点需要注意的是,每网上一层应该是对下面一层覆盖率的一个补充。简单说集成测试应该聚焦于UT不好覆盖的场景或者UT采用mock方式测试的场景,而顶层的UI自动化应该聚焦于整个流程的集成测试,覆盖集成测试和UT难以覆盖到的场景。 <测试金字塔是什么> https://juejin.cn/post/7216626919772225573

唯一可以真正验证应用程序可行性的测试,只有E2E测试。因为它需要用线上真实的数据进行测试,所以它不仅涉及到前端,还涉及到后端。除了E2E外的测试方式都是通过Mock数据来实现。 你的应用程序在与最终用户(浏览器)相同的环境中做测试,这意味着更高的置信度。即使你只编写一个 UI 测试,它给你带来的置信度也比一百个单元测试更多。 你日常工作中接触的大多数项目都是小到中等规模的,它们最适合进行 UI 测试。UI 测试是一个通用术语,我们必须将其分为端到端测试和 UI 集成测试。 <刚开始接触前端测试?那就从金字塔顶端开始吧!> https://www.infoq.cn/article/ei01kymcs0v2fo1r4srg

E2E 把整个系统当作一个黑盒,测试人员模拟真实用户在浏览器中操作 UI,测试在真实浏览器环境运行测试。 E2E 测试一般是由 QA 测试工程师来做。稍小的项目可能根据测试用例(excel)操作一遍就完了,稍大一点的会写一些自动化测试的代码。 前端可能会为核心的、主要的或稳定的业务流程写 E2E,不过占据的测试比例要小很多,主要目的是:便于给 PM(产品经理) 展示业务流程,便于修改 Bug 之后的回归测试。

完成E2E测试的最佳时间是开发过程接近尾声时。 这是因为客户使用的大部分功能都在软件中,这意味着端到端测试涵盖了用户将体验到的程序的所有必要方面。 单元测试检查一段代码的具体单元,如单个函数和程序中两个不同函数之间的孤立连接。单元测试可以更快,但其缺点是不能完全模拟用户体验。 较大的组织往往有单独的测试和开发团队,保持这两个机构相互独立,以便不对E2E测试的结果引入任何偏见。 在可能的情况下,让没有开发过特定功能的人去测试它。 这在可能的情况下消除了固有的偏见,并使端到端的测试尽可能地准确。 规模较小的独立开发者,如首次开发应用的开发者或预算限制较多的开发者自己完成E2E测试。 在可能的情况下,多人完成测试并重复测试是最理想的,因为它提供了额外的确定性,无论是自动还是人工结果。 端到端测试的调试过程更加复杂,因为自动测试返回的 “失败 “信息不太可能是问题的具体原因。开发人员需要进一步调查以解决问题,特别是在没有整合具体错误信息的情况下。 响应速度 一些E2E测试的重点是确保系统快速返回有效的结果。 UAT测试是用户验收测试的意思,是一种测试形式,不是由开发团队的人完成,而是由目标受众的成员完成。 端到端测试仅仅是对软件的分析,以及它如何有效地工作,系统测试还包括对它所运行的硬件和一些固件的评估,如操作系统,它与之互动。 通过人工端到端测试过程的主要好处之一是你自己看到所有的潜在问题,注意到计算机可能看不到的软件缺陷。然而,与实现测试过程自动化相比,这个过程可能相对缓慢。 较小的项目可以由一个团队手动进行彻底的测试,梳理代码中的任何错误,并立即将其记下。相反,较大的项目根本无法手动测试,需要大量的软件测试自动化。 <端到端测试 – 深入了解E2E测试类型、流程、方法、工具等> https://www.zaptest.com/end-to-end-testing-deep-dive-into-e2e-test-types-process-approaches-tools-more https://www.zaptest.com/zh-hans/%E7%AB%AF%E5%88%B0%E7%AB%AF%E6%B5%8B%E8%AF%95-%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3e2e%E6%B5%8B%E8%AF%95%E7%B1%BB%E5%9E%8B%E3%80%81%E6%B5%81%E7%A8%8B%E3%80%81%E6%96%B9%E6%B3%95%E3%80%81%E5%B7%A5

质量不等于测试。质量不是被测试出来的。虽然质量不是被测出来的,但同样有证据可以表明,未经测试也不可能开发出有质量的软件。 把开发过程和测试融合在一起----开发和测试必须同时开展。写一段代码就立刻测试这段代码,完成更多的代码就做更多的测试。 最适合做测试的角色是开发人员而不是测试人员,质量更像是一种预防行为而不是检测行为。在google, 测试的目标是判断这种预防行为是否正常工作。质量是开发过程中的问题,而不是测试问题。 测试工程师会转型为测试设计。少量的测试设计师快速地规划出测试范围、风险热图和应用程序的漫游路线。测试工程师会转变成像安全工程师这样的专家型角色,或者编程测试活动的管理者,而那些具体的测试活动则由其他人来完成。 <Google软件测试之道>

质量保障的追求不是发现所有的bug、解决所有的风险,而是确保即使触发了bug也不会带来恶劣的影响,在此基础上力求去发现尽可能多的bug -> bug 触发概率降到尽可能低 -> 触发bug后带来的损失降到尽可能小。 <测试八年|对业务测试人员的一些思考> https://mp.weixin.qq.com/s/LQqYwrL2EDJBg5S00E3vaA

研究了代码质量后,开发速度提高了 2 倍,bug 减少了 15 倍 https://mp.weixin.qq.com/s/2FXkUE2OttMHUSwbf3JDgw

基本库

antd 的 ConfigProvider 如果存在多层嵌套, 哪一层优先级最高, 每一层的属性怎么覆盖? 为什么 locale prefixCls 无覆盖? 如果外层的 ConfigProvider 设置了 locale 内层的 ConfigProvider 没设置, 那这时候 locale 不是无效了吗? 怎么解决? https://chatgpt.com/c/689ef7c6-2f94-8333-b328-46f09b85c787 2025-08-15

在 docusaurus v3 中, 不通过修改 md 文档的 slug 而是通过插件方式, 实现 比如实际文件路径是 form/.i18n/index.md 在 URL 里显示为 components/form 的功能. 2025-06-15

为什么 mui button 的 api 叫 variant , 最初来源于哪里? ... antd 还有其他的 api 一样的版本吗? 由于大量项目已基于 antd 构建, 但需要换一套组件库, 希望新的组件库 api 和相应功能 都能对 antd做兼容, 应该怎么做? 最好的办法是什么? 应该基于哪个新的组件库来做呢? 有人用 Material UI 做兼容 antd 的 api 的中间层库吗? ... 学习 tailwind 应该要理解哪些重点和难点地方 tailwind variants vs cva ... 基于 React Hook Form 和 Zod 做一个新的 react form 组件, 使其功能和 antd 4 的 Form 组件一样, api 用法也一样. 2024-12

很多 react UI 组件库都有 variant 属性, 为什么这么命名, 作用是什么 作用都一样吗 chrome 插件 popup 页面, 怎么区分是在 新 tab 打开, 还是 弹窗里打开? https://chatgpt.com/share/674d2c48-8c94-8008-aca4-0ae4cc13eaa7 ... shadcn/ui ant-design material-ui 现状综合看哪个好、应该怎么选择? 基于哪个做二次开发比较好,成本怎么样? 需要面向未来、有一定先进性,应该怎么选? 想从 antd 迁移到新的 react 组件库, 要求 api 尽量一致或者改造成本低, 哪个新组件库符合要求? https://chatgpt.com/share/6749ea04-8f08-8008-9f30-132d8ec8071d 2024-11

tailwindcss 的 text-danger 等 className 使用。 2023


https://www.kylegill.com/essays/next-vs-tanstack/ React Trends in 2025 https://www.robinwieruch.de/react-trends/ 2025-03-27

------ misc

JPlag 相似度检查 原理 https://chatgpt.com/share/677e48dd-63b8-8008-b7d2-83c00c030fe8 不可行

  • 完全不修改
  • 修改了注释内容
  • 修改了函数名和部分变量名
  • 交换了部分函数调用的顺序
  • 更改代码逻辑中的部分条件判断
  • 改变代码结构,将主函数分解成多个小函数
  • 调整部分使用的数据结构
  • 彻底更换实现方式,使用不同的数据结构和逻辑
  • 功能完全不相关的其它代码 可行:
  • 改变代码结构,将主函数分解成多个小函数

代码转换: convert react class based apps to functional/hooks? https://transform.tools/ https://github.com/airbnb/ts-migrate https://github.com/reactjs/react-codemod https://github.com/facebook/jscodeshift https://astexplorer.net/

--- 文档工具 2024-11

------ 构建工具 (2024)

package.json 中的 browser 字段 主要由打包器识别 (如 Webpack Rollup Browserify), 不是 Node.js 原生识别. Jest 运行在 Node.js 环境中, 它解析模块时, 会使用 main(CJS)指向的模块, 不会关心 browser 字段. 当 package.json 中同时存在 "exports" 和 "main" 字段时:优先使用 "exports" 字段。如果没有命中 "exports",才会回退到 "main" 字段。

father 和 dumi

rollup,vite以及webpack比较与介绍

  • rollup 与 webpack 都是基于JavaScript依赖系统的一个打包构建工具,他们的共同点很多。 Rollup 默认打包为 ES6 格式、依靠插件生成 CommonJS 和 AMD 代码,静态分析代码中的 import 并排除任何未实际使用的代码。 Rollup 构建速度明显快于 webpack,生成的代码量很小。
  • 不过在应用开发层面讲,如果开发一个Web应用webpack要比rollup有更大的优势,因为其天然继承了devServer以及hmr,这使得开发者可以快速的对应用进行调试开发。 Rollup 更加适合插件开发,而webpack更加适合应用开发。
  • vite 号称是下一代的打包构建工具,主要体现在他从开发环境到生产环境的构建速度都能比webpack提升很多倍,原因就在于基于 rollup 和 esbuild 两个基础构建工具上。利用浏览器对ESM模块的支持,通过babel解决兼容性。将应用中的模块区分为 依赖 和 源码 两类,Vite使用esbuild预构建依赖、构建速度快 10-100 倍。在浏览器请求源码时、根据 router 按需以 原生 ESM方式提供 源码。利用 HTTP 头来加速整个页面的重新加载,源码模块的请求会根据 304 Not Modified 进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求。
  • vite 在生产环境打包也使用的 rollup,在预购建依赖的时候使用 esbuild。
  • esbuild 使用 go 编写,发挥多线程多核优势,不使用 AST。所以一些通过 AST 处理代码的 babel插件没有很好的方法过渡到 esbuild 中。

概述

  • 转译器: babel, tsc, esbuild (go语言 不使用 ast 兼容性差些), swc (rust 兼容 babel 插件)
  • 打包器: webpack(应用打包) parcel (零配置) rollup (组件打包) vite( bundleless) snowpack (bundleless)

umijs/father Bundle 模式使用 Webpack 作为构建核心,Bundless 模式支持 esbuild、Babel 及 SWC 三种构建核心。

  • 转译器: 将一门高级语音转译为另一种高级语言,如 ts 转译为 js、es6 转译为 es5 等等。 用js/ts实现的 babel、tsc 其他语言实现的 esbuild(go)、swc(rust)。
    • esbuild 不提供 AST 操作能力,一些需要操作 AST 的 babel 插件无法与之兼容。有两大功能,分别是 bundler 与 minifier,其中 bundler 用于代码编译,类似 babel-loader、ts-loader;minifier 用于代码压缩,类似 terser。
    • SWC 设计为与 babel 插件体系相兼容,因此可以在许多现有的 babel 配置下无缝替换,提升构建速度。
  • 打包器: 将项目中的各种文件如 png、sass、json 等等打包成想要的结果。
    • 一类是通过监听源代码变化然后重新构建项目将打包后的代码推送到浏览器的传统模式 如 Webpack、 rollup、 parcel
    • 另一类是通过浏览器的原生 module 来实现动态打包的 bundleless 模式 如 vitesnowpack 他们都依赖 esbuild 。
    • Bundle vs Bundleless(代表就是webpack VS vite)。 webpack 等工具会把代码打包成 Bundle 文件,而 vite 则是依赖原生的 ESM 来实现,虽然在生产环境仍然要打包。 在生产环境中发布未打包的 ESM 仍然效率低下(即使使用 HTTP/2)。为了在生产环境中获得最佳的加载性能,最好还是将代码进行 tree-shaking、懒加载和 chunk 分割(以获得更好的缓存)。
  • gulp 强调的是前端开发的工作流程,通过配置一系列的task,定义执行顺序,来让gulp执行。 webpack 侧重模块打包,我们可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。 对于 gulp 来说模块化不是他强调的东西,而 webpack 更强调模块化开发,而文件压缩合并、预处理等功能,不过是他附带的功能。

------ 框架 脚手架

https://github.com/web-infra-dev

bit 介绍 https://github.com/mcuking/blog/issues/88

框架 2021 umijs 蚂蚁前端框架和工程化 qiankun 子应用嵌套

业务脚手架 2021

------ 基础 UI 组件

--- UI 功能库 2024

--- UI 库 2024

基于 tailwindcss 的 UI 库:

自成一体:

antd tree-shaking antd-style 只能和 antd@5 配合使用 ant-design/antd-style#156

antd5 发布日志 https://www.yuque.com/ant-design/ant-design/cy5nfvdo8oidvwmz

antd4 发布日志

  • 暗色主题 无边框组件 图标按需加载 form/table重做 内置虚拟滚动
  • antd 3.x-stable

--- UI 功能库 2021

antd 2018

  • Table 伸缩列 bug多、性能
  • Menu 和 Modal <Menu.Item onClick={doSth} /> 里放子组件、子组件里有 <Modal onCancel={cancel} /> 弹窗,cancel 事件会触发 menu item 的 click 事件;弹窗里嵌套弹窗问题。
  • Select 组件
    • 下拉框和选择框样式分别自定义场景:比如 mode="multiple"labelInValueoptions 的 label 为定制的 jsx 时,可使用 Select.Option 组件 + optionLabelProp="label" 组合来避免 onChange 参数里的 label 是 jsx 、也能让选择框里 选项样式 能自定义。
    • 无尽列表翻页 issues/12406
    • 搜索框和单选选择框合并 0.12 效果1.x修改、1.0 changelog
    • 数据项有重复时 会乱跳,如视频:mp4
  • Upload 组件
    • 多文件合并到一个 xhr 里上传 issues/8579
    • 使用内部的 UploadList 来自定义进度条显示位置
    • umi-request 基于 fetch 实现、不支持显示上传文件的进度,而 axios 可以支持。
    • 使用beforeUpload来限制上传文件大小、customRequest自定义上传接口和上传进度。
  • Upload 上传文件/夹 (参考 语雀 或 teambition 上传资源)
    • 上传的文件或文件夹、都会存在一个fileList列表里,文件属性webkitRelativePath的值存在时、表示上传的是文件夹里的文件。onChange会在上传状态(上传中、已完成、失败等)变化时调用。
    • 多次点上传按钮时、可根据fileList里每个条目的uid标记来区分新旧。两次上传同一个文件夹时、需要 分别创建不同的文件夹名,比如后缀加上(1)。
    • 需要等待 所有文件都上传后 (即状态都是 done) 并且至少有一个文件上传成功,再创建目录。
    • 前端根据每个文件的webkitRelativePath值,循环构造出多层 文件夹 的层级数据,传给后端。
    • 后端一般需要起“异步”的任务、创建各级文件夹,前端轮询异步任务状态、判断是否成功。
    • 大文件分片上传和断点续传原理,需要使用 oss 提供的 sdk。
    • 文件夹里包含超过 300 个小文件,上传起始会卡顿、上传失败的文件优先显示、上传过程并发数的浏览器限制。
  • Popover 和 Tooltip 组件,children 如果不是元素、而是 {props.children} 不起作用。

antd-mobile 旧 demo 备份 2018

工程

命令 sh python docker

https://docs.python.org/3.13/index.html

--- Python

brew install python python3  # 一起安装 2.7.x 和 3.x
python -m SimpleHTTPServer 3435  # python@2
python3 -m http.server 3000

python3 --version  # python3 -V
python3 your_script.py
pip3 --version
pip3 list | grep vllm  # 查看安装的模块

# https://pypi.tuna.tsinghua.edu.cn/simple
# https://mirrors.aliyun.com/pypi/simple/
pip3 install requests -i https://pypi.tuna.tsinghua.edu.cn/simple
pip3 uninstall requests
pip index versions vllm
pip show vllm
pip show transformers torch sentencepiece

# venv 是 Python 标准库 创建虚拟环境 隔离项目依赖 避免依赖冲突
python3 -m venv myenv
source myenv/bin/activate
pip install xx
deactivate

# 在 ~/.zshrc 加上
export PYTHON_BUILD_MIRROR_URL="https://mirrors.tuna.tsinghua.edu.cn/python"
export PYTHON_BUILD_MIRROR_URL_SKIP_CHECKSUM=1
# 手动指定下载地址
pyenv install --url https://mirrors.tuna.tsinghua.edu.cn/python/3.10.12/Python-3.10.12.tgz 3.10.12
brew install pyenv
pyenv install 3.10.12
# ~/.pyenv/versions
pyenv versions           # 查看所有已安装版本
pyenv version            # 查看当前使用的版本
pyenv global 3.10.12     # 设置全局默认版本
pyenv local 3.10.12      # 设置当前目录使用版本
pyenv shell 3.10.12      # 仅当前 shell 会话使用该版本

--- docker

docker inspect harbor.xx/xx
docker inspect harbor.xx/xx | grep -A 5 -B 5 "Cmd\|Entrypoint"
docker history harbor.xx/xx
docker history --no-trunc harbor.xx/xx
docker build -t node-build-with-sh .
docker run -it node-build-with-sh
# 挂载工作目录
docker run -it -v /Users/hua/inner/xx:/workspace -w /workspace node-build-with-sh

docker run -it harbor./test/group/rd-efficacy/node-build:node18.16_npm9.5_lerna8.0.2_python3 sh

docker run -d --name node-build-dev \
  -v /Users/hua/inner/xx:/workspace \
  -w /workspace \
  harbor./test/group/rd-efficacy/node-build:node18.16_npm9.5_lerna8.0.2_python3 \
  tail -f /dev/null

# Docker 客户端与 Docker 守护进程(Docker daemon)进行通信.
docker stop # 会向 PID 1 进程 发送 SIGTERM,等待 10 秒,若未退出则发送 SIGKILL

------ shell

env / w / who / whoami / tty / last / mtr -r
echo "system: $HOME $PATH $SHELL"
printenv HOME  # 打印环境变量
printenv | grep npm_config  # 查看所有 npm 设置的 env
type/which/whereis npm  # fn_name  type -a node / pwd

say hello
open -a Activity\ Monitor # 打开活动监视器 或者 "Activity Monitor"
zip -e output.zip ~/xx.txt  # zip加解密

mount | grep /  # 查看系统挂载状态
sudo mount -uw /  # 挂载系统分区为可写  /sbin/mount
history 10 # 列出10条
timeout 3600 some-command

# curl 默认使用 http 协议, 可以省略 http:// 前缀
curl baidu.com
# 在 mac 上 xx.sh 里的代码不会执行 因为默认没权限. 先下载,再 chmod +x xx.sh 再执行
curl -O "http://xx.com/xx.sh"
curl -v -H "Content-Type: application/json" -H "X-App-Id: xx-cli" -H "X-App-Key: xx" https://xx.com/chat -d '{
  "jsonKey": "jsonVal",
  "jsonKey1": {}
}' | jq
curl -H "Content-Type: application/json" -H "X-App-Id: xx-cli" -H "X-App-Key: xx" https://xx.com/chat -d "@aa.json" | jq

nohup sleep 100 &
# 最后一个后台运行进程的 PID
echo $!
echo $! > "flag_file.log"

# nohup 不会随着 terminal 的关闭而停止、会在 系统关闭 时停止运行
nohup echo "Hello World"
my_command='echo "Hello World" && sleep 30'
nohup bash -c "$my_command" > output.log
nohup bash -c 'echo "Hello World" && sleep 30' > output.log
# 临时文件
echo 'echo "Hello World" && sleep 30' > /tmp/my_script.sh
chmod +x /tmp/my_script.sh
nohup /tmp/my_script.sh > output.log
# 如果不需要输出日志,可以将其重定向到 /dev/null
nohup bash -c 'your_command_here' > /dev/null 2>&1 &

--- Process status (进程状态, 非线程thread)

top #  man top
top -l 1 -o cpu | head -n 20
top -l 1 -stats pid,cpu | head -n 20

lsof -p 94979
lsof -i :8087   # 查找出占用了某个端口的程序和其对应的PID
kill 3747  # 杀掉 进程id
kill -9 *pid*  # 强制杀掉进程
pkill -P $$  # 杀掉当前 shell 启动的所有子进程
# 用 tmux 或 screen 可以让你在一个 shell 中开多个会话

ps     # 等价于 ps -p $$  # 只显示当前 shell 的进程
ps -ax
ps -ww -p 94979
ps aux | grep python
ps aux | grep xx.sh  # 列出正在运行的脚本进程
ps aux | grep "xx" | grep -v grep  # 排除 grep 本身的进程
ps -ef | grep adb  # 有时候 adb devices 没反应 需要杀掉进程重启
ps -ef | grep ttyd

pgrep -x 'ClashX'  # 获取应用的 pid
pgrep -f "ttyd zsh"  # -f 匹配完整的命令行
pgrep -f "ttyd -t disableLeaveAlert=true zsh"  # 参数解析后不一样 这里匹配不到
pgrep -f "ttyd zsh"> /dev/null  # 只返回输出码
pgrep -fx "ttyd -p 9999 -W -a zsh"
pgrep -u "$USER" -f "ttyd"
pgrep -u "$USER" -fx "ttyd -p 9999 -W -a zsh"

lsof "$z_log"
# z_log 文件正被进程 ttyd 打开, 文件描述符 1w 和 2w 表明它正在被用作标准输出和标准错误的重定向.
# 这时候 z_log 文件不能被其他进程 以 > 方式 写入内容, 改为 truncate -s 0 "$z_log" 处理.
# COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
# ttyd    1245  hua    1w   REG    1,6  16 65909077 /Users/hua/xx/z_log
# ttyd    1245  hua    2w   REG    1,6  16 65909077 /Users/hua/xx/z_log

# 后台运行命令 & 和 nohup
# 注意  & 会随着 terminal 的关闭 而自动停止运行
# 在 bash 里用 & 启动的是 背景进程(子进程) 不是 背景线程
/path/to/xx.sh >> /path/to/log.txt 2>&1 &
ttyd -W -a zsh >> log.txt 2>&1 &

# 在容器或脚本中 “hold 住” 进程
sleep 365d  # 临时方案. 启动一个容器或服务后,用 sleep 防止主进程退出
tail -f /dev/null  # 临时方案. 替代 sleep 方式
# 生产环境 优雅退出 trap + while sleep 1
trap cleanup SIGTERM SIGINT
while true; do sleep 1; done

--- file/dir

# 查看 符号链接 的真实地址
realpath node_modules/react
ls -l node_modules/react

# ls 命令默认只显示文件名
ls /usr/bin  # 有 env
ls /usr/local/bin  # 有 node npm npx
ls -d $PWD/*
ls -la
ls -l "$z_log"  # 查看文件是否有 读写权限,如无 运行 chmod u+rw "$z_log"
ls /Volumes/Macintosh\ HD/Applications
ls -lhR ./  # 递归列出目录内容
ls -R /mnt | head -40

# 清理系统缓存与日志, 能使 "设置 - storage - System Data" 占用显著变小
# 执行后最好 重启 系统
sudo rm -rf /Library/Caches/*
sudo rm -rf ~/Library/Caches/*
sudo rm -rf /private/var/log/*
sudo rm -rf /private/var/folders/*
du -sh ~/Library/Application\ Support/* | sort -h

cat -n fname
mv fname rename
more filename # 一页一页的显示档案内容.
head/tail -n 20 ~/.zsh_history  # 只看 头/尾 几行(默认10行)

mkdir -p ~/inner/aa && touch $_/file.txt  # 创建目录并能生成文件
ln -s source_file dist

rm -rf xx # rm 删除不存在的文件或目录 加上 -f 不会报错
# 删除 ai 目录下的指定后缀文件
rm -rf ai/**/*.d.ts ai/**/*.test.js ai/**/*.js.map

# 同步文件和目录
# 报错 cp: --exclude=a.txt is not a directory
cp -r test/* test1 --exclude=a --exclude='a.txt'
# 加引号 避免路径中间有空格
# 报错 cp: illegal option -- -
cp -r --exclude=a --exclude='a.txt' test/* test1

# 会排除掉 所有子目录 含有的同名 a.txt 文件
rsync -av --exclude='a.txt' --exclude='a/' test/ test1
# 在目标端删除源端不存在的文件
rsync -av --exclude='a.txt' --delete --dry-run test/ test1
rsync --version  # v2 不支持通配符
# 使用 .rsync-filter 文件配置
rsync -avF .rsync-filter test/ test1

# 创建一个临时目录用于存储 other-branch 的文件
mkdir /tmp/other
diff -r . /tmp/other
diff -rq . /tmp/other  # -q 只报告哪些文件不同
diff -r --exclude=".git" . /tmp/other
# 使用 --exclude="{.git,.svn}" 好像不正确
diff -r --exclude=".git" --exclude=".svn" dir1 dir2
diff -r --exclude=".git" dir1 dir2 dir3 > diff_output.txt
diff -r --exclude=".git" --exclude="node_modules" pro-components pro-componentsk > diff_output.txt

grep -rn 'grep' *  # 以 字符串 grep 来搜索 当前目录及子目录 的所有文件内容
grep grep$ she*.md  # 以 正则表达式 grep$ 来搜索 当前目录下 文件名匹配 she*.md 的内容
grep -r --include=\*.{cpp,h} pattern ./
grep -r --exclude-dir=node_modules pattern ~/

find . -name '*bash*'
find . -name "*.js" -not -path "*node_modules*" -not -path "*js-css-html*"
find . -name '*.DS_Store' -type f -delete   # 删除某目录及子目录下的 .DS_Store 文件
# find / -mmin -5   # 查找在系统中最后5分钟里修改过的文件(modify time)

# 如果文件存在则追加内容,否则创建并写入内容
# [ -f "$file" ] && echo "$content" >> "$file" || echo "$content" > "$file"
printf '\n%.0s' {1..10} >> $file

命令行 输入多行代码 并创建 文件

nano my.py  # nano: command not found

cat > my.py << 'EOF'
str='123456789'
print(str[2:5])
print ("Hello, Python!")
EOF

git

How I Use Git Worktrees https://matklad.github.io/2024/07/25/git-worktrees.html 2025-09-28

master 分支有新的提交 删除了大量文件, feature 分支 rebase master 时, 这些在 master 上被删除的文件 也被删除了, 怎么能保留下来? https://gemini.google.com/app/ade0b31c686aa747 https://chat.deepseek.com/a/chat/s/5ddee617-1471-45cc-8ebf-4456ccd2d8dd 在 feature 分支有个 commit 是基于 master 的一个旧 commit , 现在 master 有个新 commit, 修改了大量 feature 分支相关的内容, 怎么让 feature 分支 重新 rebase master 新的 commit, 而不需要解决冲突? 需要保留 feature 和 master 的改动, 把这些改动合并到一起. - 只能 merge 因为 master 的新 commit 删了代码文件, 但 feature 新 commit 仍有这些文件并可能有其他改动. 希望是以 feature 的代码为准. 即不能因为 master 的新 commit 删了代码, feature 分支也删掉. https://chatgpt.com/c/68a46f14-8c48-8323-bf88-be5975d38a82 2025-08-19

git 出现合并冲突时候, ff 和 no-ff 等操作过程和原理是什么? 图示演示一下. 2025-04-23

当前 head 的 commit 是 Merge branch , 前一个 commit 也是 Merge branch, 而 tag_name 是在第三个 commit 上. git diff tag_name 是空, 为什么? 是因为 当前工作目录或暂存区与标签对应的提交之间没有文件内容差异。 2025-04-22

git rebase squash 后, 还能找到 squash 前的 commit ID 内容吗? 2025-04-09

预期是 feature 流水线 如果是成功状态, 可以 直接合并代码到 master 分支. 问题:

  • 一天前 feature 分支流水线 运行成功, 半天前 master 有改动, 因为时差 导致 feature 分支的一些检查: rebase master 过期, feature代码本身无问题.
  • feature 分支和 master 有 git 冲突, 会在 release 分支产生 conflict 需要手动解决.
    • feature 分支 及时 rebase master 的更新, 可提前在 feature 分支解决冲突. feature 分支和 master 无 git 冲突, 但可能有 增删代码 的 逻辑冲突. 自动合并示例 (比如对 配置文件 .npmrc 的第12行 做修改. 或 package.json 的 dependencies 里):
  • feature分支 此文件 的第3行 后只有 2行 内容。
  • origin/master分支 此文件 的第3行 后有 5行 内容,并和 feature分支 的 后2行 内容完全不同。 此时合并结果为: 前两行(相同) + origin/master分支后5行 + feature分支后2行. 没有冲突 但结果不符合预期. 怎么解决?
  • feature 分支 及时 rebase master 的更新. rebase 时冲突可能解错.
  • 需要合并进 master 的多个 feature 分支, 按顺序 一个挨一个 合并. 不能解决.
  • 发布负责人 负责 review 逻辑冲突. 防止 误修改 问题. 2025-03-29

使用 gitlab 或 github 的 monorepo 项目, 怎么能在 目录或文件级别 做文件可见性的权限控制, 或者怎么监控文件是否被下载和转存到其他地方去过? Git子模块(git submodule)或子树(git subtree)的使用区别? https://chatgpt.com/share/67e401da-969c-8008-bb41-ad633ded15e8 https://chat.deepseek.com/a/chat/s/0b84021f-9c40-416f-8203-cde1b0009754 git submodule 示例 https://github.com/eclipse-ecal/fineftp-server 2025-03-26

在 monorepo 项目中 别人误改代码, 特别是 增删 代码时间差, 不会出现 git 合并冲突提示. 这些问题怎么解决? https://grok.com/share/bGVnYWN5_4183142b-9444-44e5-a1bf-8df9eaab4eb0 https://chat.deepseek.com/a/chat/s/95cd77b8-83cc-4d77-b070-f01354419422 https://chatgpt.com/c/67e2730c-bfb4-8008-804a-c72b94bd9469 https://github.com/Wilfred/difftastic 2025-03-25

Git 中的标准合并冲突检测通常依赖于识别相对于共同祖先提交在相似时间范围内发生的重叠修改. Git 的底层三向合并算法比较合并点处的文件状态及其最近的共同祖先。虽然这种机制通常对于同一行或近距离的并发更改有效,但它可能无法始终捕获由于分支历史中在明显不同时间执行的操作而出现的语义冲突。   例如,如果在一个分支中添加了一个函数,而稍后,另一个分支中删除了包含该函数的文件,尤其是在中间有提交的情况下,Git 可能不会将此标记为需要手动解决的冲突。这是因为,从 Git 的角度来看,在被比较的特定提交级别上,更改可能看起来不重叠。代码修改缺乏直接的时间重叠可能会导致语义差异,而 Git 的纯文本比较可能会忽略这种差异。 长期存在的功能分支虽然是某些开发工作流程中的常见做法,但可能会加剧此问题分支存在的时间越长而未合并回主线,其历史偏差就越大。必须承认 Git 冲突检测的固有局限性。它主要关注文本冲突,识别文件内容中的重叠修改. Git 本身并不具备对代码更改语义含义或它们之间的时间关系的理解。因此,在具有众多相互关联的项目和可能错综复杂的提交历史的复杂 monorepo 环境中,仅依靠 Git 的自动冲突检测通常不足以保证代码完整性并防止用户遇到的延迟冲突情况。 ... git 的合并冲突检测主要基于文本更改,即当同一行代码在不同分支中有不同修改时才会触发冲突。然而,逻辑冲突——即更改在文本上不冲突但合并后可能导致功能错误的场景——往往不会被 git 自动检测。例如,一个开发者添加了一个依赖某个变量的新函数,而另一个开发者删除了该变量,git 可能不会提示冲突,但合并后的代码会出错。 ... Git 合并出现冲突的原因在于 两个分支版本对一个文件的同一区域 做了修改。行级冲突提示. 如果是不同区域,Git 会尝试自动合并(auto-merge,默认策略)解决冲突, 但这可能引起逻辑错误。 不同大版本 不能通过 git合并代码 因为无法解决冲突:

  • 代码差异过大: 1.x 和 master 在文件结构、功能模块等方面差异较多。
  • 历史变更未同步: master 分支的某些改动未在 1.x 中体现。
  • 文件删除或重命名: 1.x 和 master 对同一文件的操作不同步。
  • 如果 1.x 和 master 需要长期共存,定期同步两者的改动,避免分支差异积累到难以处理的程度。 2025-03-25

本地 git tag tag_v1 commit_id1 后, 运行了 git rebase 导致 commit_id1 不存在了, 那么 tag_v1 能通过哪些方法获取到? git show tag_v1 可查看, tag_v1和commit_id1都还在仓库里. 如果运行 git push --tags 那么 这个 commit_id1 也会被推送到 remote 仓库里吗? 会的, 但这个 commit 不再由任何分支引用 不可达 (dangling objects) . 如果引用它的 tag 也被删除, 那么一段时间后(经过垃圾回收)该 commit 就会被清理掉. ... 远程仓库有些 tags 的 commit 是通过分支 不可达 的, 怎么检查出这样的 tag和 commit, 并删除他们? ... 悬空提交(dangling objects) 是指无法从任何分支或标签访问的提交. Git 定期执行垃圾收集来清理这些无法访问的对象,这最终可能导致从存储库中永久删除这些原始提交。但是,标签的存在,即使是指向旧提交的标签,也可以防止该提交被立即视为垃圾,因此可能会将其保留一段时间。如果在重新定基之前暂时需要访问存储库的状态,则这可能很重要。最终,指向不存在的提交的标签将充当无效引用,虽然它可能会暂时阻止相关提交立即进行垃圾收集,但它不符合使用标签进行可靠历史引用的预期目的。 GitHub上删除的分支是否保证不会泄漏数据? https://github.com/orgs/community/discussions/70144 https://stackoverflow.com/questions/33283350/what-happen-to-git-tags-pointing-to-a-removed-commit 2025-03-24

在 feature 分支打了 tag, 又进行了 git rebase master 导致 feature 分支的 tag 对应的 commit_id 不存在. 这种情况, 怎么更新 tag 对应的 commit_id? 要求能集成到 bash 脚本里. ... 在 feature 分支打了 tag 并推送到了远程 同名的 feature 分支, 发布后 remote feature 分支会被自动删除, 并把代码 Merge 到了 master 分支. 但 本地同名的 feature 分支仍然存在, 继续在此分支上开发, 并打了新的 tag, 那么当前 feature 分支关联了多少 tag? 远程的 feature 分支虽然被删了 但远程 tag 仍然存在, 远程 tag 对应的 commit_id 已经被合并到 master 分支, 还能查到 远程 tag 最初的 feature 分支来源吗? ... 使用 bash 实现以下功能: 检查 feature 分支 以及其对应的本地 commit_id 与 remote 的 commit_id 是否一样, 不一样则报错. 只检查当前 feature 分支相对 master 分支新产生的 git tags 和 commits 的情况. ... 怎么用 bash 判断本地feature分支 包含了 同名远程分支 的所有 commit ? 如果本地 feature 分支有过 git rebase 操作, 有哪些方法能识别出来? https://chat.deepseek.com/a/chat/s/a1b458c9-36b5-49a0-aed4-ac8e03361407 https://chat.deepseek.com/a/chat/s/09b782e5-cb72-425f-9ade-40dce19f84cf https://chatgpt.com/share/67e0fcfd-65d0-8008-8176-c4e7c00af263 https://gemini.google.com/app/9fe03b92a9586011 2025-03-24

运行 git pull (不是 git pull origin develop ) 会把 remote 所有分支的 tags 也拉下来吗? 不会. ... 当远程的 git tags 有更新时, 本地的 tags 怎么和远程保持一致? 有些标签对应的 commit_id 已经没有在 remote 仓库里, 这些标签应该也删掉吗? 2025-03-23

Git操作你还在用merge吗?字节一面:讲讲你对rebase的理解! 先说结论:不是merge不行,是rebase更优雅! 你以为git merge就够了?字节大佬教我:commit记录也是代码质量的一部分! 血泪教训1:分支历史混乱 merge的痛点:分支历史像盘面条 commit信息难追踪 代码回溯困难 合并冲突频繁. rebase的优势:历史记录线性干净 commit信息清晰 方便代码review 减少无效commit记录. 暴击伤害2:合并冲突地狱 字节实战翻车案例: 某项目上线前夕,多分支合并导致:解决冲突花了3小时 丢失部分代码改动 紧急回滚3次 项目延期2天. merge vs rebase 核心区别 merge方式:保留完整历史 分支结构复杂 适合长期分支 操作相对简单. rebase方式:重写提交历史 分支结构线性 适合短期分支 需要谨慎操作. 最佳实践总结

  1. 适合用rebase的场景:个人功能分支 短期特性分支 同步远程代码 提交PR/MR前
  2. 适合用merge的场景:长期维护分支 发布分支 多人协作分支 紧急修复分支 rebase进阶技巧
  3. 交互式rebase:合并多个commit 修改commit信息 调整commit顺序 删除无用commit
  4. 黄金法则:不要rebase公共分支 及时同步远程代码 解决冲突要谨慎 保持commit原子性 团队规范建议 面试官最爱问 技术深度:rebase原理 解决冲突策略 分支管理方案 Git工作流 实战经验:大型项目协作 冲突处理经验 分支管理实践 团队规范制定 记住一句话:用merge还是rebase,不是个人喜好,而是团队协作效率的保证! 2025-02-16 git 操作 https://m.toutiao.com/is/JG7lVw39SZU/

js工具库代码最新版本是 3.x,但需要修复很久之前的 1.x 版本的 bug,当前只有 master 分支,怎么用 git 管理老版本的代码升级? LTS(长期支持)策略 详解。 如果是 monorepo 项目,应该采用什么策略? 在老的 1.x 分支上拉了代码做改动,合并到 master 产生了大量冲突,怎么解决? 怎么在 git 提交历史中插入一个提交? 怎么把 某个 commit 改动的文件,应用到另一个分支上、但不携带改动之前的历史信息。 以上合并方式是什么?把改动的文件内容全覆盖,还是对改动的某些行进行交集合并,删除的文件或内容怎么处理? https://chatgpt.com/share/673dd191-0d74-8008-a826-16844c0b9bb5 2024-11

git 有很多 commit,一次性合并所有提交记录 git rebase autosquash 更详细用法 https://chatgpt.com/share/674ab367-c974-8008-9cdb-410303f51fe4 2024-09

bash 处理 git ls-remote --tags origin 和 git tag -l 获取到的字符串列表,并正则匹配到字符串里 refs/tags/ 之后的部分 2024-07

------ 总结

git .git/hooks/query-watchman

git 三板斧 (2018)

  • 一板基础斧 add, commit, pull/push, checkout, revert
  • 二板合作斧 merge, rebase, stash, cherry-pick
  • 三板优雅斧 commit --amend, rebase -i

https://gitlab.com/warmhug/test

https://github.com/paulirish/git-open https://github.com/sinclairtarget/git-who

lerna nx

使用 lerna@8 和 pnpm@7 , 在 lerna version 时, 因为搭配了 pnpm 就算不使用 workspace: 协议, 也能自动关联升级版本号. 是怎么实现的? https://chatgpt.com/share/6809e167-f024-8008-983a-3d3429470081 https://gemini.google.com/app/1660bddbb4205ab5 lerna/lerna#718 lerna/lerna#2326 2025-04-24

lerna 的 libs/core/src/lib/command/index.ts 里的 configureProperties 里的 execOpts 怎么修改? 怎么在调用 lerna 命令时传入这个参数? 怎么使用 lerna 的 ChangedCommand 类? 怎么让 lerna changed 命令忽略 Merge branch带来的代码变化? 2025-04-22

当前 master 分支 最新的commit 关联了 tag a b c, 此时有新的 feature 分支合并进 master, 就在 master 最新commit 之上新增了 2个commit 变为了 master 的最新 commit, 同时在 master 第 10 条 commit 位置, 插入了一周前的 feature 分支的多个 commit 进来. 这时候, lerna change 认为 master 上的 tag a b c 疑似失效, 显示这些 tag 对应的文件有变更, 实际上这些文件已经在 master 的 commit 里, 并且没有变更. 继续提问: 是使用 git merge --no-ff 合并的 feature 分支到 master. 也没有改变 master 已有的 commit hash , 只是把 feature 分支上一周前的几个 commit 合到了 master commit 时间线里, hash 也都没有变化. https://chatgpt.com/c/68021519-6b6c-8008-832d-e82255a913ba 2025-04-18

monorepo 工具 lerna changesets rushjs 功能详细对比? lerna 配合 nx 能实现 rush.js 的 增量构建、并行化、分布式缓存 功能吗? Rushjs 提供了构建缓存(build cache)功能,还支持阶段构建(phased builds)这些优化, 能节省公司使用云构建的机器成本吗? 比传统多仓库模式能节省多少成本? https://gemini.google.com/app/8f758441dfbc2494 https://chatgpt.com/share/67e3ee41-856c-8008-acea-945ed9ba627b https://chat.deepseek.com/a/chat/s/84c31b44-3b08-4cde-921f-01f077639dca 2025-03-26

lerna publish from-git from-package 详解? 为什么 from-git 适合 自动化 cicd 场景? 使用 from-package 时, --ignore-changes 为什么不起作用? https://chat.deepseek.com/a/chat/s/f8b25b55-f0f0-4851-a901-0156ddd8f5d8 2025-03-19

lerna 运行完 根目录的 version 钩子后, 虽然提示了要修改文件的版本号, 但程序那一刻 看起来还没有改动完成相应文件, 什么时候文件内容会被实际改掉? 改成 postversion 也不行. 2025-03-11

lerna 在 preversion 阶段会执行 package.json 里的 scripts, 但不希望明确写这个 scripts, 而是想由另一个脚本 动态设置 scripts 后传递给 lerna , 这样能实现吗? https://chat.deepseek.com/a/chat/s/aaea4f5c-0d71-4b54-b8f0-a6fc1d771ef1 https://chatgpt.com/c/67ce9933-a260-8008-8046-cff83664fe40 2025-03-10

lerna 在更新版本时候, 有什么钩子函数, 能打印出来新旧版本号吗? 现在是 lerna 结合 pnpm 的 monorepo 项目, 不想在每个子包都重复写 scripts 怎么能统一解决? 2025-03-09

lerna version 不能自动更改 npm alias 的版本号, 怎么解决这个问题? 怎么解决? 除了 lerna 有其他类似工具能解决这个问题吗? https://grok.com/chat/8e0fc14a-3f17-40a2-b7c5-99463c153087 https://grok.com/share/bGVnYWN5_2285de9a-750d-409c-a6a1-0c33cd067f1e https://chat.deepseek.com/a/chat/s/e1bbf052-b8a7-4064-81f9-b7fc3bfc426f 2025-02-26

monorepo same package name multiple version coexist 除了使用 npm alias 功能外, 还有其他办法吗? 使用中文回复. ... 通过以上提到的哪种方法, 能够解决如下报错 npm ERR! code EDUPLICATEWORKSPACE npm ERR! must not have multiple workspaces with the same name ... 使用 lerna 和 pnpm 并加入 project.json 文件, 可以让多个子包 package.json 有相同的 name 和不同的 version. 除此之外,还有更多的实现办法吗? ... 参考 https://stackoverflow.com/questions/26414587/how-to-install-multiple-versions-of-package-using-npm 回复最好 https://gemini.google.com/app/4c2ea1e657922b90 2025-02-24

需要在 monorepo 里存在 同名包的 不同版本, 怎么实现? lerna 和 pnpm 支持 通过 project.json 能让存在 同名包的 不同版本, 使用 npm 能做到吗? https://chatgpt.com/c/677fbce1-c1d8-8008-ba11-f56bad58fa80 2025-01

在 2022/05 的时候 Next.js 在这个 PR#37259 从yarn 转移到了pnpm,原因是使用pnpm 帮助他们降低了下载套件的大小,而且找到了一些幽灵依赖,并在 CI 上安装套件的速度从 4 分钟降低到了 2 分钟。 ... 将 50 万个文件放在一个 Git 存储库中 2024-10

https://jamiemason.github.io/syncpack/

------ nx

在 lerna@8 + pnpm@7 的 monorepo 项目里, 因为存在两个相同的包名, 虽然通过 project.json 做了区分, 但 lerna 背后的 nx 对于内部包之间的 依赖解析 仍然有问题. https://gemini.google.com/app/f2ce6aaf2219c618 ... 使用 pnpx nx graph 分析内部包之间的依赖, 发现部分内部依赖缺失? 因为 lerna 背后实际是 nx 在检测依赖. 写死版本号, 或使用工作区协议(workspace: 或 file: 协议) 会被检测到. 但如果依赖版本号是 ^ 开头 则检测不到, 因为 SemVer ^ 范围并不是“协议” 只是 NPM 在安装时的解析策略,Nx 的项目图器并不去解析 SemVer 范围,它只信任显式的工作区协议或基于代码的导入。 https://chatgpt.com/c/6804b4b9-bc04-8008-b378-803e803e9f9e 2025-04-20

nx implicitDependencies 怎么理解和使用? pnpm build 有类似 nx implicitDependencies 的功能吗? 或者怎么能实现这样的效果, 特别是在处理 npm alias 这种场景时. https://chatgpt.com/c/67f8cedd-9b20-8008-b596-daa0e9c3bb7c https://gemini.google.com/app/c5def5cfe22d8825 https://chat.deepseek.com/a/chat/s/bfe64f5d-98e5-4481-8332-b738c1926eb6 2025-04-11

使用 Nx 进行构建时,.nx 目录用于存储与构建相关的缓存和数据 .nx/cache/ .nx/installation/ .nx/workspace-data/ 这些目录包含特定于本地环境的临时文件,不适合纳入版本控制。在 .gitignore 里忽略掉. 使用 Nx 提供的分布式缓存功能,在团队内部共享缓存. 2025-03-13


https://nx.dev/concepts/decisions/why-monorepos 依赖管理 https://nx.dev/extending-nx/recipes/project-graph-plugins

Turborepo (类似nx) 解决了 Monorepo 的问题。我们的远程缓存存储您所有任务的结果,这意味着您的 CI 永远不需要做同样的工作两次。 任务调度可能是困难的,想象 yarn build 需要运行前 yarn test ,在所有的工作空间。Turborepo 可以调度您的任务,以最大的速度,在所有可用的核心。

------ 总结

Monorepo 的核心优势之一是根目录下的单一锁文件(pnpm-lock.yaml, yarn.lock, package-lock.json),它保证了所有子项目依赖版本的一致性。在子目录中单独安装会创建独立的锁文件,破坏了这一优势。

[email protected] 里的 lerna.json 的 ignoreChanges 不支持 "!commons/xx/lib/**" 这样的 否定匹配, 但 git 的 .gitignore 文件支持.

lerna 项目存在 相同的 pkgName 不同的大版本 1x 2x 3x 怎么管理

  • 加入 project.json 文件, 内容为 { "name": "[email protected]" } 或 { "name": "[email protected]" } 利用了 nx 的特性.
  • nx 报错: lerna ERR! lerna To fix this, set a unique name for each project in a project.json inside the project's root. If the project does not currently have a project.json, you can create one that contains only a name.

lerna changed 和 list 行为不一致:

lerna tag(仅支持 annotated tags) 与 commit

  • lerna changed 会根据 annotated tag 判断是否升级版本.
  • 如果 lerna tag 对应的 commit_id 被 squash/rebase 而不在 git 历史里. lerna version 就不会基于这个 tag 的版本号 来升级版本. 解法: 修改 tag 对应到新的 commit_id, 强推覆盖远程的已有 tag.
  • 如果你的项目使用了规范化的提交信息(例如,使用 commitizen 和 cz-lerna-changelog),Lerna 可以更准确地检测变更,因为它会根据提交信息中的标签来识别影响的包. lerna/lerna#2437 lerna/lerna#1569 lerna 发包原理浅析

lerna publish 参数 from-git from-package

  • 如果 lerna publish 失败,使用 lerna publish from-git 重新发布,不用改版本号。
  • 设置 from-git 或 from-package 后不会运行 lerna version 也不检测文件变更.
  • 设置 --ignore-changes 只对 lerna version 或默认的 lerna publish(包含版本生成阶段)有效.

Lerna always uses npm to publish packages. https://lerna.js.org/docs/features/version-and-publish

uncommitted changes 阻止发布

lerna.json 配置项 https://github.com/lerna/lerna/blob/main/libs/core/src/lib/project/index.ts#L28 使用 [email protected] 在 /usr/local/lib/node_modules/lerna/dist/index.js 文件的 10480 行, 调试: console.log('log concurrency: ', this.concurrency, Object.keys(this)); this 对象的 keys 为: [ 'options', 'concurrency', 'toposort', 'execOpts', 'argv', 'name', 'composed','runner', 'script', 'projectsWithScript', '_project','logger', 'projectGraph', 'projectFileMap', 'args', 'npmClient', 'bail', 'prefix', 'count', 'packagePlural', 'joinedCommand' ]

deps

pnpm 在单 package.json 仓库里 能发现幽灵依赖吗? 在 monorepo 仓库里 发现不了子包的幽灵依赖问题? 使用 pnpm@7 发现只有 根目录的 依赖, 会被安装到 根目录的 node_modules 中, 子包的依赖 有些被安装在 子包目录的 node_modules 中,有些是在 根目录的 node_modules 的 .pnpm 里. 这个逻辑是什么? https://chat.deepseek.com/a/chat/s/92301748-7afa-491b-b44b-a5e248b1170a 2025-08-27

在 lerna@8 + pnpm@7 的 monorepo 项目里, 各个子包 虽然依赖了相同的 typescript @types/react 等 大版本, 但因为有些作为下层依赖 ts 类型包 比如 @types/estree 1.0.6 的 patch 版本问题, 导致上层 ts 类型编译报错. 通过 pnpm 的 overrides 方式 统一版本 能临时解决, 但很不优雅 也引起版本锁定问题. 另外排查这类问题 很费时间 怎么有快速的排查方式? 最终更好的解决方案是什么? 如果确实需要存在比如多个版本的 @types/estree 给不同的包使用, 应该怎么做? https://gemini.google.com/app/0cf7e56b21800f66 https://chatgpt.com/c/68aeb81b-6c44-8329-8577-d8d299e94ea8 https://www.tongyi.com/?sessionId=f2a1764a92bc4704a5a97026fc182889 2025-08-27

两个包互相依赖, 一个包依赖另一个包的 ts 定义, 一个包依赖另一个包的源码. 在 lerna pnpm 的环境中, 怎么构建? https://gemini.google.com/app/4c8d09b0bb7d0795 2025-08-21

npm 包 xx 的依赖版本是 @types/react: * 时, 在 monorepo 里存在 @types/react 16 17 18 多个大版本, 这个 xx 实际安装的 @types/react 版本是什么? ... 公共源的某些npm包, 在公司内部源没有. 通过 bundledDependencies 先从公共源下载, 在公司内部源发布. 能解决问题吗? https://chatgpt.com/c/68826ea0-4564-8008-b420-5b51b36eaaa9 2025-07-25

如果一个二级依赖的 patch 版本号升级, 在项目中对一级依赖进行 pnpm uninstall 再 pnpm add , 这时候二级依赖版本号 仍然没升级, 是怎么了? npm yarn 分别是怎么处理二级依赖的版本的? 因为项目里 A 里有多个依赖 比如 B B1 B2 都需要升级, 怎么能 pnpm up A (但此时 A 的版本号不变), 能让其依赖 B B1 B2 的 patch 版本都自动升级. 而不是 pnpm up B --depth=2 ? 2025-06-29

pnpm workspaces 某个子包 aa 的 dependencies 含有这样依赖 "demo": "workspace:demo2@*" 其中 demo2 是另一个子包的包名. 当在 workspaces 根目录 运行 pnpm --filter "aa..." build 时候, 预期是 demo2 的子包需要先运行 build 命令, 但实际未运行. 这是因为 pnpm 默认把 npm alias 的依赖, 当做 外部依赖 解析, 需要额外的解决方案, 应该怎么做呢? ... 需要做到 自动化工具构建, 能通过给 pnpm 写插件等方式, 补足这个功能吗? 应该怎么写? https://gemini.google.com/app/74b4f952721158d0 2025-05-27

为什么使用 ^2.2.12-alpha.3 在 npm install 时候安装的不是指定的这个版本? 2025-04-21

不同子包依赖了不同的 ts react react-router 版本, 在 pnpm 下会互相影响? 源码存在 import { Route, StaticRouter } from 'react-router-dom'; 时, ts 会报错 Route, StaticRouter 不存在. 2025-04-09

在 pnpm(v7) + lerna 的 monorepo 项目, 为了能让各个子包 使用各自不同的 react 版本, 在子包 package.json 的 devDependencies 里安装 @types/react 包, 在子包 tsconfig.json 配置 "paths": { "react": ["./node_modules/@types/react"] } 只解析当前目录安装的 @types/react 内容. 但 @types/react 本身依赖的 csstype 等包, 是被安装在 根目录的 node_modules 里, 如果子包 有源码 调用 React.CSSProperties 类型, 就会报错 TS2339: Property 'position' does not exist on type 'CSSProperties'. 解法: 在子包 package.json 的 devDependencies 里, 加入 @types/react 包依赖的 csstype 等包. 使其都能在当前目录的 node_modules 里被找到, 问题解决. 2025-04-09

场景: 项目的 build工具(依赖ts@3), 但项目本身(依赖ts@4), 在使用 npm(@9) 构建时候 无报错, 但使用 pnpm(@7) 构建时 对源码的 ts 语句解析报错. npm 和 pnpm 分别这么处理:

  • npm: 直接使用 根目录 node_modules 的 ts@4 来解析 build工具+项目 的源码, 虽然 build工具 是依赖的 ts@3 但使用 ts@4 来解析 "凑巧"也没有错误.
  • pnpm: 会使用 build工具的ts@3 来解析 项目源码, 导致解析报错, 因为项目源码需要 ts@4 来解析. 参考: lerna@8 的 dependencies 里这么声明 ts 依赖 "typescript": ">=3 < 6", 确保使用方 不受其版本锁定的影响. ... npm(@9) 依赖提升Hoisting, 默认会将所有依赖提升到 根目录 node_modules. pnpm(@7) 严格依赖隔离, 默认不会提升依赖, 每个子包的 node_modules 仅包含其显式声明的依赖, 使用 硬链接和符号链接. pnpm 不会默认进行大规模的提升。它使用符号链接(symlinks)的方式,在项目的 node_modules 里只精确地链接项目直接依赖的包。而这些包自身的依赖,则位于一个集中的内容寻址存储区(通常是项目根目录下的 .pnpm 文件夹内),并通过符号链接按需链接到对应包的 node_modules 目录下。 https://gemini.google.com/app/c1b7c1ac21903ab2 ... moduleResolution 总结 2025-04-08

lerna + pnpm 的 monorepo 项目, 在子包里单独引入 TS 的版本, 怎么能不受 根目录的 @types/react 版本影响? 2025-04-06

pnpm monorepo 怎么查看除了内部 link 包之外的其他包依赖, 在 registry 是否存在? 如果没有直接的命令, 写一个 node js 脚本来实现. ... 内部链接的版本号, 可以以 workspace: 或 file: 开头, 但也可以不是以它们开头. 因为 pnpm 提供了 prefer-workspace-packages 和 link-workspace-packages 设置, 能够自动匹配引用 monorepo 内部有相同包名的其他 package. 怎么识别并处理这种情况? ... 包所在不一定只是 packages 目录内, 而是在 pnpm-workspace.yaml 配置中指定的, 可以通过 pnpm list --json -r 来获取所有内部包, 基于此再做过滤. ... https://chat.deepseek.com/a/chat/s/f2241a08-daf7-4c21-b266-ef53b3d836e6 2025-03-06

运行 pnpm -r run build 构建问题. 在 monorepo 里运行 pnpm run build 时, 因为有对 build 出的目录删除操作, 如果不设置 workspace-concurrency=1 就会报错, 但设置后速度就很慢. 应该怎么解决? https://gemini.google.com/app/f37076c19be3c895 2025-04-11 在 npmrc 里设置 workspace-concurrency=1 (注意与--parallel区别) 的用途:

  • 避免并发引发的竞态问题: 各个子项目在构建、清理或其他任务中可能存在共享资源(比如同一个目录、文件或网络资源)的写入冲突,强制串行执行可以防止由于并发操作带来的竞态条件和文件锁冲突。
  • 任务之间存在依赖或副作用: 当某些任务必须按照严格的顺序完成,或者前一个任务的产物会影响下一个任务的执行. 在设置 pnpm 的 workspace-concurrency = 1 时候, 怎么利用 nx 能缓存构建结果加速构建过程? 2025-03-13 pnpm -r run build 怎么先构建被依赖的包? 对于 npm alias 形式的依赖, 没有先构建 dependencies 是怎么了? 2025-02-28 使用 pnpm 未把 dependencies 构建完成,而导致 dependent 构建失败的问题 https://stackoverflow.com/questions/72216431/how-to-control-pnpm-workspace-build-order 2025-02

npm 的 dependencies 写了 latest, 是怎么解析版本的? 如果 最新发布的版本 是个 alpha 但不是 latest 标签, 会对它做解析吗? 这个最新的 alpha 版本的依赖有缺失, npm install 包的 latest 版本时, 实际不应安装这个 alpha 版本, 但 先对这个 alpha 版本 报错 No matching version found, 导致 安装失败. 是为什么? 2025-02-13 https://chatgpt.com/share/67ad9bcd-913c-8008-aa33-1edb177b7203

npm install --legacy-peer-deps npm v7+ 默认 自动安装各个包的 peerDependencies 但使用了 --legacy-peer-deps 则不会安装, 需要 包使用者(比如业务仓库) 在 dependencies 或 devDependencies 中自行安装. 使用 --legacy-peer-deps 的主要风险是运行时兼容性问题。由于忽略了 peer 依赖检查,安装的包可能在运行时无法正常工作。例如,某个组件库可能依赖 react@16 的特定 API,而项目使用 react@17,可能导致功能异常。 2025-02

前端或 node 项目, 引用A包的时候,比如A引用了B,B里面有overrides/resolutions,最终会装 overrides / resolutions 指向的包吗? 主项目的 overrides/resolutions 优先级最高,覆盖所有依赖。 如果主项目没有定义,子依赖的 overrides/resolutions 只会影响其自己的依赖树。 ... 怎么在运行 npm start / build 之前, 确保 node_modules 里的依赖有被重新 insall 过 2025-01

npm version 怎么自动升级 monorepo 的 子包依赖版本号 pnpm 只检查并保持 workspaces 内部包 的最新版本,写成 bash 脚本 2024-06

p/npm

pnpm 安装 jest 分析一下 node_modules 结构. 比如 .pnpm/@[email protected][email protected]/node_modules 路径里为什么有 ts-node ? node_modules/jest/node_modules/.bin/jest 文件里 export NODE_PATH node_modules/.pnpm/[email protected]_emg2r4tyatcnbgvb4hel57idem/node_modules/jest/bin/node_modules https://gemini.google.com/app/5c8016f5723f0933 2025-08-27

pnpm v7 里 public-hoist-pattern 和 hoist-pattern 和 hoist 区别? hoist-pattern 默认值是 ['*'] 如果在 .npmrc 里设置了 hoist-pattern[]=eslint 最终的 hoist-pattern 值是什么? https://chatgpt.com/c/68aed297-1fd4-8332-b822-c4e5d5ef8022 2025-08-27

在 lerna@8 + pnpm@7 + [email protected] + [email protected] 的 monorepo 项目里:

  • 使用 pnpm publish ./dir/subdir 或者使用 lerna publish 两种方式都不会报错.
  • 使用 npm publish ./dir/subdir 命令发版本. 绝大多数子包 都能正常发布成功, 只有部分子包报错 npm ERR! Cannot set properties of null (setting 'peer') 升级 npm 版本为 10.x 版本 不会报错. 为什么 pnpm publish 不报错? 这时候 pnpm 和 npm 有什么关系? 是应该使用 pnpm 还是 npm ? 如果使用 lerna publish 时, 背后实际使用的是 pnpm 还是 npm ? 发包命令封装在了一个单独的 npm 包中, 默认使用的是 npm publish . 但使用它的项目可以是 npm pnpm yarn 等各种包管理器, 这个抽象出来的 npm 包 应该怎么兼容项目里不同包管理器的情况? https://gemini.google.com/app/695adcd1a1cb940e https://chatgpt.com/c/68a85205-0acc-8321-9a95-da9ba8e7805c 2025-08-22~27

const rl = readline.createInterface({ input: res, crlfDelay: Infinity, // Recognizes '\r\n' and '\n' as line breaks }); 如上 res 是个 流数据, 需要一行行读取. 其实际内容如下 data: { "response": { "modelVersion": "gemini-2.5-pro1" } }\r\n\r\n data: { "response": { "modelVersion": "gemini-2.5-pro2" } }\r\n\r\n data: { "response": { "modelVersion": "gemini-2.5-pro3" } }\r\n\r\n res 是 PassThrough 对象, 需要先读取到这个对象的实际数据, 做一些修改, 再构造出一个新的 PassThrough 对象. 2025-07-23

在 node 模块里, 一个函数 需要返回一个 await axios.request() 值. 但又希望不请求真实的服务器地址, 而是直接返回给定的mock结果, 应该怎么做? 2025-07-22

运行 pnpm store prune 后, 安装遇到如下问题, 是因为本地缓存吗? This error may happen when a package is republished to the registry with the same version. In this case, the metadata in the local pnpm cache will contain the old integrity checksum. 没有 republish 但同一个包同一个版本, 发布到了 不同的 registry 上. 是这个问题吗? 2025-07-20

对于 responseType: 'stream' 的 http 输出, 使用 node 的 readline.createInterface 可以按行读取内容, 怎么能一次全部读取 而不用按行读? 2025-07-16

pnpm workspaces 会统一添加子包的依赖到根目录的 lock 文件里, 怎么排除某几子包? ... 因为公司内部源不全, 安装外部包时 怎么把其依赖的 node_modules 也作为源码, 但不叫 node_modules 这个名字. ... 开发阶段的 npm 包设置了 bin 怎么能给其他目录的调用者使用? 2025-07-13

package.json 的 browser 字段值, 可以怎么写, 分别起到什么作用? jest 是使用什么 编译和打包 工具? 是调用 package.json 里的 main 还是 browser 指向的模块? 设置了 testEnvironment: 'jsdom' 之后, 会使用 browser 指向的模块吗? https://chatgpt.com/c/6844032d-7350-8008-a325-40da589b8176 2025-06-07

pnpm v7 的 list 命令 怎么能 exclude peer dependencies https://chatgpt.com/c/68382b61-8408-8008-b85a-2064c39c1dd1 2025-05-29

修改了 registry 但需要保持原 registry 生成的 pnpm-lock.yaml 文件的版本号一样, 并自动修改 resolution 的 integrity 和 tarball 字段. pnpm/pnpm#6667 https://stackoverflow.com/questions/62439074/override-registry-for-installed-packages-in-package-lock-json 可行方法: 先用 pnpm install --fix-lockfile 更新 lockfile, 再手动替换 tarball 字段的 registry URL 为新的. 2025-05-26

详细解释一下 re2 这个包的作用, 以及其与 node-gyp 编译了什么? node-re2 是一个 Node.js 模块,它封装了 Google 的 RE2 正则表达式引擎,避免潜在的 ReDoS(正则表达式拒绝服务)攻击。保证线性时间复杂度,从算法层面杜绝 ReDoS。 node 的 ajv 包 devDependencies 依赖了 re2 , re2 依赖了 install-artifact-from-github 和 node-gyp . 在 安装包过程中, re2 会尝试下载 https://github.com/uhop/node-re2/releases/download/1.20.12/darwin-x64-108.br 这个预编译文件, 若无预编译二进制 调用 node-gyp 编译 RE2 源码,生成适配当前环境的 .node 文件。 https://gemini.google.com/app/8db2f2b251d9f63e ... 在 package.json 里的 pnpm overrides 字段, 怎么指定使用 workspaces 里某个包的版本, 并自动跟随版本变化. 2025-05-21

同一个 npm 包, 在不同的 registry 的 integrity 为什么不一样, 怎么修复? 如果是从其他 registry 同步到另一个 registry 的包, 他们的 integrity 一样吗? 切换 Registry 之后, 使用 node 脚本修改 lock 文件, 需要让 lock 文件里的依赖包名和版本号都不变. 应该怎么处理? https://gemini.google.com/app/8bd107edfc557f66 2025-05-13

现有不同的 git 仓库, 其内部代码大致一样, 但 npmrc 不同. 虽然已经用 process.chdir 切换到了相应的目录. 但随后在运行 child_process spawn 时候, process env 里的 npm 相关配置 设置使用了 chdir 之前目录的配置. 这跟 spawn 的 cwd 设置有关系吗? 应该怎么解决? 怎么知道在设置 cwd 后, spawn 函数执行时候的 process env 参数有哪些? https://gemini.google.com/app/c3b2f45e5789965b 2025-05-08

使用 npm child_process exec 调用 npm publish ./dir 怎么获取发布包的成功和失败状态, 以及包的 name 和 version 信息? 2025-05-06

使用 nodejs 删除 pnpm-lock.yaml 里的 resolution 下的 tarball 字段, 其他内容保持不变. 2025-04-27

pnpm 里没有和 npm 的 omit-lockfile-registry-resolved 一样作用的配置吗? pnpm 能生成和使用 npm-shrinkwrap 文件, 代替 lock 文件使用吗? 2025-04-16

项目 package.json 里的 packageManager 作用, 为什么能让系统安装的 pnpm 版本不生效? 2025-04-15

npm install 时生成的 lock 文件里每个包的 integrity 字段用于确保包文件的完整性,其值通过特定算法计算文件内容的哈希值生成。包内容相同则 integrity 相同,与不同的 registry 无关 与 yarn pnpm 等包管理器无关. 若内容有差异(如恶意篡改、非官方修改版 即使版本号相同),则 integrity 不同。 是 npm 利用 integrity 防止包被恶意篡改的核心机制。 怎么能不生成 package-lock.json 文件里的 resolved 和 pnpm-lock.json 文件里的 tarball 字段? npm/npm#16849 2025-04-15

pnpm install 后的 lock 文件里的 tarball 字段的生成规则是什么? 生成的结果是 tarball: npm/@types/babel__traverse/-/babel__traverse-7.20.7.tgz 但实际多了 npm/ 前缀, 是什么原因? 这个前缀导致下载这个包时报了 404 错误. 虽然有 npm/ 前缀, 在本地电脑运行 pnpm install 不会报错, 但在流水线里会报 404 错误. 什么原因? 2025-04-14

npm 和 pnpm 在 .npmrc 文件里 可通用的配置项 都有哪些? 怎么让 pnpm 保持和 npm 一样的 模块安装方式, 不要有 node_modules/.pnpm 目录. 2025-04-08

单独的 npm 包 execa 里的 sync 和 child_process 里的 execSync 的区别? https://chat.deepseek.com/a/chat/s/9af55d01-f490-46bc-b8a5-677cd1a2a3bc 2025-03-17

使用 pnpm 安装了依赖, 但在 package.json 的 scripts 里使用 npm run lint, 这样有问题吗? 如果是 monorepo 项目, 在子包里运行, 怎么查找 bin 下的二进制文件? https://chat.deepseek.com/a/chat/s/133eb6d1-d73f-4457-b92a-8a725cad3d1d 2025-03-13

使用 pnpm 为了避免在 package.json 里声明, 在 postinstall 或 prepare 阶段 安装一个依赖, 怎么能避免自动修改 lock 文件. ... 结果 "scripts": { "postinstall": "pnpm install nx@latest --lockfile=false --ignore-workspace --dir ./tmp", } https://chatgpt.com/c/67cd4e89-f4a4-8008-b5e1-89bfe0c831a8 https://chat.deepseek.com/a/chat/s/3c5acb32-1b6b-4e8c-9808-25ebc8f419d8 https://gemini.google.com/app/9f8cca7169306de3 2025-03-09

npm yarn 和 pnpm 的 lock 文件内容结构详细解释? 现在使用 pnpm 工具, 有两个环境, 比如 A 环境 registry 是 https://ra.com 生成了 lock 文件. 但 B 环境 registry 是 https://rb.com , 希望复用 A 环境生成的 lock 文件, 怎么做到? pnpm-lock.yaml 文件里的 tarball 地址, 怎么能不区分 ra rb 的域名? 2025-01

lockfile 出现合并冲突,主流的包管理工具都支持运行依赖安装命令(npm install/yarn/pnpm install)来自动解决冲突。 在 主分支 上合入 开发分支(git merge feat-branch),theirs 指的就是开发分支,ours 指的是主分支,如果两个分支同时更新同一模块的版本号、对 lockfile 进行合并的策略:

  • npm: 深合并,并以当前分支( ours )的为准
  • yarn: 浅合并,并以目标分支(theirs)的为准
  • pnpm: 深合并,以版本号大的为准 (认为 新版本出现的问题会比旧版本更少)
    • 关注直接依赖 搜素 specifiers 的版本变更,对于直接依赖引入的间接依赖,自动升级出错的概率较小(一旦出错影响的不只一个项目),且 review 成本太高,选择信任社区。
    • 支持在每个分支中生成锁文件 pnpm/pnpm#4475
    • @types/react 18.3.5 bug 在 package.json 设置 resolutions 锁定版本。

------ 版本号

某个版本的 nodejs 可以使用非自带的 npm 版本吗, 有版本范围要求吗? 2025-08-26

这个返回什么 semver.satisfies('0.0.11-beta.0', '^0.0.10', { includePrerelease: true }) https://gemini.google.com/app/858055839ab4ed51 只有 gemini 2.5pro 回答正确, 其他的最新模型 ChatGPT@5 grok@4 deepseek 千问 豆包 Kimi 全部回答错误. https://stackoverflow.com/a/77837308/2190503 ^0.0.1 - 0.0.1 (即使有 0.0.2 npm update 也不会升级) ^0.0.z won't update anything, because there is no element after z . 2025-08-25

node-semver 怎么获取 Tilde 或 Caret 标记? 代码依赖里一般都写 Tilde 或 Caret 标记, 怎么用 node-semver 做解析? 2025-03-05

确保依赖版本始终同步的一种常用方法是,在 package.json 中为工作区包的依赖项指定严格的版本号,而不是 ^ 或 ~ 这样的语义版本号范围。这样做可以避免依赖更新时出现的意外问题。

对于应用项目来说,可以直接使用固定版本;但是对于类库项目,不推荐固定版本,有以下原因:

  • 依赖该类库的应用项目无法充分复用依赖: 比如 ^1.0.0 和 ^1.1.0 可以合并成 ^1.1.0)
  • 类库项目的间接依赖出现安全漏洞时,无法通过重新安装依赖直接修复
  • 锁定直接依赖的版本也不完全有效,丢失 lock 后,直接依赖的间接依赖还是会进行升级,进而导致 BREAKING CHANGE
  • 锁版本 就得信任其他依赖不会出现问题(听天由命)
  • 尽量由开发流程保证,有冲突就复测,并做好充足的人工 review

在开发一个 npm包 时,你的 npm包 是需要被其他仓库依赖的,由于扁平安装机制,如果你锁定了依赖包版本,你的依赖包就不能和其他依赖包共享同一 semver 范围内的依赖包,这样会造成不必要的冗余。所以我们不应该把package-lock.json 文件发布出去( npm 默认也不会把 package-lock.json 文件发布出去)。

npm 包的主版本号为 0 时,会被认为是一个不稳定版本,主版本号和次版本号都为 0: ^0.0.z、~0.0.z 都被当作固定版本,主版本号为 0: ^0.y.z 表现和 ~0.y.z 相同,只保持修订号为最新版本。 1.0.0 的版本号用于界定公共 API,对外部发布一个正式版本的npm包时,把它的版本标为1.0.0。

pre-release 预发布版本号的排序规则是: 不同预发布版本类型之间 alpha < beta < rc < release(即稳定版本,没有预发布标识符)。 同一预发布版本类型下,数字越大,版本越新,例如 1.0.0-alpha.1 < 1.0.0-alpha.2。 比如 rc-0..n > beta-0..n > alpha-2.. 2024-07~12

------ 总结

npm源 http://registry.npmjs.org/esbuild/0.21.4 ali源 https://registry.npmmirror.com/esbuild/0.21.4 腾讯源 https://mirrors.cloud.tencent.com/npm/esbuild/0.21.4 https://docs.npmjs.com/cli/v10/commands/npm

https://docs.npmjs.com/cli/v10/using-npm/config https://docs.npmjs.com/cli/v10/configuring-npm/package-json https://docs.npmjs.com/cli/v9/using-npm/config http://yarnpkg.com

https://jpospisil.com/2017/06/02/understanding-lock-files-in-npm-5

https://npmtrends.com/lint-staged-vs-pre-commit-vs-pretty-quick https://www.npmtrends.com/jsplumb-vs-mxgraph

node/npm 各个大版本 发布时间: https://nodejs.org/en/about/previous-releases https://www.npmjs.com/package/npm?activeTab=versions https://github.com/npm/cli/releases

https://www.npmjs.com/package/npm-check https://www.npmjs.com/package/depcheck

--- pnpm

http://pnpm.io 注意: 从 pnpm/CHANGELOG 里查看 API 的变更. https://github.com/pnpm/pnpm/blob/main/pnpm/CHANGELOG.md https://github.com/pnpm/pnpm.io/blob/v7/docs/npmrc.md https://github.com/pnpm/pnpm.io/blob/v7/versioned_docs_archived/version-4.x/npmrc.md 注意: pnpm v7 文档 不全, 有些在 version-4.x 里

package.json 里设置 "packageManager": "[email protected]" 会使得 在当前目录运行 pnpm -v 始终是 7.33.7 而忽略系统安装的 不同 pnpm 版本. 原因是 https://github.com/nodejs/corepack

https://pnpm.io/symlinked-node-modules-structure 分析 /node_modules/.modules.yaml 文件 pnpm(v7+) 的 Isolated 即通过 node-linker=hoisted 设置 每个子包的 node_modules 只存自己依赖的软链接 没有 hoist 到顶层

场景: 当同一个包 [email protected] "分别"发到不同的 registry a/b/c 时, 会生成不同的 integrity a/b/c.

  • 先在 registry a 下, 进行 pnpm install 会缓存 [email protected] 在 pnpm store path 目录下, 并生成 pnpm-lock.yaml 文件.
  • 再拷贝此 lock 文件到 registry b 下. lock 文件中 [email protected] 仍是 integrity-a (实际应该修改为 integrity-b ). 但 pnpm install 仍能成功, 为什么? 因为 直接读了 pnpm store path 目录下的 pkga 的缓存. 注意: 但在 服务器上, a/b 属于不同容器, b 读不了 a 的缓存, b 在安装时候 就会报错. 在 registry b 里 运行 rm -rf "$(pnpm store path)" && pnpm install --frozen-lockfile 即可复现错误.

https://pnpm.io/workspaces monorepo 场景: 比如 package.json 文件的 "dependencies": { "demo0": "npm:demo1@^2.0.1", "demo": "workspace:demo2@*" } 这类 npm alias 依赖. 内部存在 demo2 这个包, 但 pnpm ls demo2 无结果, 而 pnpm ls demo 有结果.

https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-module-type-aliases/package.json https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-types/package.json 注意如上 @docusaurus/module-type-aliases 和 @docusaurus/types 里 package.json 的 "@types/react": "*" 这种 * 的写法, 会依赖 monorepo 根目录的 @types/react 版本. 场景: 在 pnpm 下, 因为 不同子包 依赖的 @types/react 大版本不一致, 不能在 根目录下 设置统一的 @types/react 版本. 子包 a/b/c 依赖了 @types/react@16^ 子包 d/e/f 及其下层依赖 因为声明了 @types/react: * 就也实际使用了 @types/react@16^ 版本, 但他们实际需要的是 @types/react@18^ 版本, 这样导致错误. 通过 pnpm why -r @types/react 查看实际使用版本.

https://www.npmjs.com/package/@types/react-dom/v/18.3.1?activeTab=code 比如 @types/react-dom 18 的 "dependencies": { "@types/react": "*" } 版本号是 * 在 monorepo 中 存在 @types/react 16 17 18 多个版本, pnpm 使用 最低版本 16. 而除了 "古老" 的包外 其他包实际需要的是 @types/react 18 版本, 使用 pnpm overrides 功能统一覆盖解决.

phantom dependencies 项目里存在 幽灵依赖 时 pnpm 会自动抛错. monorepo 子包存在幽灵依赖 但安装没报错. pnpm dlx depcheck Missing dependencies 即为幽灵依赖

pnpm 的设计哲学不鼓励“幽灵依赖”(phantom dependencies)。即使你在根目录安装了 @types/react,如果某个子包的代码里 import 了 React,最佳实践依然是在该子包的 package.json 中也声明 devDependencies。版本号可以宽松一些(例如 * 或 workspace:*),pnpm 会自动解析到根目录安装的那个唯一版本。 pnpm 会将所有 workspace 包的公共依赖提升(hoist) 到根目录的 node_modules 中。 依赖隔离:每个包的 node_modules 目录只包含其直接依赖。间接依赖通过符号链接从全局存储或依赖的 node_modules 中获取。关键点是:一个包无法访问其兄弟依赖或祖父依赖,除非它们被明确声明为直接依赖或通过依赖链传递。

命令 p/npm git lerna

rm -rf node_modules **/node_modules

ls -l $(which npm)
npm whoami
npm profile get
npm access list packages --registry https://registry.npmjs.org

# node env 优先级: 命令行 env > `/project/.npmrc` > `~/.npmrc` > `/etc/npmrc`
npm config list -l  # 按 env 优先级显示 所有值
npm config list --json  # 只显示 最终实际生效 的值
npm config get registry  # 获取 最终实际生效 的某个值
npm config set -g registry https://registry.npmmirror.com
npm config get cache  # 一般为 ~/.npm 查看 _npx 目录
npm cache clean --force

# install 时除了 可选依赖 (optionalDependencies) 其他遇到 404 会报错退出.
npm install --verbose > install.log
# 安装 npm alias 别名依赖
npm install --registry=https://registry.npmmirror.com axios4@npm:[email protected] axios5@npm:[email protected]
npm install --prefix ./dir
npm run build --prefix ./dir

# 从 git 安装, 验证 ssh -T [email protected]   ssh -v [email protected]
npm install git+ssh://[email protected]:warmhug/demo.git#develop
npm install git+https://github.com/warmhug/demo.git
npm install https://warmhug:[email protected]/warmhug/my-private-lib.git  # Personal Access Token
# 默认情况下, /usr/local 目录属于 root,普通用户没有权限修改
# 修改 /usr/local/lib/node_modules 的权限(不推荐) 推荐使用 nvm
sudo chown -R $(whoami) /usr/local/lib/node_modules
sudo chown -R $(whoami) /usr/local/bin

# 设置 dist-tag
npm dist-tag add @huajs/demo latest
npm root -g
npm ls -g node-sass
npm ls --long node-sass
npm ls --all --json --loglevel silent

npm view [email protected] engines  # 查看 npm 兼容的 node 版本范围
npm view [email protected] main
npm view [email protected] exports --json
node -p process.env
node -e "console.log(module.paths)"

# link
npm link  # cd my-lib , 会创建 globally-installed my-lib
npm link my-lib  # cd my-app
# 使用 file: 协议替代 link , 不会创建 globally-installed my-lib
npm install ../path/to/my-lib
ln -s /abs/path/to/my-cli ./node_modules/my-cli  # 手动软链接 node_modules

# npm monorepo 在根目录运行 npm v7(2020-10发布) 支持 Workspaces
npm version 0.1.5 --workspaces --no-git-tag-version --allow-same-version=true
npm version patch --workspace=packages/button --workspace=packages/card --no-git-tag-version --allow-same-version=true -f
# 如果只改某个子包版本号,进入到子包 设置 --workspaces=false
npm version patch --workspaces=false --no-git-tag-version
npm version prerelease --preid rc --no-git-tag-version

npm pack --dry-run --json

# 发包 登录账号
# npm publish 时使用的 registry 与 npmrc 里的 registry 和 @scope/registry 哪个起作用?
# 命令行 --registry > @scope:registry > 全局/项目级 registry > npm 官方 registry
npm publish
npm publish ./dir/subdir  # 必须是相对路径
npm publish --dry-run
npm publish --no-git-checks --tag beta

# corepack (Node.js >=16.9 自带)
corepack -h  # -v
# 安装并启用指定版本  会把 全局默认 npm 版本 切换到 9.6.7
corepack prepare [email protected] --activate

# https://docs.npmjs.com/cli/v10/commands/npx
npx mocha --version  # 在项目的 node_modules/.bin 目录中查找可执行文件
npx http-server --ignore-existing # 忽略本地的同名模块
# -p 会临时安装包到 缓存目录 ~/.npm/_npx 使用 npm config get cache 查看.
npx -p typescript tsc --version
npx --verbose -p typescript tsc --version
npx -p [email protected] npm publish --dry-run
# https://code.visualstudio.com/api/get-started/your-first-extension
npx --package yo --package generator-code -- yo code
npm_config_registry=https://registry.npmmirror.com/ npx

npm search @ant-design --searchlimit=100 --json  # 搜索组织下的包


# === pnpm

ls -la node_modules/react  # node_modules/react -> ../../.pnpm/[email protected]/node_modules/react

pnpm install --dir ./dir  # 自动进去指定目录安装. 同 npm install --prefix ./dir
pnpm install --frozen-lockfile  # 流水线里安装
# 只安装某个子包的依赖. 不推荐 cd 进入子目录安装 无法链接内部依赖, 破坏单一锁文件, 依赖版本冲突
pnpm install --filter <package_name>
pnpm --filter "@huajs/demo..." build
pnpm --filter "@xx/quick-*..." build  # 运行 筛选出的包 scripts 里比如 test build 等

# monorepo 依赖关系
pnpx nx graph
pnpm ls -r
pnpm ls -r demo1
pnpm ls -r --only-projects --parseable --filter "@xx/yy"
pnpm ls  # 列出 package.json 中声明的直接依赖
pnpm ls react  # 只列出 react 依赖
pnpm ls --json --long
pnpm ls --depth 2 ts-jest
pnpm ls --depth Infinity fast-glob  # 等效于 pnpm why -r fast-glob

# pnpm add pkg 和 pnpm install pkg 的区别?
pnpm add express@2 react@">=0.1.0 <0.2.0"
pnpm add ./package.tar.gz
pnpm add ./some-directory  # same as running pnpm link

rm -rf "$(pnpm store path)"
pnpm store prune
pnpm import package‑lock.json  # 导入 npm lock 或 npm-shrinkwrap.json 文件
pnpx create-react-app@next ./my-app  # npm 的 npx 等效于 pnpm 的 pnpx = pnpm dlx

pnpm outdated -r # 只检测 lock文件(不是package.json) 里的依赖版本号 是否过时
pnpm outdated "@ant-design/pro-*"
# 升级到 npm latest 指定的版本 如果 workspace 内部包 版本号大于npm最新版 则使用内部包版本号
pnpm up "@ant-design/pro-*" -r --latest
pnpm up "@ant-design/pro-*" -r  # 加 --workspace 作用一样

.npmrc 文件

ignore-scripts=true
legacy-peer-deps=true
omit-lockfile-registry-resolved=true  # npm 特有
#
# configs for npm/pnpm/yarn
#
# node-options=--max_old_space_size=8192
; loglevel=verbose
package-lock=false
update-notifier=false
engine-strict=true  # 对 package.json 里的 "engines": { "node": ">=18" } 起作用

registry=https://registry.npmmirror.com
#
# pnpm 特有配置
#
verify-store-integrity=false  # 7.7.0 开始默认 false. npm 没有相匹配的配置
verify-deps-before-run=install
link-workspace-packages=deep
workspace-concurrency=1  # default: Infinity

# pnpm@7 public-hoist-pattern 默认是 ['*types*', '*eslint*', '@prettier/plugin-*', '*prettier-plugin-*']
public-hoist-pattern[]  # 设置为空 覆盖默认值, 任何包 都不能被提升到根 node_modules
# 向 默认值 追加新值
# public-hoist-pattern[]=@types*  # 所有子包 types 当能统一版本时, 提升依赖
# public-hoist-pattern[]=!@types*  # 所有子包 types 禁止 提升依赖
# public-hoist-pattern[]=!@types/react
# hoist-pattern[]=!@types/react
# hoist-pattern[]=!@types/react-dom

auto-install-peers=false
strict-peer-dependencies=false  # pnpm@7 默认是 true

# enable-pre-post-scripts=true
# package-manager-strict=true  # since v9 默认 true , v10 packageManagerStrict
# resolution-mode=lowest-direct
lockfile=false
# lockfile-include-tarball-url=false  # 实际不起作用
recursive-install=false
reporter=append-only
pnpmfile=node_modules/.pnpm-config/@pnpm/types-fixer/pnpmfile.cjs

------ git

# -f 强制运行  -d 同时考虑子目录  -x 清理忽略文件  -n 模拟删除操作.
git clean -fdxn  # git 删除 Untracked files

git ls-files -m  # 列出所有已跟踪且内容已修改的文件
git ls-files -o --exclude-standard  # 列出所有未跟踪且不在 .gitignore 中的文件
git ls-files -m -o --exclude-standard -z  # 一起列出来
git ls-files -m -o --exclude-standard | tr '\n' ' '  # 替换换行为空格
# 修改 git status --porcelain 的输出内容
git status --porcelain | awk '$1 == "M" || $1 == "??" {print $2}' | tr '\n' ' '
# 不检测更新
git update-index --skip-worktree -- .npmrc  # 比 assume-unchanged 更好
git update-index --no-skip-worktree -- .npmrc
git update-index --assume-unchanged file1 file2
git update-index --no-assume-unchanged file1 file2  # 恢复检测
# https://stackoverflow.com/questions/12288212/git-update-index-assume-unchanged-on-directory
# 对于 untracked files 不支持使用 assume-unchanged 先加入到 .git/info/exclude 排除
git ls-files -o --exclude-standard >> .git/info/exclude
git update-index --assume-unchanged $(git ls-files -m | tr '\n' ' ')
git ls-files -v | grep '^[a-z]'  # 获取已经被 assume-unchanged 的文件

git remote [-v add | set-url] origin [email protected]
git ls-remote --heads origin
git ls-remote --tags  # 查看远程仓库所有 tags
git config -l  # --list

git commit --amend  # 修改提交信息
git commit --no-edit  # 使用上一次的提交信息进行提交 (未进行过提交会失败)
# 压缩 commit 保留压缩前的所有commit信息 其中的 hash 修改记录 也会被保留
git merge --squash feature-branch
git add . && git commit --no-verify

git pull --rebase
git pull   # 仅拉取与当前分支相关的标签 只有当标签指向的提交是由于拉取特定分支而下载到本地时,这些标签才会被自动下载。
git pull --prune	# 更新所有远程分支引用,并删除本地已失效的远程分支引用
git fetch   # 获取 当前origin的远程 所有分支 信息
git fetch --all  # 获取 当前origin和设置的其他origin的 所有分支 信息
git fetch origin master
git branch -m newBranchName  # 重命名分支
git checkout HEAD~1 -- file1 dir1
git reset HEAD~1 file1 dir1

git log master..feat-xx --oneline
git log -n 10
git log origin/master -- .npmrc package.json
git log --name-status # 显示文件增删状态
git log --graph
git log --oneline --decorate
git log --oneline --first-parent --reverse | tail -1
git log --graph --pretty="%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset" --all
git log --graph --pretty="%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset"

# HEAD = HEAD~0 = HEAD^0 当前提交
# HEAD~1 = HEAD^ 主线的上一次提交  HEAD~3 = HEAD^^^ 主线的上三次提交
# HEAD^1 主线提交(第一个父提交) HEAD^2 第2个并入的分支的最近一次的提交
# HEAD^2~3 第2个并入的分支 的最近第 4 次的提交
git diff HEAD^  # 比较 最新提交 和 其父提交 的差异
git diff master..feat-xx
git diff origin/master..origin/master -- .npmrc
git diff --name-only version1/branch1 version2/branch2
# 比较当前分支和 master 分支的实际不同的内容
git diff --name-only master..HEAD
git diff master..HEAD -b -w --ignore-blank-lines --ignore-space-change --ignore-all-space -p --stat [file/dir]
git diff master..HEAD -b -w --ignore-blank-lines --ignore-space-change --ignore-all-space --name-only
git diff @{upstream}
# 创建和 apply 补丁
# 当前为 branch-a 分支,想应用 branch-b 相对于 branch-a 的更改
git diff branch-a..branch-b > changes.patch
git diff branch-a..branch-b -- path/to/file > changes.patch
git apply changes.patch

git merge -X ours master  # 在 feature 分支执行
git checkout --ours .  # 恢复被 master 分支删除的文件
# 此时 -X ours 含义:
# 当某个文件 被双方同时修改 时,以当前分支(feature)的版本为准.
# 如果 master 删除了文件,而 feature 没有修改这个文件,那 Git 会直接认为:
# master 删除生效(文件被删) 因为 feature 没有冲突性修改  文件就显示成 deleted: xx/yy/file

git merge feature  # git merge 默认行为是“如果可能就快进,否则就三方合并”。 不能快进 则会产生 Merge pull request pull_id from xx_branch 或者 Merge branch “branch_name” 信息
git merge --no-ff  # 强制进行三方合并,即使可以进行快进合并
git merge --ff-only  # 只允许进行快进合并。如果不能快进合并,它会中止合并操作并报错

# git rebase 需要经常 reapply 其他提交的改动,commit 的时间顺序也会乱掉。只对自己的分支 commit 做 rebase,公共的分支不要 rebase. 其后续的 commit hash 将全部改变
git rebase -i [commit_id] # hash 换成 master
git rebase -i --root # 删除第一个提交
git rebase origin/master
git push --force-with-lease  # 强制提交 比 -f 安全

# cherry-pick 和 rebase 最终都会在操作完之后、修改同样提交的 commit hash 值
# 场景: 比如要 pick 的 来源分支的 commit 只是 HADE~1, 但 来源分支的 HEAD~5 和 目标分支的 HEAD~1 有相同的 commit_hash (即来源分支同步了最新的 master commit 但目标分支没有同步), 此时来源分支的 HADE~1到4 (而不是预期的只是HADE~1) 的 commit 都会 apply 到 目标分支, 并且在目标分支 同步过来的 HADE~1到4 的 commit hash 都会被重新修改。
git cherry-pick src_branch_commit_hash  # 切换到 目标分支
# 从另一个仓库的分支 pick 先 git fetch <other-repo-url> <other-branch>
git cherry-pick commit_hash # commit_hash 可以是其他仓库的hash

# --soft 不修改本地文件 --hard 本地的文件修改都被丢弃
git reset --[soft | hard] [origin/master | file | 057d]
git reset --hard && git clean --force -dfx # pristine
git reset --hard && git clean --force -df # wipe
git revert commit_id # 回滚代码 不抹掉 提交记录 产生新纪录
# git reflog 的记录只会保存在本地,不会推送到远程仓库。
git reflog  # 撤销 reset 时 找到撤销前的 commit_id 再 git reset 即可


# Git 标签是与特定的提交关联的,而不是直接与分支关联 。
# 标签是提交的别名,只要标签存在,它所指向的提交(以及该提交的历史)就会被保留 。 删除标签只会移除这个标签的“标签”本身,而不会影响代码或提交 。同样地,删除分支也不会删除其指向的提交 。
# tag 只附在一个 commit 上、如果这个 commit 被 squash,但 tag 仍然存在。
# https://stackoverflow.com/questions/54281360/what-happens-to-tags-of-squashed-commits
# 在 git rebase 之后,标签可能会指向新的历史中任何分支都无法访问的提交。在 rebase 后的历史中,这些标签有时被称为“悬空的”或“孤立的”。然而,标签本身仍然存在于仓库中。
git tag v1.0  # 给当前分支最新 commit 打 tag
git tag v1.0 commit_id  # 给当前分支 某个 commit_id 打 tag
# 打 annotated tags  使用 git show tag_name 会看到包含 tagger 标记
git tag -a 0.0.1 -m 'Release version 0.0.1'
git tag -a -m '@pkg/[email protected]' @pkg/[email protected]
git tag -a @pkg/[email protected] -m '@pkg/[email protected]' 4da6c3d4 -f
# 获取 tags
git pull --tags   # 拉取所有分支的更新 + 所有 tags .  注意: 远程仓库可能包含大量历史 tags(如版本发布标签),全量拉取会占用额外存储和网络资源.
git fetch --prune-tags --prune -f # 删除本地已被远程删除的标签 Git 2.20 及以上版本
git fetch --tags -f  # 强制覆盖本地 tags
git fetch --tags --all  # 额外获取所有 tags 信息
# 推送 tags
git push [origin] --tags    # 推送所有标签到服务器
git push --follow-tags --no-verify origin f-i18n-xx
git push origin tag_name
git push origin --delete tag_name
git push origin :refs/tags/tag_name
# 删除 tags
git tag -d tag_name
git tag -d $(git tag -l)  # 删除 本地所有 tags
# 搜索本地的某个 tag_name
git tag -l '*tag_name*'
git tag | grep tag_name
# 按时间排序的最近 5 个 tag (再转为 json 数组)
git tag --sort=-creatordate | head -n 5
git tag --sort=-creatordate | head -n 5 | awk 'BEGIN{printf "["} {printf "%s\"%s\"", sep, $0; sep=", "} END{print "]"}'
git for-each-ref --sort=-creatordate --count=5 --format='%(refname:short) %(objectname)' refs/tags
git for-each-ref refs/tags/ --format='%(refname:short) %(objectname)'
# 查看 tag 信息
git describe --first-parent
git describe --all  # 查找所有分支上的标签
git describe --tags
git describe --tags HEAD
git describe --tags --match "xx"  # 仅匹配名称包含 "xx" 的标签
git show-ref --tags
git tag -v [email protected]  # 非 annotated tags 会报错 error: cannot verify a non-tag object

# 查看当前分支上有哪些 tags
git tag --merged HEAD / feat1 # 所有直接打在该分支的 commit 上的 tag (无论新旧)
git tag --no-contains master  # 获取那些不包含在 master 中的标签
git tag --contains HEAD  # 查看直接指向当前分支 最新 commit 的 tag
git tag --points-at HEAD  # 查看直接指向当前分支 最新 commit 的 tag
git tag --points-at 6627f6  # 查看直接指向 某个 commit_id 的 tag

# 遍历所有本地的 tag,检查每个 tag 指向的提交是否是当前分支(HEAD)的祖先, 即在当前分支的历史中。
for tag in $(git tag); do if git merge-base --is-ancestor "$tag" HEAD; then echo "$tag"; fi; done

# 操作 https://stackoverflow.com/a/930495/2190503
# 在 .gitattributes 文件里配置 当 pnpm-lock.yaml 出现冲突时,将以当前分支为准
pnpm-lock.yaml merge=ours

# dangling object
git fsck --full --no-reflog | grep "dangling commit"
# dangling commit abc12345 本地没了, 远程存在. 怎么把 远程的加载到本地?
# https://chatgpt.com/c/68a5daa6-ff5c-8328-818c-fd3d7f1cabeb
git fetch origin abc12345
git checkout -b recovered-branch abc12345

# 其他
git rev-list --left-right --count origin/branch1..branch1
git reflog show branch1 -n5 | grep 'rebase'

# 每个 commit 都包含两个时间戳 作者时间(AuthorDate) 提交时间(CommitterDate)
# Git rebase、amend、cherry-pick 等操作会保留旧的 AuthorDate,但会更新 CommitDate
git show --no-patch --pretty=fuller commit_id

git lfs pull  # 拉取大文件
git lfs ls-files  # 检查文件完整性

# --show-toplevel | --short
git rev-parse --symbolic-full-name --abbrev-ref HEAD
git symbolic-ref --quiet HEAD

# GitHub stars topics/javascript
# https://www.star-history.com/#google-gemini/gemini-cli
# https://github.com/search?q=stars:%3E1&s=stars&type=Repositories
# https://github.com/topics/javascript

# 搜索 issues
# https://help.github.com/articles/searching-issues/
# https://github.com/search?type=Issues&q=xx+in:body+author:warmhug
# https://github.com/search?type=Issues&q=xx+commenter:warmhug+user:ant-design
# https://github.com/search?type=Issues&q=xx+commenter:warmhug+repo:ant-design/ant-design-mobile

# GitHub commit 或合并 MR 时,可以自动修改 issue 状态、关闭关联的 issue。
# 业内成熟的 GIT 分支模型 https://cloud.githubusercontent.com/assets/36899/7315642/015f534c-eaa2-11e4-9882-b7cc7535fb72.png
# GitHub Issues blog https://gitblog.io/

------ lerna

# https://lerna.js.org/docs/api-reference/commands

# --loglevel silly --yes --no-commit-hooks
# --include-merged-tags --no-push --no-git-tag-version
lerna ls --graph # 等效 pnpm ls -r --json
lerna ls --long # 等效 pnpm ls -r --depth -1 --json 换成 npm 不行
lerna ls --since master
lerna ls --since="master" --loglevel=verbose
lerna ls --since --include-merged-tags
lerna list --scope=my --include-dependencies --ndjson
lerna list --since=origin/master -include-dependents --loglevel=verbose
lerna list --scope=package-A --include-dependencies --since=main

# changed 比较当前工作树与最近的标签之间的差异 不支持 since scope 参数
lerna changed
lerna changed --include-merged-tags
lerna changed --include-merged-tags --loglevel debug

# 比较自上次发布以来的所有包或单个包的差异。依赖 Git 标签来确定上次发布的版本。
lerna diff
lerna diff package-name

# lerna version / publish 不支持 --scope 参数
lerna version patch --exact
lerna version patch --include-merged-tags --no-push --no-git-tag-version --no-commit-hooks --exact
lerna version patch --exact --message '🎨 chore(release): Publish' --conventional-commits
lerna version prerelease --preid beta
lerna publish prerelease --preid rc --dist-tag rc
lerna publish from-git --preid rc --dist-tag rc
lerna publish from-package

# 构建时需包含依赖  使用 concurrency 不要使用 parallel 参数
lerna run build --include-dependencies --concurrency 4

lerna watch -- echo \$LERNA_PACKAGE_NAME \$LERNA_FILE_CHANGES
lerna watch -- lerna run build --scope=\$LERNA_PACKAGE_NAME

lerna exec --since --include-merged-tags -- ls -la
lerna exec --include-merged-tags --concurrency 1 -- "pwd && ls -la"
lerna exec --scope @ant-design/pro-form -- pnpm version 0.1.5-alpha.0 --no-git-tag-version
# 可以使用 pnpm up 命令,但升级后的 包的版本号为类似这样 "xxx": "workspace:0.1.3" 需要 lerna/npm publish 命令再次处理.
lernaCli, 'exec', '--scope', name, '--', `pnpm version ${newVersion}` --workspaces=false --no-git-tag-version --allow-same-version=true`

--- jq

npm view [email protected] --json  | jq '{(.name): .["dist-tags"].latest}'
echo '[{ "name": 1 }]' | jq -r '.[].name'
echo '{message:"aa", content: "www.cont"}' | yq '.message'

# 使用 yq 操作 yaml
clash_file="./configs/clash.yaml"
new_str="DOMAIN-SUFFIX,xx.com,DIRECT"
echo $(yq '.rules' $clash_file)
yq e '.rules |= [ "'"$new_str"'" ] +.' $clash_file -i

.

软件

markdown 文本变成了一行, 有 \n 等字符, 推荐一些在线工具美化或格式化 2025-09-26

https://frame.work/ro/en/laptop16?tab=whats-new 2025-09 组装电脑

macOS 系统的 storage 里 System Data 占用了 60G 多, 这个很不正常, 怎么处理? 2025-08-10

网页版微信 https://wx.qq.com/ 能收到的表情包拖到电脑桌面保存. 2025-05

需求是想在 mac 电脑上 同时连接不同的 WiFi , 解决 公司网络 阻止访问某些网站的问题. 有哪些解决办法? 比如 macos 能做双系统吗? 或者 macbook pro 使用自己网络, 搭配自己的 mac mini 使用公司网络, 但需要 macbook 能方便的控制 mac mini, 这样可行吗? 希望在mac上使用两个网络, 不同app 链接不同的网络. 还有什么办法吗? 2025-05-12

我这个 macrodroid 设置有什么问题,应该怎么修改? gpt最好,dp疑似抄gpt,豆包一般,百度用dp,通义宕机 2025-04-11

vscode 有个内置插件, 能检测 typescript 的语法, 不小心关掉了怎么重开? 2025-04-07

crontab 脚本里能使用 环境变量 吗, 怎么使用? 在 .gitconfig 里能使用环境变量吗? 在 .gitconfig 里 怎么写注释? 在 .zshrc 里 的变量 需要 export 导出吗? 把 环境变量 设置在 .zshrc 里, 怎么根据目录自动使用 git 账号? 在 ~/.zshrc 里 export 了 git_user 但在 .gitconfig 里 使用不了, 怎么了? 2025-03-31

macOS 使用 快捷指令 制作一个功能, 能触发 ctrl+. 快捷键. 2024-12

在 macOS 系统上、使用 bash 写一个函数,自动地每天上午 11点50分 拷贝文件 a.md 的内容到一个新文件 _backup/datetime_a.md 中,每隔三天的 上午11点49分、清空 b.log 和 c.log 文件的内容。运行前后需要发出通知。 把 备份的文件, 只保留 5 个最新的, 其余旧的删除. https://chatgpt.com/share/674539a5-4d50-8008-9cce-a950f4a2354b 2024-11

在macOS用户目录下的 .zshrc 里写一个函数,判断是否已运行命令 ttyd -W -a zsh >> "$z_log" 2>&1 & 如果未运行过、则运行一次,如果已运行、则进一步判断:如果调用者是 ttyd 、则根据 http://localhost:7681/?arg=/Users/hua/.zshrc&arg='echo "aa"' 这个 URL 运行 arg 参数里的 echo 等任意自定义命令。 https://chatgpt.com/share/6742e267-f3a0-8008-bda3-6b1b6bbce601 2024-11

谷歌账号在注册的时候就确定了关联的国家与地区,属于哪个国家地区和当时注册ip手机环境有关系。以下是查看当前 Google 账号的归属地方法:登录 Google 账号,打开 Google 搜索首页 点击 首页右下角 条款 在新页面显示出 国家/地区版本:香港 2024-11-14

clash 配置指定域名用指定 dns 解析 https://chatgpt.com/share/671762b0-e55c-8008-bf27-b762cf930059 2024-08

2023-11 尝试 百度/腾讯/中国移动 网盘,广告多 文件格式支持少,最终使用 微软云盘。

2022-05 惠普z27k显示器 typec 100w 输出功率 能给电脑充电

macOS

https://github.com/PasteBar/PasteBarApp https://github.com/hkdobrev/cleanmac

------ 设置

  • 点击和手势: 触控板。1 勾选 “轻点来点按” 2 启用词典:查询与数据检测器 - 选择三指轻点 3 更多手势 - 应用Expose。
  • 三指拖移窗口: 辅助功能 -> 鼠标与触控板 -> 触控板选项 -> 启用拖移 -> 三指拖移。
  • 触发角: 调度中心 -> 触发角 (左上角:启动台, 左下角:显示器睡眠, 右上角:调度中心, 右下角:桌面)。
  • 键盘 -> 键盘快捷键:
    • 输入法(input source) 选择 cmd + 空格,在 “服务” 里勾选或不选。
    • 打开文件夹下的 terminal: 选择 服务(Services), 展开 "文件和文件夹", 勾选 "新建位于文件夹位置的终端窗口", 选择一个文件夹 "右键" 即可看到.
    • 添加快捷键
  • launchpad 里的图标 不能一次性拖动 多个 进行移动. (macOS 15.3)
  • dock: 程序坞 -> 不勾选 “在程序坞中显示最近使用的应用程序”(最后一项) 显示隐藏 cmd + alt + d
  • 通知: 通知中心 -> 勾选 “当显示器进入睡眠状态时/当屏幕锁定时”
  • 文本替换: 键盘 -> 文本,「command + A」全选、拖拽到 Finder 会生成 “用户词典.plist” 的文件。
  • 系统顶部菜单栏: 按住 Command 再拖动图标,改变右边图标顺序。
  • Finder 设置
    • 列表视图 cmd + 2 展开所有子文件夹 alt + 左边箭头
    • cmd + alt,拖动 app 到工具栏。
  • QuickLook: 搜索下载 QLMarkdown / QLStephen / QuickLookJSON 并放到 ~/Library/QuickLook/Library/QuickLook 目录。如果不生效、killall Finder 重启 Finder。
  • 查看ip地址: 设置 - wifi - 详细信息。
  • m1 外接显示器分辨率低: 显示器 -> 按住 Option 键的同时点击“缩放”。
  • 关闭 sip 关机、按住电源键(非m1按下Cmd R) 选择实用工具->终端 csrutil disable 查看状态 csrutil status
# 查看计算机名称: 设置 - General - About - name
# 查看本地主机名: 设置 - General - Sharing - Local hostname
scutil --get ComputerName  # 电脑名修改后, Local hostname 也会跟随自动修改
scutil --get LocalHostName # 用于本地网络上的服务发现 http://hostname.local:7890

uname -a  # 查看处理器架构

# System Settings – Privacy & Security 系统设置 – 隐私和安全性
# 允许安装”任何来源“的软件,解决 xx.app已损坏
sudo spctl --master-disable

xcode-select --install  # 安装 git gcc
pmset noidle # 阻止电脑睡眠 同时按住 shift、control、电源键,关闭显示器
# defaults read 查看系统设置
defaults write com.apple.screencapture type jpg
defaults write com.apple.screencapture location ~/Downloads/
defaults write com.apple.Music autoPlay -bool false
# Enable tap-to-click for the trackpad and show the correct state in System Preferences
defaults write com.apple.AppleMultitouchTrackpad Clicking -bool true
defaults -currentHost write -g com.apple.mouse.tapBehavior -int 1
# Show the path bar in the Finder
defaults write com.apple.finder "ShowPathbar" -bool "true" && killall Finder
# Disable the .DS file creation
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
# Apply the settings
/System/Library/PrivateFrameworks/SystemAdministration.framework/Resources/activateSettings -u

--- cron 定时任务

系统任务在 /etc/crontab/etc/cron.d/ 目录,需要管理员权限. crontab 文件一般位于 /var/at/tabs/<username>/var/cron/tabs/<username> 不建议直接改.

# 通过 vi 编辑器修改, 使用 :wq 保存.
# 注意: crontab 里的默认 env 为 SHELL=/bin/sh 等.
crontab -l  # 查看当前的 crontab 内容
crontab -e  # 编辑 cron 配置 保存后 cron 会自动加载和应用
sudo launchctl list | grep cron  # 检查 cron 服务是否正常运行
sudo launchctl load -w /System/Library/LaunchDaemons/com.vix.cron.plist # 如果未启动

crontab -e 脚本内容示例

# 接下来的 每1分钟 每2分钟 每10分钟 执行. 后面的四个 * 分别表示小时、日期、月份和星期几
* * * * * env > /tmp/cron_log
* * * * * zsh -ic 'echo "time: $(date)" >> /tmp/cron_log; env >> /tmp/cron_log'
*/2 * * * * env > /tmp/cron_log
*/10 * * * * env > /tmp/cron_log
# 每天 11:50 14:30 执行备份  /bin/bash -c 'source ~/.zshrc; fn_name fn_arg'
50 11 * * * zsh -ic 'scheduled_tasks backup >> "$hl_ext_log"' 2>&1
30 14 * * * zsh -ic 'scheduled_tasks backup >> "$hl_ext_log"' 2>&1
# 每隔三天 14:29 清空日志文件
29 14 */3 * * zsh -ic 'scheduled_tasks clear_logs >> "$hl_ext_log"' 2>&1

------ 软件

图像视频

  • 截图: command + shift + 4 (3全屏) 录屏: command + shift + 5
  • xnip snipaste lightshot (snip) / licecap (kap gifify) / UPDF(pdf编辑) / any-video-converter(online-audio-converter.com) / XnConvert(图像处理) / Movist (IINA) / ExifRenamer(重命名图片) / ExifTool exifr / HandBrake / MKVToolnix(mkv字幕抽取) / perian(QuickTime 插件) / aria2
  • 图片批量修改 宽或高 最大值 保持宽高比 sips -Z 1600 *.jpg 或指定宽高 sips -z height width [file]
brew install ffmpeg
ffmpeg -i input.mp4  # 查看分辨率 Stream #0:0: Video: h264 (High), **1920x1080**, ...
ffmpeg -i input.mp4 -filter:v "crop=宽度:高度:x偏移:y偏移" output.mp4  # 裁剪视频
ffplay input.mp4 -vf "crop=1280:720:320:180"  # 裁剪视频 预览
# 2x 倍速压缩, 没有音频
ffmpeg -i input.mov -filter:v "setpts=0.5*PTS" -crf 28 -preset fast 2x_compressed.mp4

文件传输 https://github.com/WCY-dt/EasyTransfer https://snapdrop.net/ (速度快 最方便, mac 上 edge 浏览器不可用、使用 chrome 浏览器) https://easychuan.cn/ https://www.wenshushu.cn/ https://github.com/schollz/croc Mac smb 文件共享(速度约1M/s较慢): 在需要共享文件的 Mac 上打开「系统偏好设置-共享-文件共享」会显示类似 smb://192.168.1.9 的共享地址。在另一台 Mac 上打开访达,在菜单栏选择「前往-连接服务器」。在 iPhone 或 iPad 打开「文件」App,点击右上角选项图标,选择「连接服务器」。

拼字幕 https://quotemaker.cc/zh/ 视频字幕类型有三种:内嵌字幕、外挂字幕、封装软字幕。可以视频转为音频、再提取字幕。

欧路词典: 修改 ~/Library/Preferences/ com.eusoft.eudic.plist 修改 MAIN_TimesLeft:允许使用次数(任意改) 10000000 重启 (更新 notion、百度网盘下载 再升级)

git设置 全局默认设置 code ~/.gitconfig 内部 name email

[alias]
  st = status
  co = checkout
  ci = commit
  br = branch
  cp = cherry-pick
  r = rebase -i origin/main
  acp = !git add -A && git commit -m \"auto commit\" && git push
[push]
  autoSetupRemote = true
[user]
  name = 然则
  email = [email protected]
[includeIf "gitdir:~/inner/-/"]
    path = .gitconfig-github

code ~/.gitconfig-github 文件 给特定目录 设置个人 name email

[user]
  name = warmhug
  email = [email protected]

web shell ttyd 基于 xtermjs

brew install ttyd
ttyd vim/login/bash/zsh
ttyd -W top  # 自动运行 top 命令、 加 --once 网页关闭时 命令也自动停止运行
ttyd -W -t fontSize=20 zsh  # http://localhost:7681
ttyd -W -a -t disableLeaveAlert=true zsh # http://localhost:7681/?&arg=aa&arg=bb
ttyd -p 9999 -W -a ./test.sh  # http://localhost:9999/?arg=./test.sh&arg=aa
# 命令不能被 ttyd 直接运行 https://github.com/tsl0922/ttyd/issues/1031

LaunchAgents

launchctl load/unload ~/Library/LaunchAgents/com.hua.autorun.plist  # 加载卸载 plist 文件
launchctl list | grep com.hua.autorun  # 验证是否运行

进程守护工具 supervisor

测网速 https://fast.com vpn检测 https://proxy.incolumitas.com/proxy_detect.html 查看本机公网 ip: http://cip.cc https://ipinfo.io/json https://ifconfig.me

curl cip.cc
traceroute baidu.com  # 查看域名路由 或 `ping baidu.com`
ifconfig | grep inet
#
# 2025-08 在 macOS 上 `ifconfig` 结果解释 https://www.tongyi.com/?sessionId=77c9f2e4fb574fd49f1de408bd118c63
#
# 127.x.x.x 都是本地回环范围
inet 127.0.0.1 netmask 0xff000000
# 当前连接网络的实际 IPv4 地址(比如公司或家庭网络) 连接路由器/Wi-Fi 后获得的局域网地址
en0: ...
    inet 10.140.30.244 netmask 0xfffffc00 broadcast 10.140.31.255
# 虚拟化技术(如 Docker Desktop、虚拟机)创建的虚拟网络网关
# js 的 WebRTC 的 ICE 候选地址中,真实 IP(如 10.140.30.244)被替换为 .local 域名. WebRTC 在 chrome extension 里 也只能看到 192.168.64.1 这个地址. 在 ChromeOS 设备 使用 chrome.networking.config API 才能获取到 真实 IP 地址.
bridge100: ...
    inet 192.168.64.1 netmask 0xffffff00 broadcast 192.168.64.255
# 其他状态为 inactive,说明未激活或未连接

chrome vscode zsh

vscode 查看 pnpm node_modules 里的 符号链接 等内容 很不方便, 对其背后的实际文件 有什么定位和搜索的好办法吗? https://chatgpt.com/c/68af0425-82dc-8327-b2df-11c547f14b7a 2025-08-27

有什么 vscode 内置的 api 能临时禁用启用所有插件? workbench.extensions.action.disableAllInstalledExtensions workbench.extensions.action.enableAllInstalledExtensions 2025-05

有办法绕过 chrome extension manifest v3 禁止内联 script 的限制吗? https://chat.deepseek.com/a/chat/s/edb9092f-5c97-461c-a2e9-0d362a2c3180 2025-04-01

------ chrome

Bookmarklet

  • https://make-bookmarklets.com/
  • 需要保存为书签 javascript:(function(){var baseUrl="https://web.archive.org/web/*/",urlmod=document.URL;window.location.href=baseUrl+urlmod;}());

--- chrome extensions

https://peekfoc.us/ Mobile simulator - responsive testing tool Interactive Git Log uicloner

ChatGPT 历史会话搜索 chrome 插件: 1Proompt / ChatGPT Conversation History Search / Superpower ChatGPT / Echoes / Searchable ChatGPT / GPT Search

Tab Position Options / 一键切换(Jomic) 搜索拐杖 下一页(空格键自动翻到下一页) ModHeader XSwitch Tamper Tampermonkey / Disable Content-Security-Policy / Talend API Tester / Web Developer / Neat URL / Copy Tab Info / Open Multiple URLs / 沙拉查词 / User JavaScript and CSS / Wayback Machine / Memex / 一叶 / grammarly.com / gitpod npmhub / screenity / Language Reactor / Side Browser / Sidebar Tab / Porter Plug / Video Speed Controller

------ vscode

工作空间 /Users/hua/Downloads /Users/hua/.aaid /Users/hua/.nvm/versions/node /tmp /Users/var/folders/xk/tpmztqjx0gldhvryd_mh60_80000gn/T

--- 扩展

推荐:

  • plantuml(设置指定server) / Auto Hide / Live Preview / Markdown All in One / markdown-pdf / marp / GitLens(simple logs) / pangu / Hungry Delete / Template String Converter
  • Code Runner / Terminal Keeper / Commands(usernamehw) / Todo Tree / Excalidraw / npm-dependency-links / Bookmarks / Diff Folders / Editor Group Minimizer Plus / favorites 端口 转发 实现 内网穿透,目前已被 国内禁用

https://github.com/jackiotyu/git-worktree-manager https://github.com/jianbingfang/vscode-dup-checker

--- 设置

// 快捷键
[
  { "key": "cmd+d", "command": "editor.action.copyLinesDownAction" },
  { "key": "alt+`", "command": "terminal.open" }
]
// markdown-pdf 扩展
{
  "markdown-pdf.displayHeaderFooter": false,
  "markdown-pdf.margin.top": "0.01cm", // bottom
  "markdown-pdf.margin.left": "0.5cm", // right
}
// xxProj/.vscode/settings.json
{
  "editor.tabSize": 2,
  "prettier.singleQuote": true,
  "typescript.tsdk": "node_modules/typescript/lib",
  "search.exclude": {
    "**/dist": true,
  }
}

tasks xxProj/.vscode/tasks.json 代码片段 xxProj/.vscode/my.code-snippets

------ zsh(rc)

Zsh 和 Bash 的不同

https://github.com/MichaelAquilina/zsh-you-should-use

生成 ssh key 推拉代码

ssh-keygen -t ed25519 -C [email protected]
ssh-add ~/.ssh/id_ed25519
# 再把 ~/.ssh/id_ed25519.pub 文件内容添加到 gitlab
# 配置 ssh 走 clash 代理, code ~/.ssh/config
Host github.com
  ProxyCommand nc -X connect -x 127.0.0.1:7890 %h %p

code ~/.zshrc

#export PS1="\u \w$"
ZSH_DISABLE_COMPFIX="true"
export ZSH=$HOME/.oh-my-zsh
ZSH_THEME="ys"  # Look ~/.oh-my-zsh/themes/
# plugins=(git)  # Look ~/.oh-my-zsh/plugins/*
source $ZSH/oh-my-zsh.sh

export EDITOR='vim'
# export EDITOR=nano
# export EDITOR='code'  # 修改为 vscode 编辑器有问题

# 使用 brew install.sh 安装脚本时, git 设置为 git config --global http.version HTTP/1.1
# brew 国内源 https://www.jianshu.com/p/bea984d27cd2
# cd "$(brew --repo)" && git remote -v
# cd "$(brew --repo homebrew/core)" && git remote -v
# cd "$(brew --repo homebrew/cask)" && git remote -v
# 恢复官方源
# git -C "$(brew --repo)" remote set-url origin https://github.com/Homebrew/brew.git
# git -C "$(brew --repo homebrew/core)" remote set-url origin https://github.com/Homebrew/homebrew-core.git
# git -C "$(brew --repo homebrew/cask)" remote set-url origin https://github.com/Homebrew/homebrew-cask.git
# 更换 home-bottles
# export HOMEBREW_BOTTLE_DOMAIN=http://mirrors.aliyun.com/homebrew/homebrew-bottles
# export HOMEBREW_BOTTLE_DOMAIN=http://7xkcej.dl1.z0.glb.clouddn.com
# env | grep HOMEBREW
# brew config
# brew ls

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

# 不建议用 source https://github.com/ohmyzsh/ohmyzsh/wiki/FAQ
# alias sz='source ~/.zshrc'
alias sz='exec zsh'
alias cz='code ~/.zshrc'

clash Charles Apache

------ clash

2015 ~ 2025

https://clash-meta.gitbook.io/clash.meta-wiki-older https://github.com/MetaCubeX/ClashX.Meta 支持 tun 模式, 能让“所有程序”都能通过 Clash 代理, 通过虚拟网卡 修改系统路由表, 作用在 网络层, 几乎等同 VPN 效果. 不开启 tun 是作用在 应用层.

验证 终端代理 是否成功: curl -v x.com

  • 不能用 ping, ping 使用的是ICMP协议,ICMP处于网络层(第三层),而SOCKS5是传输层代理协议(第四层),HTTP和HTTPS是应用层协议(第五层或者第七层),协议层不同是无法代理的。
  • 可选: 终端代理 brew install proxychains-ng 修改 /usr/local/etc/proxychains.conf 配置文件“末尾”部分内容 #socks4 127.0.0.1 9050 改为 socks5 127.0.0.1 1080。 使用 proxychains4 -q curl https://www.google.com 看是否成功,不成功则需要关闭 sip

多设备共享vpn网络:

获取 DNS服务器 设置:

scutil --dns
cat /etc/resolv.conf
networksetup -getdnsservers Wi-Fi
networksetup -getdnsservers Ethernet

clash文档

远程控制:菜单 -> 控制台 -> 右键 -> 检查元素 -> 查看网络 -> 端口和秘钥 (或者 设置 -> Api端口/秘钥) 在浏览器打开 http://127.0.0.1:58147/ui/#/proxies

绕过微信客户端网络限制/相关域名ip走proxy:

  • 先设为“全局模式”,点击Clash“控制台”,查看“日志”。
  • 在微信客户端里 发送文字和图片,查看抓包的相关域名和ip,用 https://db-ip.com 验证微信ip网段
    • 登录和收发文字: qq.com / wechat.com / tenpay.com
    • 收发图片: 43.153.165.235:80 / 43.175.127.21:443
    • 搜索"xx.0到xx.255怎么配置IP-CIDR",或者ip网段计算器
    • 最终规则类似 SRC-IP-CIDR,43.175.127.0/24,Proxy
  • 在Clash配置文件"rules"添加规则。

code ~/.config/clash/config.yaml 备份 configs/clash.yaml

mac 自动设置全局代理 https://gist.github.com/rmcdongit/f66ff91e0dad78d4d6346a75ded4b751 https://gist.github.com/dvessel/2b6ad97b2da16d445671b39618221aab https://community.jamf.com/t5/jamf-pro/scripting-quot-exclude-simple-hostnames-quot/m-p/64445

open /System/Library/PreferencePanes/Network.prefPane  # 打开网络偏好设置面板
open "x-apple.systempreferences:com.apple.Network-Settings.extension?Proxies"
networksetup
# 打开 WiFi 里 自动发现代理 开关
networksetup -setproxyautodiscovery Wi-Fi on
# 获取 WiFi 或 以太网 代理配置
networksetup -getsecurewebproxy Wi-Fi/Ethernet
networksetup -getproxybypassdomains Wi-Fi
networksetup -listallnetworkservices

# 设置别名
# alias pset='networksetup -setwebproxy Wi-Fi 127.0.0.1 7890 && networksetup -setsecurewebproxy Wi-Fi 127.0.0.1 7890 && networksetup -setsocksfirewallproxy Wi-Fi 127.0.0.1 7890 && networksetup -setproxybypassdomains Wi-Fi 192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,127.0.0.1,localhost,*.local,timestamp.apple.com,sequoia.apple.com,seed-sequoia.siri.apple.com'
# alias psystem='networksetup -setwebproxystate Wi-Fi on && networksetup -setsecurewebproxystate Wi-Fi on && networksetup -setsocksfirewallproxystate Wi-Fi on'
# alias upsystem='networksetup -setwebproxystate Wi-Fi off && networksetup -setsecurewebproxystate Wi-Fi off && networksetup -setsocksfirewallproxystate Wi-Fi off'

------ Charles whistle

2019 2024

whistle 规则配置:

https://aa.bb.xx 127.0.0.1:28064 excludeFilter://^/service
https://aa.bb.xx/govern 127.0.0.1:3025
https://local.tedev.ltt:27187  127.0.0.1:27187

Charles

  • 注意
    • 公司里默认安装的vpn软件、公司wifi的代理选项默认会打开“自动发现代理”的配置,需要关闭后、才能使用Charles代理。
    • 使用没有 被设置代理的 浏览器(比如 Chrome 翻墙代理需要关掉
  • HTTPs 支持:
    • Help -> SSL Proxying -> Install Charles Root Certificate (挨着的 模拟器 / **手机 **证书都装)
      • 注意:手机上安装的 证书 和 连接的 mac 电脑要匹配。使用新电脑需要重新给手机安装证书。
    • 在 macOS 钥匙串访问 里信任证书,iOS 设置里信任证书。
    • 菜单 Proxy -> Proxy Setting -> Port: 8888 /
    • 菜单 Proxy -> SSL Proxying Settings -> SSL Proxying -> add -> Host: * Port: 443
    • 在 iOS (不用连数据线) WiFi 设置 HTTP 代理,服务器输入 电脑 ip、端口 8888
  • 其他:
    • 关闭 mac 端包的抓取:菜单 Proxy 将 maxOS Proxy 取消选中 (这样 iOS 模拟器里也抓不了)
    • 抓取支付宝 RPC 请求:支付宝 可切换环境包 设置关闭 mmtp 开关
    • 映射本地 js 文件、调试代码:菜单 Tools -> Map Remote / Map Local…
    • 拦截请求:菜单 Tools -> Rewrite -> 勾选 Enable Rewrite -> Add -> Add -> Rewrite Rule -> Type 选 URL, Where 勾选 Request, Match Value 填 http(s?):\/\/aa.bb.xx\/(?!(service)\/)勾选Regex , Replace value 填 https://127.0.0.1:28064/ 勾选 Replace all
    • (点击配置框的问号、发现是使用的 Perl-style regular expressions)

------ Apache

出现 403 You dont have permission to access 错误, 修改 路径下 各级目录 权限 everyone 为 “只读”,再重启。 默认设置,不能浏览目录、只能访问目录下的文件,比较安全。 如果目录中存在 .htaccess 文件,检查其中是否有配置禁止访问。比如有 Deny from all

# 2024-08 mac系统的 Apache 怎么配置 localhost 同时支持 https http https://chatgpt.com/share/674ab45e-27a8-8008-b1bb-04c8bf5e444e
# 生成自签名证书
sudo mkdir /etc/apache2/ssl
cd /etc/apache2/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt

httpd -v # 查看版本号
sudo apachectl restart / start / stop   # 开关重启
code /etc/apache2/httpd.conf  # 编辑 Apche 的配置文件
# http://localhost  https://localhost

httpd.conf 文件配置

# Apache 通过 <Directory> 指令控制特定目录的访问权限。
# 在 index template 里插入自定义 meta. http://httpd.apache.org/docs/2.4/mod/mod_autoindex.html
IndexHeadInsert "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
DocumentRoot "/Users/hua/inner"
<Directory "/Users/hua/inner">
    Options Indexes FollowSymLinks MultiViews
    MultiviewsMatch Any
    AllowOverride None
    Require all granted
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
    Header set Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"
    Header set Access-Control-Allow-Credentials: true
</Directory>
<VirtualHost *:80>
  <FilesMatch "\.(md|cpp|php)$">
    AddDefaultCharset utf-8
    Header always set Content-Type "text/plain; charset: utf-8"
  </FilesMatch>
</VirtualHost>

# 打开 https://localhost 支持
# 取消注释 LoadModule ssl_module libexec/apache2/mod_ssl.so
Listen 443
<VirtualHost *:443>
    ServerName localhost
    DocumentRoot "/Users/hua/inner"
    SSLEngine on
    SSLCertificateFile "/etc/apache2/ssl/localhost.crt"
    SSLCertificateKeyFile "/etc/apache2/ssl/localhost.key"
    ErrorLog "/private/var/log/apache2/error_log"
    CustomLog "/private/var/log/apache2/access_log" common
</VirtualHost>

Listen 9999
<VirtualHost *:9999>
  ServerName me.com
  DocumentRoot "/Users/hua/Downloads"
  <Directory "/Users/hua/Downloads">
      Options Indexes FollowSymLinks MultiViews
      MultiviewsMatch Any
      AllowOverride None
      Require all granted
  </Directory>
</VirtualHost>

Ubuntu / UTM

Red Hat / QEMU 和 Ubuntu 是什么关系? QEMU 开源虚拟化引擎. Ubuntu 系统默认安装并支持 KVM/QEMU 虚拟化。 Ubuntu 是 QEMU 的“下游使用者”,它利用 QEMU 的能力为用户提供虚拟化功能。 2025-09-05

mac 上的虚拟机 UTM / VMware Fusion Player / Parallels Desktop 哪个比较好? 需要免费使用. https://chat.deepseek.com/a/chat/s/68b857de-7b1c-41a6-8013-490dbf25f899 2025-08-09


cat /etc/os-release  # 查看发行版
lscpu | grep -i avx2
free -h

# 通过 apt 或 dpkg 列出所有软件包
dpkg --get-selections | grep -v deinstall
dpkg -l | grep 软件包名称
apt list --installed

# 安装 Python
sudo apt install python3  # sudo apt install python3.11
sudo apt install python3-pip
pip3 --version
# 可选
sudo apt install python3-venv  # 安装 venv(用于创建虚拟环境)
sudo apt install python3-dev  # 安装开发工具包
  • Unix 遵循的原则是 KISS (Keep it simple, stupid) do one thing and do it well。
  • Linux 严格区分大小写。所有内容以文件形式保存,包括硬件。如:键盘 /dev/stdin 显示器 /dev/stdout
  • Linux 不靠扩展名区分文件类型,靠权限区分。( .gz .tgz .sh 等文件扩展名只是为了方便管理员查看 )
    • bash 文件 想在 mac 上双击可执行(调用系统terminal),需要去掉文件后缀名。
  • shell 是一个命令行解释器。shell 是壳,kernel 是内核。shell 把用户敲进去的命令、翻译为 linux 内核能识别的语言。
    • sh: Bourne Shell 的缩写,可以说是目前所有 Shell 的祖先。 bash : Bourne Again Shell 的缩写,是 sh 的一个进阶版本。
  • vi编辑器使用 color-scheme :colo desert 或者 配置 ~/.vimrccolo desert + syntax on
  • 在 Windows 上 哪些流行的 terminal 能和 macOS Linux 的 terminal 兼容?
    • Windows Terminal / WSL(Windows Subsystem for Linux)/ Git Bash

------ UTM 虚拟机

2025-08

MacBook Pro 2018 (Intel + AMD GPU) x86_64

  1. UTM 安装 Linux 虚拟机

参考 https://www.tongyi.com/qianwen/?sessionId=e4e3643aac5f497096256d70a4432775 下载 https://www.releases.ubuntu.com/22.04/ ubuntu-22.04.5-live-server-amd64.iso . 使用 server 版本 没有图形界面 占资源少.

  • Create a New Virtual Machine -> Virtualize -> Linux -> 加载下载的 Ubuntu ISO 镜像
  • 分配: 内存 8G, 存储(Storage) 64G . 设置 Shared Directory, 取名 Ubuntu22 .
  • 点击 Play 图标, 运行 Ubuntu ISO 镜像. 选择 Try or Install Ubuntu Server .
  1. 安装 Ubuntu 操作系统

复选框 括号里的 x 表示选中, 使用 空格 来取消选中.

  • 如果你的网络可能不顺畅,选择 "Ubuntu Server (minimized)" 并且不勾选 "Search for third-party drivers" 选项.
  • 在 Proxy address 里留空.
  • 在 Storage configuration 步骤的 “Confirm destructive action” 提示框, 选择“Continue”.
  • 在 SSH configuration 里, 可以先不选 Install OpenSSH server .
  • 在 "Featured server snaps" 界面, 都不选择.
  • 在 “Installation complete!” 界面, 选择 [Reboot Now] 来重启计算机
  • 遇到 “Failed unmounting /cdrom” 错误, 进入 UTM - Ubuntu22 界面 末尾的 CD/DVD 取消选择 Ubuntu ISO 镜像. 确认安装介质已经移除后,按照屏幕上的提示按 Enter 键。系统会尝试再次卸载 /cdrom 并继续启动过程。
  • 到 Ubuntu 22.04.5 LTS hua tty1 界面, 表示安装完成, 主机名为 "hua".
  • 在 hua login: 提示符后 输入你的用户名. 如果创建了一个名为 "hua" 的用户,那么你应该输入 hua 以及后续的密码.

utm 虚拟机 设置了 shared directory , 怎么在 虚拟机 里实际访问这个目录的内容?

剪贴板共享, 这样设置 不可行: 关掉虚拟机 在 UTM 里 右键 → Sharing → 勾选 Enable Clipboard Sharing 或者 右键 → Edit → Display → Spice(qxl). 需要改用 SSH 连接.

操作虚拟机:

# 安装 ssh
sudo apt update
sudo apt install openssh-server
sudo systemctl enable ssh
sudo systemctl start ssh
# 在 mac 电脑终端里 登录 Ubuntu 虚拟机
# 通过 ip addr show 查看虚拟机的 IP 地址, 显示为 inet 192.168.64.3/24 metric...
ssh [email protected]
# 虚拟机里 翻墙:
# 在 clashx 里 copy shell command 获取的 export https_proxy=http://127.0.0.1...
# 使用 ifconfig 获取 ip 比如 192.168.64.1 替换 127.0.0.1 如下:
export https_proxy=http://192.168.64.1:7890 http_proxy=http://192.168.64.1:7890 all_proxy=socks5://192.168.64.1:7890

mobile / win

usb 充电线 输入为 5v1a 时, 末尾分叉为多个头 每个头的输出是多少? 2025-08-08

有两个表情图片 没有删除的地方, 但在 微信和 QQ 的表情选择里 都能看到. 是存放在哪里的? 怎么能删除掉? 2025-06-13

最新发布的 iPad OS 26 能用来写代码? 能安装 vscode terminal 等软件吗? 2025-06-11

2025-05-15 手机控制电脑ppt https://github.com/Rico00121/decktap

Win系统安装盘、系统下载地址,电脑开机(按F12)设置U盘优先启动。 2024-04

小米多看电纸书一代、安装app方法 iPhone 恢复出厂设置后,系统软件版本是 iOS 最新版 不是出厂时旧版本。 连接数据线恢复备份的文件后,各个第三方app仍然需要重新下载、如有卡死状态 用手机网络 先下载重要app 其他暂停. 2022-09

2019 支持 Mac + Win 读写的U盘格式: exFAT FAT32 NTFS(软件 ntfstool / ParagonNTFS )


Android 软件: MX播放器(VLC不能播放加密文件) AirDroid 微动手势(允许后台弹出界面和显示悬浮窗), automate,, kwgt, popup widget, macrodroid, tasker(收费), easytouch, anywhere . 反编译apk: apktool/dex2jar/jd-gui/javadecompilers

iOS 快捷指令

  • 同步: Apple ID -> iCloud -> 使用iCloud的APP -> 显示全部 找到 快捷指令 勾选同步。
  • 朗读的 声音大小和siri一样,不受设置里声音大小的控制,通过设置 Siri 的声音来控制。

自动化

2021 ~ 2025

https://github.com/modstart-lib/linkandroid

------ scrcpy adb

电脑控制手机 https://www.zhihu.com/question/46795475 、 anydesk 体验不错、但不能远程操作iPhone,国产抄袭版 todesk 会卡死,Wormhole虫洞 利用 iPhone 的辅助功能-触控 能被三方控制功能实现远程操作、但体验很差。

# scrcpy --tcpip  # 插入usb线时、先设置无线连接,之后不用插入usb线、通过具体ip地址链接。
# scrcpy --tcpip=10.94.62.181  # 如果ip正确但也连不上 删掉ip 插上线。
scrcpy --shortcut-mod=lctrl --stay-awake --turn-screen-off -m1024 -b2M --tcpip=10.94.62.181

adb 自动化: https://blog.ferstar.org/post/use-tasker-do-some-funny-things/

adb -s emulator-5554 shell input text 'my%stext'
# 如果有空格、特殊字符等, 会报错: Error: Invalid arguments for command: text usage: input ...
# 对这些字符 ( ) < > | ; & * \ ~ " ' 加上反斜杠 \ 转义, 空格用 %s 转义

# adb 解锁 android 手机
# https://stackoverflow.com/questions/30402582/how-to-verify-android-device-screen-on-or-off-using-adb-shell-command

screenState=$(adb shell dumpsys nfc | grep -e 'mScreenState=' -e 'Screen State:' | tr : = | cut -d '=' -f2)
if [ "$screenState" == "OFF_LOCKED" ] ; then
  echo "Screen is off. Turning on."
  adb shell input keyevent 26 # wakeup
  sleep 0.8
  adb shell input touchscreen swipe 540 1000 540 500 # unlock bottom->top
  sleep 0.8
  adb shell input text 0000 # pin
  echo "OK, should be on now."
else
  echo "Screen is already on. Locking."
  adb shell input keyevent 26
fi

------ AppleScript

2024

在 bash 文件里调用 osascript

#!/bin/bash

# 显示系统通知
osascript -e 'display notification "Test message" with title "Test Notification"'

osascript -e 'tell application "Safari" to activate'
osascript -e 'activate app "Safari"'
osascript -e 'quit app "Safari"'

osascript -e 'tell application "System Events" to tell process "ClashX"
  tell menu bar item 1 of menu bar 2
    click
    key code 15 using command down
  end tell
end tell
'

# https://apple.stackexchange.com/questions/103621/run-applescript-from-bash-script
osascript <<EOD
  tell application "Google Chrome"
    activate
  end tell
EOD

------ Android kwgt

2025

$df(h:mma:ss)$ ( good $if(df(H)&gt;=0&amp;df(H)&lt;=11, "morning", df(H)&gt;=12&amp;df(H)&lt;=15, "afternoon", df(H)&gt;=16&amp;df(H)&lt;=20, "evening", "night")$ ) 2025-05 公式编辑器

KWGT 默认刷新间隔为每分钟一次,可在 全局设置 中,将 更新间隔 调整为 1秒, 但会导致 手机耗电 过度. 所以 小组件的 秒数 不能直接显示出来, 能怎么做? https://chat.deepseek.com/a/chat/s/fc16fdf3-c934-4446-9e30-91f821899648 https://www.douban.com/group/topic/243177384 2025-03

kwgt kustom 能用 JavaScript 编程的方式做小组件吗? 哪里有比较丰富的 widgets 市场或集合, 可以直接下载使用? 2025-03-04

kwgt 官网 reddit

------ Android automate

2023 2024

https://llamalab.com/automate/

权限设置:开启无障碍 允许后台弹出界面 显示悬浮窗 桌面快捷方式。 添加桌面图标:在flow beginning里 install home screen shortcut

语法: 拼接变量 "my string" ++ myVarmystring{myVar}。 正则表达式(java版本): matches(txt, "(?s)\\s*+(?:https?://)?+(?:www\\.)?+(?:m\\.)?+(.+?)/?+\\s*+")[1]。 函数: contains(txt, "https://") 等。 Content view 组件的 Content MIME type: video/mp4 等类型。 一些 APP 的 Package 和 Activity class: com.android.chrome / com.google.android.apps.chrome.Main

社区优秀应用:Search Engine 、 Tab Browser 、 Text to Speech 、Web dialogs (inspect layout, better support) 、 Microsoft Rewards Auto-Search

  • 直接打开 天猫精灵-我的设备 页面: 使用 App start 组件,package 选择 com.alibaba.ailabs.tg Activity class 选择 com.alibaba.ailabs.tg.home.MyIotHomeActivity
  • 亮度升高: set screen brightness 为 0.4,因为 小米改动了系统默认亮度、这里0.5是最亮的。
  • 复制日期时间: 设置变量 dt "{Now;dateFormat;yyyy-MM-dd_HH-mm}" 设置 clipboard 为 dt。

--- 通过分享使用 百度/Google 搜索:

情况分析:

  • 从普通软件分享的文字是 你好 这样的纯文本。
  • 从 edge 浏览器bing网站菜单栏的“分享按钮”直接点击分享的文字是 https://cn.bing.com/search?q=test&qs=HS 这种纯粹的url。
  • 从 edge 浏览器bing搜索结果网页内选中文字后、弹出的分享按钮点击是 "你好" https://cn.bing.com/search?q=test&qs=HS 这种 纯文本+URL,需要去掉其中的链接。

实现:

  1. 使用 Content shared 组件,设置 Content MIME type 为 Any / Text,Content text 为 txt。
  2. 上一步 txt 值可能是 纯文本、纯文本+URL、纯URL 三者中的某一种,使用 Expression true 组件来做 if 判断。
    1. 先判断是否为http开头的纯URL、if语句为 #txt < 4 ? 0 : slice(txt, 0, 4) = "http" 如果值为真、这时只是bing(或者你自己的默认)搜索引擎链接,用表达式 matches(txt, ".*([?&])q=(.*?)&.*")[1] 提取 url 后边的 q 参数值。
    2. 否则再判断是否是 纯文本+URL(注意文本和URL之间有换行符),设置中间变量 txt1 为 matches(txt, "\"(.*)\"([\\s\\S]*)http.*")[1] 这个正则能匹配换行符、并提取出了其中的纯文本文字。
    3. 再使用 Expression true 组件判断 txt1 != "" 值为真、则使用 Variable set 组件、设置 txt 为 txt1。不为真、则是 纯文本 的情况、直接返回 txt 即可。
  3. 最终打开的链接: "https://www.google.com/search?q=" ++ txt"https://www.baidu.com/s?wd=" ++ txt

--- 处理 onedriver 里 txt 文件:

使用 Dialog choice 组件,在 Choices 输入框输入

{
  "content://com.microsoft.skydrive.content.external/Drive/ID/1/Item/RID/4B2D0681F143BB23%216901/Stream/1/Property/_life.txt": "life",
  "content://com.microsoft.skydrive.content.external/Drive/ID/1/Item/RID/4B2D0681F143BB23%216902/Stream/1/Property/_misc.txt": "misc"
}

勾选 Show window 选项、才能弹出弹窗。

其中 json 里的 URL 来自 小米默认浏览器 打开 onedriver txt 文件时的路径,使用这个路径、也可以在 automate 这里打开。 再使用 App start 组件,package 选择 cn.wps.moffice_eng.xiaomi.lite Activity class 选择 cn.wps.moffice.plugin.app.entrance.WriterEntranceActivity

------ iOS Scriptable

2022 ~ 2023

mac scriptable scriptable docs reddit 社区 automators 社区 https://github.com/dersvenhesse/awesome-scriptable https://github.com/evilbutcher/Scriptables https://routinehub.co/

捷径汇总 https://ifttt.com/ 通过获取“智能开关、iOS提醒事项日历”等各类服务的API、再设置 if.then 逻辑、在手机上打开才能运行。注意:没有像“iOS快捷指令”app的系统权限、不能调用其他app。

iOS<=16 版本,小组件里列表内容 没有click等点击事件、只可以通过url打开Safari或其他app。

icon_themer & Fancy Icon Maker 新版 iOS 已失效。

iOS内容限制:转到“设置” > “屏幕时间” > “内容和隐私限制” > 选择“内容限制”-”网页内容“。

appintents

.

创作/素材

想要在 DevOps无限环 这个图的各个环节, 补充一些 公司内部对应的工具. 有什么可编辑的图片工具? 还能支持多次修改编辑. Figma / Canva / Excalidraw 2025-09-30


https://time.is https://datetime.app

like jq for markdown https://github.com/yshavit/mdq

文字图 https://emojis.click/zh https://asciiflow.com/ https://ascii-tree-generator.com/

markdown 表情 👍 😄 😃 😆

艺术字

占位图

pdf转markdown https://github.com/MarkPDFdown/markpdfdown pdf转word: 夸克浏览器-工具 / https://www.tongyi.com/discover/convert 语音转文字 https://www.zaixianai.cn/voiceToText 拼图 https://img.ops-coffee.com/ https://nextbconvert.com/en https://tinyurl.com/

https://path-motion.yysuni.com/canvas https://www.svgshow.cn/ https://github.com/liujuntao123/new-svg-viewer

https://clipso.agilestudio.cn/

独立开发者工具 https://github.com/yaolifeng0629/Awesome-independent-tools 新闻订阅 https://github.com/sansan0/TrendRadar https://github.com/glidea/zenfeed https://github.com/w4n9hu1/hot-hub-web 白噪音 https://soundbox.fun/

cdn

[![NPM version][npm-image]][npm-url]
[![Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]

[npm-url]: https://npmjs.org/package/@huajs/demo
[npm-image]: http://img.shields.io/npm/v/@huajs/demo.svg

[downloads-url]: https://npmjs.org/package/@huajs/demo
[downloads-image]: http://img.shields.io/npm/dm/@huajs/demo.svg?style=flat-square

[travis-url]: https://travis-ci.org/react-component/m-steps
[travis-image]: http://img.shields.io/travis/react-component/m-steps.svg

国外图片站点 https://www.pexels.com/zh-cn/ https://pixabay.com/

https://gw.alipayobjects.com/os/lib/react/16.13.0/umd/react.production.min.js https://gw.alipayobjects.com/os/lib/react-dom/16.13.0/umd/react-dom.production.min.js https://gw.alipayobjects.com/zos/rmsportal/gIYqpRZVWejUBzkRRZMl.png https://img.alicdn.com/bao/uploaded/i1/32785103/TB2UQQOsFXXXXaDXXXXXXXXXXXX_!!32785103.jpg_300x300q90.jpg https://gw.alipayobjects.com/zos/rmsportal/[email protected] https://gw.alipayobjects.com/zos/rmsportal/RxMbdtGwmMUIVsXRiLyJ.jpg https://os.alipayobjects.com/rmsportal/EylTaSCtqXQRiTK.jpg http://images.cnblogs.com/cnblogs_com/bluedream2009/201609/o_mm.jpg

国内有哪些靠谱的 Javascript 库 CDN可用 https://unpkg.com https://cdnjs.com https://jshub.com https://cdnjs.cloudflare.com https://www.bootcdn.cn https://www.staticfile.org https://upcdn.b0.upaiyun.com https://cdn.bytedance.com https://www.webcache.cn

http://cdn.staticfile.org/angular.js/1.2.16/angular.js http://cdn.bootcss.com/placeholder.js/3.1.0/placeholder.js https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.js https://code.jquery.com/ui/1.13.0/jquery-ui.js jQuery v1.12.4 https://gw.alipayobjects.com/os/rmsportal/YbGjMuYEbXdIGJRsqOSA.js https://a.alipayobjects.com/jquery/jquery/1.11.1/jquery-debug.js https://gw.alipayobjects.com/os/lib/jquery/3.6.0/dist/jquery.min.js qrcode.js https://gw.alipayobjects.com/os/rmsportal/lRHmUpUMSTHDNMnENjeD.js less.js https://gw.alipayobjects.com/os/rmsportal/OKOpSSqWebCoOQQXdLVG.js bootstrap.css v3.3.7 https://gw.alipayobjects.com/os/rmsportal/SaEqgaEyUazqSndgTxGj.css bootstrap.js v3.3.7 https://gw.alipayobjects.com/os/rmsportal/MoeUXzBfoEONHwCbBvXl.js

命名

devops 中 dev 环节英语应该叫什么 https://chatgpt.com/c/689082d1-4d54-8008-b28b-6668d4e733f6 2025-08-04

代码项目的目录命名 common 和 commons 哪个更好? https://gemini.google.com/app/fd0ec4b35523c91f https://chat.deepseek.com/a/chat/s/f32465b1-6753-4abf-be2b-1edb5ea56f26 https://chatgpt.com/share/67bdc47e-88b4-8008-9094-399b0a78b555 2025-02-25

http://json-schema.org/draft-07/schema 2025-04

2024-lerna |- packages/ │ |─ demo/ │ |─ demo1/ |- shared/ │ |─ utils.ts |- tests/ │ |─ setupTests.ts |- typings/ │ |─ css-modules.d.ts │ |─ scss.d.ts |- .gitignore |- .npmrc |- tsconfig.json |- typings.d.ts |- vitest.config.ts


bash 英语术语: Redirection Pipes

aids / facilities / Misc / Vendor / base / core data-commons / data-utils / http-utils / json-helper integration / integrate / legacy

lib - Library(库):通常包含一系列可重用的代码模块或函数集合。 common - Common(公共):存放项目中多个部分都会用到的通用函数或组件。 commons - 公共组件/方法:项目中多个部分都会用到的通用逻辑和功能。 aux 或 auxiliary - 辅助,与 helper 类似,指辅助性代码模块。 Assistants - 辅助类,帮助主程序执行操作。 helper - Helper(助手):这类文件或模块提供一些辅助性的功能函数。 Helpers - 帮助函数或模块,用于简化代码。 extensions / ext - 扩展方法:扩展已有对象或类型的额外功能函数。 tools - 工具集:各种杂项但实用的功能函数合集。 utility utilities (完整形式) - 同样指代工具函数,与 utils 含义一致 support - 支持模块:为其它主要模块提供支持性功能的代码块。 tasks / jobs - 任务/作业:用于定时任务或其他异步工作流程的模块。

logger / logging - 日志记录:用于处理日志生成和管理的模块。 core_utils - 核心工具:专用于项目核心模块的一组工具方法。 funcs / functions - 函数集:用来存储独立、非特定业务逻辑的函数。 Components - 组件类,用于构建更大的系统。 Modules - 模块类,包含一组相关的功能。 Libraries - 库,提供预定义的功能集合。 Frameworks - 框架,提供应用程序的基本结构。 Addons - 插件或附加组件,扩展主程序的功能。 Plugins - 插件,用于扩展软件的功能。 Scripts - 脚本,一系列自动化命令或程序。 Snippets - 代码片段,用于快速插入常用代码。 services - 服务层:在某些架构中,这一层封装了应用程序的核心业务逻辑和数据处理操作。 services_utils - 服务层工具:在服务层内部使用的通用功能模块。 models - 模型:在 MVC(Model-View-Controller)架构中,模型代表数据结构及相关的业务逻辑。 middlewares - 中间件:在像Express.js这样的Node框架中,中间件是指处理HTTP请求的函数序列。 io - Input/Output(输入/输出):与数据读取、写入等I/O操作相关的模块。 config - 配置:存放应用程序配置信息的模块或文件夹。 cache - 缓存:提供缓存功能,如数据缓存、HTTP请求缓存等的模块。 validators / validation - 校验器/验证:包含数据校验逻辑的模块。 exceptions - 异常处理:用来定义和处理自定义异常的模块。 consts / constants - 常量:存放程序中不会改变的值。 enums - 枚举:存储枚举类型的模块。 templates / views - 模板/视图:在Web开发中,存放HTML模板或其他类型视图文件的目录。 primitives - 基础工具:包含一些基础且常用的处理数据、字符串等的基础方法。

PRD 系分 2019-11

PRD有三种状态:Draft、 Review、Ready, 其中起草人为产品或研发团队,相关人 review 通过。

修订记录/更新日志 修改日期 修改版本 修改内容 备注

前后端测试负责人、工作量评估。

一、需求背景 1.1 需求来源 1.2 需求描述 概念对齐/名词定义/关键术语 目标对齐 竞品调研/同类产品调研 使用场景/主要用户/试点用户

二、需求目标 产品定位 产品目标 产品能力 业务问题(业务需求)现存问题 功能一览表格 业务流程

三、结构/流程图 3.1 功能结构图 3.2 需求流程图 业务流程 -> 任务流程 -> 页面流程 3.3 交互设计图

四、需求范围 模块 功能 优先级

五、功能性需求 详细需求 详细方案

六、非功能性需求 上线/灰度/回滚方案、兼容性、AB实验、高可用、性能、监控、权限、运维 等。

七、附录 数据分析报告、用户调研报告

------ 系分 模版

2019-11

系分(系统设计+业务分析)的本质其实就是将技术推演的过程前置,所带来的好处就是:问题可以在第一时间发现,第一时间解决,从而最大化的降低了需求变更、方案变更 所带来的沉没成本。

--- 修订历史

版本号 作者 内容提要 发布日期
V1.0 XX 初稿 2020-10-24

--- 需求背景 xxxx

--- 需求目标 xxxx

--- 相关资源

  • prd(@xx): XXX 交互稿(@xx): XXX 视觉稿(@xx): XXX
  • 后端系分: XXX、API 列表

--- 功能分析

1.模块交互截图 2.展示要素分析 3.时序图(包含系统交互、用户行为交互)

模块A xxxx 模块B xxxx

特殊模块分析(可选) 1.特殊功能描述 2.实现思路流程图?依赖的框架、类库? 3.性能表现,是否需要降级?降级的维度:钱包版本、系统版本、小程序版本? 4.兼容性,稳定性方案

--- 监控设计 核心业务数据监控。异常监控告警。

--- 灰度方案 服务端、客户端、配置项灰度方案。

--- 应急方案 写操作熔断方案、核心模块熔断、应急提示(小黄条)

--- 埋点方案 1.页面访问埋点 2.链路行动点曝光+点击 3.特殊业务埋点

--- 技术沉淀 1.沉淀一个组件? 2.沉淀一个模板? 3.沉淀一套解决方案?

--- 项目管理

工作量评估

功能点 工作量 需求优先级 责任人
模块A X天 P0 小马
模块B X天 P0 小马
模块C X天 P1 小马

项目风险点

项目详细计划表

发布checkList

plantuml

2022

@startuml
:sss;
split
   :A;
   kill
split again
   :B;
   detach
split again
   :C;
   kill
end split
@enduml
@startuml
title 无分支条件

[*] --> active
active -right-> inactive : disable
inactive -left-> active  : enable
inactive --> closed  : close
active --> closed  : close
closed --> [*]
@enduml
@startuml

left to right direction
'top to bottom direction

rectangle Arrows
rectangle C
rectangle D
rectangle E

Arrows --> C
Arrows --> D
Arrows --[hidden]> E

@enduml
@startuml
left to right direction
'top to bottom direction

rectangle Arrows
note top : aaa\nbbb
rectangle A
rectangle B
rectangle C
rectangle D
rectangle E

Arrows --> A
A --> B
A --> C
Arrows -u-> D
Arrows -u-> E
Arrows -u-> F

@enduml
@startuml
left to right direction

rectangle ima as "Issues Management" #lightgreen
rectangle qac as "Quick Access"
rectangle jse as "JS Overview \n [[https://baidu.com JS Error List]]"
rectangle req as "Request Overview \n [[https://baidu.com Error Request List]]"
rectangle res as "Resource Overview \n [[https://baidu.com Error Resource List]]"
rectangle per as "Performance Overview \n [[https://baidu.com Worst Performing Pages]]"

qac --> ima : direct link to
jse --> ima : manage issues
req --> ima : manage issues
res --> ima : manage issues
per --> ima : manage issues

@enduml
@startuml

!$rfcs = "进入 apm_web_rfcs 空间"
!$coll = "收集需求"
!$new  = "新建需求\n添加基本描述"
!$rc   = "选择 slard/apmplus 空间,同步创建新需求 或关联已有需求"
!$entr = "进入 slard/apmplus 空间"
!$main = '在 slard/apmplus 空间做需求管理 \n 会 <u>自动同步</u> 部分状态变更 到 rfcs 空间的相应需求'
!$fm   = "在 slard/apmplus 空间完成 线上验收"
!$fr   = "rfcs 空间相应需求 手动再确认"
!$stop = "终止"

rectangle $coll #A9DCDF
rectangle frr as "$fr" #lightgreen
rectangle $stop #ddd

:Actor: -u-> $coll : bp/oncall
$coll -r-> ($new) : $rfcs
($new) -r-> ($rc) : 转为正式需求
($new) -d-> ($stop) : 伪需求
($rc) -d-> ($main) : $entr
($main) -d-> frr : $fm

@enduml
' a 不能变成 :a:
a -> b
if "a" then
  -->[true] "Some Action"
else
  ->[false] "Something else"
endif
'甘特图

@startgantt
/'
单行注释、放在 单引号之间,多行注释前后加斜杠
[正式上线] lasts 1 day and starts at 2020/03/20
'/
'skinparam classFontSize 10'

scale 2
project starts the 2019/12/16
saturday are closed
sunday are closed
2020/01/01 is closed
2020/01/22 to 2020/02/02 is closed
2019/12/16 to 2019/12/30 are named [十二月]
2020/01/01 to 2020/01/31 are named [一月]
'2020/02/01 to 2020/02/30 are named [二月]'

-- 开发阶段(灰色背景是节假日、不计入总时间) --
[环境准备] as [hj] lasts 2 days and is colored in Lavender/LightBlue
then [首页 3d] lasts 3 days
[流程管理 4d] as [lc] lasts 4 days
[hj] -> [lc]

[<size:13><b>交付中心 <color:red>11d] as [jf] lasts 11 days
[jf] starts at [lc]'s end and is colored in Yellow/Green
[列表 3d] lasts 3 days and starts at [jf]'s start
[大图 3d] lasts 3 days and starts at [jf]'s start
[明细 3d] lasts 3 days and starts at [jf]'s start
[大图 3d] lasts 3 days and starts at [jf]'s start
[任务 3d] lasts 3 days and starts at [jf]'s start
[权限 5d] as [qx] lasts 5 days and starts at [jf]'s end

-- 测试阶段 --
[集成测试 5d] as [jc] lasts 5 days and is colored in Fuchsia/FireBrick
[qx] -> [jc]

@endgantt

About

Do something "deep, lasting, and meaningful". 做一些“深入、持久、有意义”的事情

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •