MoreRSS

site iconSunZhongWei | 孙仲维 修改

博客名「大象笔记」,全干程序员一名,曾在金山,DNSPod,腾讯云,常驻烟台。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

SunZhongWei | 孙仲维 的 RSS 预览

vscode copilot 国内满血复活 Claude 的配置方法

2025-10-17 20:52:28

大概是上个月,我发现国内已经不能在 vscode GitHub copilot 中使用 claude 相关的模型了。对我来说,不太影响日常的搬砖性的 crud 开发任务。但是今天,遇到了出设计稿的任务,想让 ai 出一版平板 app 的设计稿。之前用 claude 给出的效果非常赞。参考前文 Claude 3.7 生成 APP/网站 UI 设计稿的提示词。

没有 claude 的情况下,我用 gpt 5 codex 和 gemini 2.5 pro 分别除了一版设计稿,效果惨不忍睹。而且让 gemini 微调,也是一直嗯嗯嗯,就是不改。无法忍受🤣 不得不请回 claude了。

网上查了一下,方法很简单,只要不是国内的 ip 就能继续使用 claude。于是,我打开 vscode 的左下角设置,选择 settings

在搜索框里输入 proxy,找到 http proxy 配置项,输入自己的本地代理地址。例如,我的是 socks5。这样就搞定了

例如:

socks5://localhost:4455

再次打开 vscode,在聊天窗口,就能 claude 相关的模型了。

vscode copilot Claude

我用 claude 4.5 使用了跟 gpt codex 和 gemini 一样的提示词。还得是 claude,ui 效果非常赞,逻辑清晰,审美在线。唯一的缺点是,让她用中文输出界面,非得给我用英文,我有用 gpt 5 mini 修复了一轮才解决。再就是很容易出现返回超过长度限制的问题。但是这些都能接受,毕竟效果是真的好。

tailwindcss V4 警告处理, cdn.tailwindcss.com should not be used in production

2025-10-14 15:25:00

用 AI 生成的网页代码,如果使用了 tailwindcss V4 的 CDN 版本,会看到浏览器控制台报了一段警告信息:

cdn.tailwindcss.com should not be used in production. To use Tailwind CSS in production, install it as a PostCSS plugin or use the Tailwind CLI: https://tailwindcss.com/docs/installation

奈何 AI 用 tailwindcss 生成的页面就是比用 bootstrap 的好看,不得不解决一下。

为何生产环境不能使用 cdn.tailwindcss.com

参考 github 上的这个 issue:

https://github.com/tailwindlabs/tailwindcss/issues/18731

The warning is there on purpose. The v3 CDN build is not intended for production use. It's meant for prototyping during development.

Certain things like transitions may not function properly in cases where new, unseen classes are added to an element. DOM updates are batched in the browser meaning that we won't get notified until after the transition has "started" and as such its possible for a transition to not animate in the first time.

大致意思就是,CDN 版本在生产环境中可能会导致一些问题,例如元素上动态添加的类。

但是,我觉得主要原因是,CDN 版本会加载所有的样式,文件大,而项目实际使用的样式很少。所以需要使用 PostCSS 插件或者 Tailwind CLI 来生成按需加载的 CSS 文件。

使用 Tailwind CLI 还是 PostCSS 插件

简单看了一下 PostCSS 的介绍,感觉还是太复杂了(不想花时间在前端复杂度上),不如直接使用 Tailwind CLI 来生成 CSS 文件。

其实,我连 Tailwind CLI 都不想用,要不是感觉浏览器终端里有警告信息显得不专业,我都想继续用 CDN 版本。

Tailwind CLI 的工作原理

Tailwind CSS works by scanning all of your HTML files, JavaScript components, and any other templates for class names, generating the corresponding styles and then writing them to a static CSS file.

即,Tailwind CLI 会扫描你的 HTML 文件、JavaScript 组件和其他模板中的类名,生成相应的样式,然后将它们写入一个静态 CSS 文件。

安装 Tailwind CLI

npm install tailwindcss @tailwindcss/cli

也可以不使用 node,直接下载预编译的二进制文件。但是 tailwindcss-windows-x64.exe 文件大小 127M,感觉太大了,算了。

在哪里执行呢?我是在 golang gin 项目根目录执行的。执行完成后,会看到根目录下多了一个 node_modules 目录(需要添加到 .gitignore 中), 以及一个 package.json 文件,内容如下:

{
  "dependencies": {
    "@tailwindcss/cli": "^4.1.14"
  }
}

命令参数

> npx @tailwindcss/cli
≈ tailwindcss v4.1.14

Usage:
  tailwindcss [--input input.css] [--output output.css] [--watch] [options…]

Options:
  -i, --input ················· Input file
  -o, --output ················ Output file [default: `-`]
  -w, --watch[=always] ········ Watch for changes and rebuild as needed, and use `always` to keep watching when stdin is closed
  -m, --minify ················ Optimize and minify the output
      --optimize ·············· Optimize the output without minifying
      --cwd ··················· The current working directory [default: `.`]
      --map ··················· Generate a source map [default: `false`]
  -h, --help ·················· Display usage information

执行编译

npx @tailwindcss/cli -i public/css/style.css -o public/css/output.css --cwd=templates

输出提示:

≈ tailwindcss v4.1.14

Done in 136ms

需要注意 --cwd 参数,指定扫描的目录。因为我的 HTML 模板文件都在 templates 目录下。 而我的 public 目录也放到了 templates 目录下,所以 public/css/style.css 这个输入文件路径是相对于 templates 目录的。 这里比较特殊,跟正常的项目结构不太一样。没办法,我用 golang gin 感觉这样方便调试。

$ tree templates/
templates/
├── product.html
├── products.html
├── public
│   ├── css
│   │   ├── output.css
│   │   └── style.css
│   ├── images
│   │   ├── default_avatar.png
│   │   ├── image_404.jpg
│   └── js
│       └── main.js
└── thanks.html

编译后的 CSS 文件大小

不压缩的话,output.css 文件大小 33K. 如果加上 --minify 参数:

npx @tailwindcss/cli -i public/css/style.css -o public/css/output.min.css --cwd=templates --minify

减少为 25K。

好了,大功告成。下面是记录的一些报错信息,可以忽略。

后续

  • 将 tailwind 命令加入到项目 Makefile 中
  • 区分开发环境和生产环境的 CSS 文件。开发环境使用 style.css,生产环境使用 output.min.css

初始化 Tailwind CSS 配置文件

npx tailwindcss init

报错:

npm ERR! could not determine executable to run

网上说是因为 V4 版本会出现这个问题,降级到 V3 版本就可以了。但是,我想用 V4 版本啊。

V4 直接在命令参数里指定 cwd 参数就可以了。其实也用不上 init 命令。

ReferenceError: structuredClone is not defined

> node --version
v16.14.2

是 Node 的版本问题:structuredClone() was added in Node.js 17.0.0 (Sept 2021) 需要高版本的 Node.js 才支持 structuredClone()。

$ nvm install 17

$ node -v
v17.9.1

参考

  • https://v3.tailwindcss.com/docs/optimizing-for-production
  • https://blog.murtazau.xyz/templ-tailwind-htmx

golang gin 生成网站地图文件 sitemap.xml

2025-10-12 22:36:54

周末继续 Golang Gin 重构 PHP 的 Magento 电商网站。其中一个需要重构的功能是网站地图 sitemap.xml 文件的生成。 之前做的网站普遍简单,很少超过上万个产品或者文章。而电商类的服务,例如 magento 通常需要导入几十万甚至上百万的产品信息。那么就需要注意一下 sitemap.xml 的配置规范。

golang 三方库

https://github.com/sabloger/sitemap-generator

虽然 Star 数只有 40 个,但是看起来文档还挺详情,准备测试一下。

> go get github.com/sabloger/sitemap-generator/smg
go: downloading github.com/sabloger/sitemap-generator v1.3.0
go: added github.com/sabloger/sitemap-generator v1.3.0

存储目录

一个独立的 sitemap 目录,放到根目录下。也方便 Nginx 规则配置。同时在 golang gin 代码中做访问处理,方便本地调试。

sitemap.xml 的更新机制

  • 定时任务,每天凌晨 2 点更新一次
  • 手动触发更新
  • 批量导入操作完成后,触发更新。用 goroutine 异步处理会不会好一些?
  • 新增页面后,手动添加
  • 手动添加产品、文章等,触发更新

Priority 的值如何设置

sitemap 中每个条目的 Priority 的主要作用是“引导”爬虫,告诉它们你认为哪些页面最重要,应该优先抓取。 Priority 的值范围是 0.0 到 1.0,1.0 表示最高优先级。但是我不了解具体每个页面的值应该设置为多少。 于是问了一下 DeepSeek: "网站的 sitemap.xml 如果是外贸站的产品链接,Priority 设置成多少合适?":

  • 首页:1.0。网站的入口和核心,代表整个网站的最高优先级。
  • 核心产品分类/目录页:0.8 - 0.9。这些是产品页面的父级集合页,流量潜力大,重要性仅次于首页。
  • 具体产品页:0.8。产品页是转化的最终着陆页,是网站的价值所在,必须设置为高优先级。
  • 其他重要页面(关于我们、联系我们): 0.7。这些页面对于建立信任和促成询盘很重要,但不是直接的转化页。
  • 博客文章/新闻内容:0.6 - 0.7。用于内容营销和获取长尾流量,重要性低于核心业务页面。
  • 标签页、按条件筛选页:0.4 - 0.5。这些页面可能有重复内容问题,优先级应调低,避免爬虫浪费抓取预算。
  • 网站条款、隐私政策等:0.3。必要但完全不重要的页面,设置为最低优先级。

具体的设置需要灵活调整,不是所有产品页都必须一模一样。例如:

  • 将爆款产品、主打产品的优先级设置为 0.9。或者新发布的博客文章优先级设高。
  • 将常规产品的优先级设置为 0.8。
  • 将清仓、过季或低利润产品的优先级设置为 0.6。

感觉分析的非常合理。

简单的条目

<url>
	<loc>https://www.sunzhongwei.com/</loc>
	<changefreq>daily</changefreq>
	<priority>1.0</priority>
</url>

复杂的条目

可以同时设置产品图片相关信息。

<url>
	<loc>https://www.sunzhongwei.com/product-a.html</loc>
	<lastmod>2025-08-22T08:19:56+00:00</lastmod>
	<changefreq>daily</changefreq>
	<priority>1.0</priority>
	<image:image>
		<image:loc>https://www.sunzhongwei.com/product-a.jpg</image:loc>
		<image:title>Some App</image:title>
		<image:caption>Some App</image:caption>
	</image:image>
	<PageMap xmlns="http://www.google.com/schemas/sitemap-pagemap/1.0">
		<DataObject type="thumbnail">
			<Attribute name="name" value="Some App"/>
			<Attribute name="src" value="https://www.sunzhongwei.com/product-a.jpg"/>
		</DataObject>
	</PageMap>
</url>

单个文件的 URL 数量限制

  • 每个 sitemap 文件最多包含 50,000 个 URL 条目
  • 每个 sitemap 文件的大小不能超过 50MB(未压缩)

可以通过设置来限制单个文件的 URL 数量,例如设置为 10,000 条。

smProducts := smi.NewSitemap()
smProducts.SetName("product_sitemap")
smProducts.SetLastMod(&now)
sm.SetMaxURLsCount(10000) // Default maximum number of URLs in each file is 50,000 to break

例如,网站有 35,000 个产品页面,那么会生成 4 个 sitemap 文件:

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
	<sitemap>
		<loc>http://localhost:9053/sitemap/product_sitemap3.xml</loc>
	</sitemap>
	<sitemap>
		<loc>http://localhost:9053/sitemap/product_sitemap2.xml</loc>
	</sitemap>
	<sitemap>
		<loc>http://localhost:9053/sitemap/product_sitemap1.xml</loc>
	</sitemap>
	<sitemap>
		<loc>http://localhost:9053/sitemap/product_sitemap.xml</loc>
	</sitemap>
</sitemapindex>

其他

  • 生产环境部署时,sitemap.xml 使用 Nginx 处理访问

国庆假期处理的第二例网站服务器被刷流量,导致 Linode Server 宕机

2025-10-07 18:29:35

国庆第一天,刚处理了国内的阿里云个人博客服务器被刷爆带宽。 而国庆第五天,一大早就收到海外的一个网站服务器(Linode Server)的宕机通知邮件。

早上一起床就赶紧登上了服务器,发现是网站服务器被刷流量,直接导致服务器负载过高,网站无法访问。

攻击流量特征

几乎全部的垃圾流量都是在刷一个站的博客列表页面,路径如下:

/latest-blog?mdrv=<xxx.com>&start=<random_number>
/latest-blog?=1&pagespeed=%27%3Fpagespeed%3D%27&start=2750
  • 正常的 mdrv 参数应该是一个六位字母的随机字符串,类似 71hp3w,但是攻击流量中 mdrv 参数值不少是 xxx.com 结尾的域名。
  • 再就是莫名其妙的 pagespeed 参数
  • 同时 URL 参数结构混乱

请求大概一秒钟几十次,一直在持续,没有停下来的意思。 观察了两天,攻击流量在减少,但是还没有停止。至少服务器负载降下来了。

Nginx 屏蔽规则

让 DeepSeek 帮忙分析了一下,给出了两个屏蔽规则:

location / {
    # 匹配 /latest-blog 路径且 mdrv 参数值包含 .com
    if ($request_uri ~* "^/latest-blog\?.*mdrv=[^&]*\.com") {
            return 444;
    }

    # 新增规则2:屏蔽 /latest-blog 路径且包含 pagespeed 参数(不区分大小写)
    if ($request_uri ~* "^/latest-blog\?.*pagespeed") {
            return 444;
    }

    try_files $uri $uri/ /index.php?$args;
}

AI 非常适合写正则表达式,反正比我写的好。

整理这篇文章,主要是为了记录 Nginx 的配置。

PHP 建站系统的尴尬之处

这个网站是一个 PHP Joomla 搭建的内容站。(Joomla 类似 WordPress)

我的体会是,通用的 php 建站系统,类似 WordPress、joomla、magento 为了通用性,页面请求的处理逻辑包含了大量的数据库联表查询。

导致一个 4 核 8G 的服务器,连处理一秒钟 100 次的请求都吃力。 而且要去做定制化缓存,也非常麻烦。

这两天刚听了 Ruby on Rails 作者的一个播客,他承认 Ruby 哪里都好,就是服务器需要多一点的成本。 PHP 也是类似的道理。我还是更喜欢 Go 来开发网站,至少不用为了性能去折腾。也能扛住这种小规模的攻击。

自己开发,也可以在参数中增加校验,例如页面参数,再增加一个校验串,防止随机页码。

为什么没有使用 Cloudflare

这个网站比较特殊,主站使用了 Cloudflare,但是为了自动支持多语言,使用了三方的翻译服务。 相当于几十种翻译,每个语种对应一个新的二级域名,每个二级域名需要解析到三方的实时翻译服务上,三方翻译服务收到正常用户的请求后,拉取对应的源站内容,实时翻译为目标语言,再返回给浏览器用户。由于需要加三方翻译服务的 IP 白名单,导致 cloudflare 的拦截失效。

而 Cloudflare 是可以识别这类攻击,自动返回 robot challenge 页面,防止恶意流量的。

蓝易云也有海外 cdn 节点

前两天发的那篇国内服务器被刷流量的公众号文章,有个专业做 CDN 的大佬恰好刷到了,就加了我微信, 推荐了他们的 CDN 服务,蓝易云,官方地址:

https://www.tsycdn.com

处理机制也跟 cloudflare 类似,在识别出攻击流量特征后,触发强制人机验证。 而且他们也遇到了国内广东大量 PCDN 刷流量的问题,也做了相应的防护。跟这位大佬交流的过程中,感觉还是专业的 CDN 服务靠谱一些,我这种个人开发者,还是不要自己折腾了。 蓝易云也有海外的 CDN 节点,可以考虑使用。

感兴趣的兄弟可以加这位大佬的 V:lanyiyun6

随机生成家庭住址及工作单位,职务等个人资料的在线工具

2025-09-29 16:07:46

开发完了公司内网的人事管理系统,开始动手测试,发现里面的测试数据惨不忍睹,全是 111,222 这样的名字,员工资料里全是数字,显得系统异常粗糙😵‍💫。明天就要给人事部门演示了,这样可不行。于是我就用之前开发的 随机生成身份证号,手机号,邮箱地址的微信小程序 生成了一堆测试数据,界面里面看起来像个正式一点的人事系统了。但是,还有一部分数据没法自动生成,例如,家庭住址/户籍地址,工作单位,职务这些信息。

于是,我想干脆借此机会把这个工具再完善一下,就加上了更多的个人资料字段随机生成,效果如下:

随机生成家庭住址及工作单位

本来想加上一些工资卡开户银行的信息想想算了,怕引起敏感词问题。同时增加了网页版本,方便在不方便登录微信的办公机上使用🤣🤣🤣 网页版地址如下:

https://www.sunzhongwei.com/tools5/random-person-info

但是手动复制的效率还是低,要录入几十个员工的测试数据,还是一件异常繁琐的体力活。我要试试微软新开源的 playwright 自动化测试工具,通过调用我的这个网页接口来获取数据,然后填充到页面中。直接插入数据库不好吗?我感觉还是不如在界面中操作更容易发现问题。再就是不知道 playwright 如果接入 mcp 会不会更简单一些。

尝试了一下 gpt5 codex 的代码效果,还可以,就是有点发挥不稳定的感觉。有时候很聪明,有时候又智障的不行。但是实现这种简单的随机数据,还是很适合的👍

git blame 确认代码中的屎是不是自己拉的

2025-09-21 15:22:39

今天在排查一处程序 bug 时,发现一段代码写的逻辑实在乱,完全没有印象正确的逻辑应该是怎样的。 于是想查看这段代码是不是自己写的,什么时候写的,为什么这么写的。

直接在 VSCode 的 github copilot 的 Chat 窗口中问了一下:

如何通过 git 命令查看某段代码是那个提交修改的:例如:
line1
line2
line3

得到的回答是,可以试试 git blame 命令。试了一下,非常好用。

git blame 示例

例如, 我想查看 models/product.go 文件中第 10 到 13 行的修改记录,可以运行:

git blame -L 10,13 models/product.go

执行结果如下图:

git blame 执行结果

可以看到每一行代码前面都有一个 commit hash 和作者信息。通过这些 hash 可以进一步查看具体的提交内容。

git show <commit-hash>

VSCode 中查看 git blame 信息

网上搜索了一下,发现 VSCode 内置了 git blame 功能,可以直接在编辑器中查看每行代码的最后修改信息。

参考,VSCode 的官方文档:

https://code.visualstudio.com/docs/sourcecontrol/overview

git blame vscode 文档

可以看到,编辑区域的底部的 Status Bar 上会显示当前行的最后修改信息,点击可以查看更多详情。如下图所示:

git blame vscode

还是 VSCode 方便啊。