julia-evans

20 articles

← Back Live Monitor RSS Feed

远离 Tailwind,学习构建我的 CSS 结构

Translated AI Summary eng
[AI 摘要] The author describes migrating from Tailwind CSS to vanilla CSS, sharing lessons on structuring CSS code for better maintainability.
View content
<p>你好!八年前,我<a href="https://jvns.ca/blog/2018/11/01/tailwind--write-css-without-the-css/">兴奋地写了关于发现 Tailwind 的文章</a>。</p> <p>那时我真的不知道如何组织我的 CSS 代码,在一堆完全混乱的东西和 Tailwind 之间选择时,我非常高兴地选择了 Tailwind。它帮助我制作了许多小网站!</p> <p>过去一周左右,我一直在将一些网站从 Tailwind 迁移到更语义化的 HTML 和纯 CSS,这非常有趣且令人兴奋,所以我学到了一些东西!</p> <p>像往常一样,我不是全职前端开发者,所以我的 CSS 学习多年来都是断断续续发生的。</p> <h3 id="it-turns-out-tailwind-taught-me-a-lot">事实证明 Tailwind 教了我很多</h3> <p>当我开始思考如何组织 CSS 时,一开始我很害怕:我不太擅长组织我的 CSS!但接着我开始阅读关于如何组织 CSS 的博客文章(比如<a href="https://www.miriamsuzanne.com/2022/09/06/layers/">一整套层叠层</a>或<a href="https://jacobb.nyc/writing/how-i-write-css-in-2024">我在 2024 年如何写 CSS</a>),然后我意识到几件事:</p> <ol> <li>每个 CSS 代码库都有许多不同的事情在发生(布局!字体!颜色!通用组件!)</li> <li>为每种事情设置系统或指南非常有用,否则事情会变得混乱</li> <li>Tailwind 对其中一些事情有系统,而且我已经知道这些系统!也许我可以模仿我喜欢的系统!</li> </ol> <p>例如,Tailwind 有:</p> <ul> <li>一个重置样式表</li> <li>一个<a href="https://jvns.ca/blog/2026/05/04/css-colour-palettes/">调色板</a></li> <li>一个<a href="https://v2.tailwindcss.com/docs/font-size">字体比例</a></li> </ul…
Show original
<p>Hello! 8 years ago, I <a href="https://jvns.ca/blog/2018/11/01/tailwind--write-css-without-the-css/">wrote excitedly about discovering Tailwind</a>.</p> <p>At that time I really had no idea how to structure my CSS code and given the choice between a pile of complete chaos and Tailwind, I was really happy to choose Tailwind. It helped me make a lot of tiny sites!</p> <p>I spent the last week or so migrating a couple of sites away from Tailwind and towards more semantic HTML + vanilla CSS, and it was SO fun and SO interesting, so here are some things I learned!</p> <p>As usual I&rsquo;m not a full-time frontend developer and so all of my CSS learning has happened in fits and starts over many years.</p> <h3 id="it-turns-out-tailwind-taught-me-a-lot">it turns out Tailwind taught me a lot</h3> <p>When I started thinking about structuring CSS, I was intimidated at first: I&rsquo;m not very good at structuring my CSS! But then I started reading blog posts talking about how to structure CSS…
Read article Original

CSS 色板资源链接

Translated AI Summary eng
[AI 摘要] 该文分享了作者在告别 Tailwind 后收藏的一系列 CSS 调色板、生成器及颜色工具资源。
View content
<p>前阵子我决定新项目不再使用 Tailwind,转而编写原生 CSS。</p> <p>但我怀念 Tailwind 的一点是它的<a href="https://v2.tailwindcss.com/docs/customizing-colors#color-palette-reference">调色板</a>(<a href="https://gist.github.com/jvns/9e59b2cd1fe12601084ba78dded072fe">CSS 格式版本在此</a>)。如果我需要浅蓝色,直接使用 <code>blue-100</code> 即可;若不喜欢,可尝试 <code>blue-200</code> 或 <code>blue-50</code>。我对颜色不太在行,因此拥有一套由更擅长颜色的人精心设计的合理调色板,对我来说差别很大。</p> <p>但我对这些 Tailwind 颜色也有些腻了,于是今天在 Mastodon 上询问还有哪些其他调色板可用。一位朋友说他也想要这些调色板的链接,所以我写了这篇博文,好让我的朋友和其他人都能看到:)</p> <h3 id="my-favourites">我最喜欢的</h3> <p>我最喜欢的是:</p> <ul> <li><a href="https://uchu.style/">uchū</a>(<a href="https://code.webb.page/nevercease/uchu.git/tree/dist/uchu.css">CSS 文件</a>,<a href="https://code.webb.page/nevercease/uchu.git/about/documentation/FAQ.md">常见问题</a>)</li> <li><a href="https://stephango.com/flexoki">flexoki</a>(<a href="https://github.com/kepano/flexoki/blob/main/css/flexoki.css">CSS 文件</a>)</li> <li><a href="https://www.reasonable.work/artifacts/ra005-reasonable-colors/">reasonable co…
Show original
<p>A while back I decided to stop using Tailwind for new projects and to just write vanilla CSS instead.</p> <p>But one thing I missed about Tailwind was the <a href="https://v2.tailwindcss.com/docs/customizing-colors#color-palette-reference">colour palette</a> (<a href="https://gist.github.com/jvns/9e59b2cd1fe12601084ba78dded072fe">here as CSS</a>). If I wanted a light blue I could just use <code>blue-100</code> and if I didn&rsquo;t like it maybe try <code>blue-200</code> or <code>blue-50</code>. I&rsquo;m not very good with colours so it makes a big difference to me to have a reasonable colour palette that somebody who is better at colour than me has thought about.</p> <p>But I&rsquo;m also a little tired of those Tailwind colours, so I asked on Mastodon today what other colour palettes were out there. And then a friend said they wanted links to those colour palettes, so here&rsquo;s a blog post so my friend can see them, and all the rest of you too :)</p> <h3 id="my-favourites">my …
Read article Original

在浏览器中测试Vue组件

Translated AI Summary eng
[AI 摘要] 作者分享了在不使用Node.js的情况下,使用QUnit框架在浏览器中直接为Vue组件编写和运行端到端集成测试的实践经验。
View content
<p>大家好!我在这里的长期项目之一是 <a href="https://jvns.ca/#javascript">探索如何在不使用Node</a>或其他服务端JavaScript运行时的情况下编写前端JavaScript。</p> <p>我在前端JavaScript项目中经常遇到的一个问题是不知道如何为它们编写测试。我过去尝试过使用Playwright,但它似乎很慢且笨重,因为总是需要启动这些新的浏览器进程,而且需要一些Node代码来编排测试。</p> <p>结果就是我干脆不测试我的前端代码,这感觉不太好。通常我也不会经常更新我的项目,所以这个问题不常出现,但如果有更自信地进行更改的能力就好了!因此,一种我喜欢的前端测试方法已经列入我的愿望清单很久了。</p> <h3 id="idea-just-run-the-tests-in-the-browser-tab">想法:直接在浏览器标签页中运行测试</h3> <p>不久前,Alex Chan写了一篇很棒的文章,名为<a href="https://alexwlchan.net/2023/testing-javascript-without-a-framework/">Testing JavaScript without a (third-party) framework</a>,这是对我之前关于如何编写一个运行在浏览器页面中的微型单元测试框架系列文章的回应。</p> <p>我当时很喜欢这篇文章,但它只谈到了单元测试,而我想为我的Vue组件编写端到端的集成测试,我不知道该怎么做。</p> <p>所以,当我前几天和<a href="https://bsky.app/profile/polotek.bsky.social">Marco</a>交谈时,他说了类似“你知道,你可以直接在浏览器中运行你的Vue组件测试”的话,我想“嘿,我应该再试一次!!!”。</p> <p>我昨天刚完成这一切,所以肯定还有很多可以改进的地方,但我想在忘记之前写下我对这个过程的一些观察。</p> <p>这对我来说有点棘手,因为Vue网站通常假设你以某种方式在构建过程中使用Node(有很多“第一步:<code>npm install THING</code>”),而我不想使用Node/Deno等。但结果证明这并不太复杂。</p> <p>我将要讨论测…
Show original
<p>Hello! One of my long term projects on here is <a href="https://jvns.ca/#javascript">figuring out how to write frontend Javascript without using Node</a> or any other server JS runtime.</p> <p>One issue I run into a lot in my frontend JS projects is that I don&rsquo;t know how to write tests for them. I&rsquo;ve tried to use Playwright in the past, but it felt slow and unwieldy to be starting these new browser processes all the time, and it involved some Node code to orchestrate the tests.</p> <p>The result is that I just don&rsquo;t test my frontend code which doesn&rsquo;t feel great. Usually I don&rsquo;t update my projects much either so it doesn&rsquo;t come up that much, but it would be nice to be able to make changes with more confidence! So a way to do frontend testing that I like has been on my wishlist for a long time.</p> <h3 id="idea-just-run-the-tests-in-the-browser-tab">idea: just run the tests in the browser tab</h3> <p>Alex Chan wrote a great post a while back called…
Read article Original

tcpdump和dig手册页示例

Translated AI Summary eng
[AI 摘要] 作者为tcpdump和dig工具的手册页添加了面向初学者和不常用用户的基础示例。
View content
<p>你好!上个月关于<a href="https://jvns.ca/blog/2026/02/18/man-pages/">手册页的思考</a>让我最大的收获是:手册页中的示例真的非常有用,因此我着手为我最爱的两个工具的手册页添加(或改进)示例。</p> <p>以下是成果:</p> <ul> <li><a href="https://bind9.readthedocs.io/en/stable/manpages.html#dig-dns-lookup-utility">dig手册页(现已包含示例)</a></li> <li><a href="https://www.tcpdump.org/manpages/tcpdump.1.html#lbAF">tcpdump手册页示例</a>(这是在原有示例基础上的更新)</li> </ul> <h3 id="the-goal-include-the-most-basic-examples">目标:包含最基础的示例</h3> <p>这里的目标纯粹是提供关于如何使用该工具的最基础示例,面向那些不常使用tcpdump或dig(或从未使用过!)且不记得其工作原理的人。</p> <p>到目前为止,提出“我想为这个工具的初学者和不常使用的用户写一个示例章节”这个说法一直非常奏效。它易于解释,根据我听到的用户对手册页的需求,我认为这很合理,维护者们似乎也认为它很有说服力。</p> <p>感谢Denis Ovsienko、Guy Harris、Ondřej Surý以及所有审阅文档更改的人,这是一次愉快的经历,激励我继续在手册页上做更多工作。</p> <h3 id="why-improve-the-man-pages">为何要改进手册页?</h3> <p>我现在有兴趣参与工具官方文档的工作,因为:</p> <ul> <li>手册页实际上可以达到接近100%的准确性!经过审查流程以确保信息真实无误具有很大价值。</li> <li>即使是关于“tcpdump最常用的标志是什么”这样的基本问题,维护者通常也了解一些我不知道的实用功能!例如,在处理这些tcpdump示例时我了解到,使用<code>tcpdump -w out.pcap</code>将数据包保存到文件时,加上<code>-v</code>参数来打印已捕获数据包数量的实时摘要非常有用…
Show original
<p>Hello! My big takeaway from last month&rsquo;s <a href="https://jvns.ca/blog/2026/02/18/man-pages/">musings about man pages</a> was that examples in man pages are really great, so I worked on adding (or improving) examples to two of my favourite tools&rsquo; man pages.</p> <p>Here they are:</p> <ul> <li>the <a href="https://bind9.readthedocs.io/en/stable/manpages.html#dig-dns-lookup-utility">dig man page (now with examples)</a></li> <li>the <a href="https://www.tcpdump.org/manpages/tcpdump.1.html#lbAF">tcpdump man page examples</a> (this one is an update to the previous examples)</li> </ul> <h3 id="the-goal-include-the-most-basic-examples">the goal: include the most basic examples</h3> <p>The goal here was really just to give the absolute most basic examples of how to use the tool, for people who use tcpdump or dig infrequently (or have never used it before!) and don&rsquo;t remember how it works.</p> <p>So far saying &ldquo;hey, I want to write an examples section for beginners and…
Read article Original

关于改进手册页的笔记

Translated AI Summary eng
[AI 摘要] 本文探讨了改进命令行工具手册页的各种方法,包括添加选项摘要、分类组织、速查表和示例,以提升可用性。
View content
<p>大家好!去年花了些时间研究 Git 的手册页后,我开始更深入地思考什么才是好的手册页。</p> <p>我曾为许多工具(tcpdump、git、dig 等)编写速查表,这些工具的手册页是其主要文档。因为我经常发现手册页难以快速找到所需信息。</p> <p>最近我在想——手册页本身能否包含出色的速查表?什么能让手册页更易用?我的思考还处于早期阶段,但想先记录下一些快速笔记。</p> <p>我在 Mastodon 上询问了大家最喜欢的手册页,以下是我从那些手册页中看到的一些有趣示例。</p> <h3 id="an-options-summary">选项摘要</h3> <p>如果你读过很多手册页,可能在<code>SYNOPSIS</code>部分见过类似这样的内容:当你列出几乎所有字母时,就显得很难读</p> <pre><code>ls [-@ABCFGHILOPRSTUWabcdefghiklmnopqrstuvwxy1%,] grep [-abcdDEFGHhIiJLlMmnOopqRSsUVvwXxZz] </code></pre> <p><a href="https://download.samba.org/pub/rsync/rsync.1">rsync 手册页</a>有一个我从未见过的解决方案:它将 SYNOPSIS 保持得非常简洁,像这样:</p> <pre><code> Local: rsync [OPTION...] SRC... [DEST] </code></pre> <p>然后有一个"选项摘要"部分,每个选项用一行总结,如下:</p> <pre><code>--verbose, -v increase verbosity --info=FLAGS fine-grained informational verbosity --debug=FLAGS fine-grained debug verbosity --stderr=e|a|c change stderr output mode (default: errors) --quiet, -q suppress non-error messages --no-motd …
Show original
<p>Hello! After <a href="https://jvns.ca/blog/2026/01/08/a-data-model-for-git/">spending some time working on the Git man pages</a> last year, I&rsquo;ve been thinking a little more about what makes a good man page.</p> <p>I&rsquo;ve spent a lot of time writing cheat sheets for tools (tcpdump, git, dig, etc) which have a man page as their primary documentation. This is because I often find the man pages hard to navigate to get the information I want.</p> <p>Lately I&rsquo;ve wondering &ndash; could the man page <em>itself</em> have an amazing cheat sheet in it? What might make a man page easier to use? I&rsquo;m still very early in thinking about this but I wanted to write down some quick notes.</p> <p>I <a href="https://social.jvns.ca/@b0rk/116092583707187579">asked some people on Mastodon</a> for their favourite man pages, and here are some examples of interesting things I saw on those man pages.</p> <h3 id="an-options-summary">an OPTIONS SUMMARY</h3> <p>If you&rsquo;ve read a lot of…
Read article Original

开始使用 Django 的一些笔记

Translated AI Summary eng
[AI 摘要] 这是一篇关于作者初次学习并使用 Django Web 框架的个人体验笔记,分享了其相比 Rails 更显式、内置管理界面、ORM 及迁移系统、良好文档和内置功能等优点。
View content
<p>你好!我最喜欢的事情之一,就是开始学习一门我从未尝试过但已经存在 20 多年的“老旧无聊技术”。当发现我将来可能遇到的每一个问题都已经被解决过上千次,我可以轻松搞定一切时,感觉真的很好。</p> <p>我很久以前就觉得学习像 Rails、Django 或 Laravel 这样流行的 Web 框架会很酷,但一直没能真正付诸行动。不过几个月前,我开始学习 Django 来制作一个网站,到目前为止我很喜欢它,这里有一些简短的笔记!</p> <h3 id="less-magic-than-rails">比 Rails 魔法少</h3> <p>我在 2020 年花了一些时间<a href="https://jvns.ca/blog/2020/11/09/day-1--a-little-rails-/">尝试学习 Rails</a>,虽然它很酷,而且我真的很想喜欢 Rails(Ruby 社区很棒!),但我发现如果我将一个 Rails 项目闲置几个月,当我回来时,就很难记起如何进行任何操作,因为(例如)如果在你的 <code>routes.rb</code> 文件中写着 <code>resources :topics</code>,这本身并不能告诉你 <code>topics</code> 路由是在哪里配置的,你需要记住或查阅相关约定。</p> <p>能够将一个项目搁置数月甚至数年,然后回来继续工作,对我来说非常重要(我所有的项目都是这样运作的!),而 Django 对我来说感觉更容易,因为事物更加显式。</p> <p>在我的小型 Django 项目中,感觉我只需要关注 5 个主要文件(除了设置文件):<code>urls.py</code>、<code>models.py</code>、<code>views.py</code>、<code>admin.py</code> 和 <code>tests.py</code>,如果我想知道其他东西(比如 HTML 模板)在哪里,它通常会从其中一个文件中被显式引用。</p> <h3 id="a-built-in-admin">一个内置的管理后台</h3> <p>对于这个项目,我想要有一个管理界面来手动编辑或查看数据库中的某些数据。Django 有一个非常好的内置管理界面,我只需少量代码就能对其进行自定义。</p> <p>例如,这是…
Show original
<p>Hello! One of my favourite things is starting to learn an Old Boring Technology that I&rsquo;ve never tried before but that has been around for 20+ years. It feels really good when every problem I&rsquo;m ever going to have has been solved already 1000 times and I can just get stuff done easily.</p> <p>I&rsquo;ve thought it would be cool to learn a popular web framework like Rails or Django or Laravel for a long time, but I&rsquo;d never really managed to make it happen. But I started learning Django to make a website a few months back, I&rsquo;ve been liking it so far, and here are a few quick notes!</p> <h3 id="less-magic-than-rails">less magic than Rails</h3> <p>I spent some time <a href="https://jvns.ca/blog/2020/11/09/day-1--a-little-rails-/">trying to learn Rails</a> in 2020, and while it was cool and I really wanted to like Rails (the Ruby community is great!), I found that if I left my Rails project alone for months, when I came back to it it was hard for me to remember how …
Read article Original

Git 的数据模型(及其他文档更新)

Translated AI Summary eng
[AI 摘要] 作者通过撰写新数据模型文档和根据测试读者反馈改进手册页,为 Git 文档做出了贡献。
View content
<p>大家好!去年秋天,我决定花一些时间来改进 Git 的文档。我早就想为开源文档做贡献了——通常如果我觉得某个软件的文档可以改进,我会写一篇博客文章或一份 zine 之类的。但这次我转念一想:我能不能直接去改进官方文档呢?</p> <p>于是 <a href="https://marieflanagan.com/">Marie</a> 和我对 Git 文档做了一些改动!</p> <h3 id="a-data-model-for-git">Git 的一个数据模型</h3> <p>在参与文档工作一段时间后,我们注意到 Git 在其文档中频繁使用“对象”、“引用”或“索引”等术语,却没有很好地解释这些术语的含义,或者它们如何与“提交”和“分支”等其他核心概念相关联。因此,我们撰写了一份新的“数据模型”文档!</p> <p>你可以<a href="https://github.com/git/git/blob/master/Documentation/gitdatamodel.adoc">在此处阅读该数据模型</a>(目前版本)。我估计在某个时候(下一次发布之后?),它也会出现在 <a href="https://git-scm.com">Git 网站</a>上。</p> <p>我对此感到很兴奋,因为理解 Git 如何组织其提交和分支数据,多年来真正帮助我理解了 Git 的工作原理。我认为有一份简短(1600 词!)且准确的数据模型版本是很重要的。</p> <p>“准确”这部分证明并非易事:我知道 Git 数据模型如何工作的基础知识,但在审查过程中,我学到了一些新的细节,并不得不做出相当多的修改(例如,暂存区如何存储合并冲突)。</p> <h3 id="updates-to-git-push-git-pull-and-more">更新 <code>git push</code>、<code>git pull</code> 及更多内容</h3> <p>我还致力于更新一些 Git 核心手册页的介绍部分。我很快意识到,“仅凭我的最佳判断去尝试改进”是行不通的:为什么维护者应该相信我的版本更好?</p> <p>在讨论开源文档改动时,我经常看到一个问题:两位软件的专家用户会争论某个解释是否清晰(“我觉得 X 是个好方法!” “不,我觉得 Y 更好!”)。</p> <p>我认为这样做…
Show original
<p>Hello! This past fall, I decided to take some time to work on Git&rsquo;s documentation. I&rsquo;ve been thinking about working on open source docs for a long time &ndash; usually if I think the documentation for something could be improved, I&rsquo;ll write a blog post or a zine or something. But this time I wondered: could I instead make a few improvements to the official documentation?</p> <p>So <a href="https://marieflanagan.com/">Marie</a> and I made a few changes to the Git documentation!</p> <h3 id="a-data-model-for-git">a data model for Git</h3> <p>After a while working on the documentation, we noticed that Git uses the terms &ldquo;object&rdquo;, &ldquo;reference&rdquo;, or &ldquo;index&rdquo; in its documentation a lot, but that it didn&rsquo;t have a great explanation of what those terms mean or how they relate to other core concepts like &ldquo;commit&rdquo; and &ldquo;branch&rdquo;. So we wrote a new &ldquo;data model&rdquo; document!</p> <p>You can <a href="https://git…
Read article Original

从vim切换到Helix的笔记

Translated AI Summary eng
[AI 摘要] 本文作者分享了从 Vim 切换到 Helix 编辑器三个月的体验,包括选择原因、与 Vim 的对比以及遇到的优缺点。
View content
<p>你好!今年夏天早些时候,我和一位朋友聊到我有多<a href="https://jvns.ca/blog/2024/09/12/reasons-i--still--love-fish/">喜欢使用 fish shell</a>,以及我有多喜欢它不需要我进行配置。他们说对 <a href="https://helix-editor.com/">Helix</a> 文本编辑器也有同样的感觉,所以我决定尝试一下。</p> <p>我已经使用它三个月了,以下是一些笔记。</p> <h3 id="why-helix-language-servers">为什么选择 Helix:语言服务器</h3> <p>我想尝试 Helix 的动机在于,我一直在尝试设置一个可用的语言服务器环境(这样我就能做诸如“跳转到定义”之类的事情),而在 Vim 或 Neovim 中搭建一个感觉良好的环境实在费时费力。</p> <p>在使用 Vim/Neovim 20 年后,我尝试过“从零开始构建自己的自定义配置”和“使用别人预先构建的配置系统”,尽管我热爱 Vim,但想到一切都能直接工作而无需在配置上花费精力,我还是感到兴奋。</p> <p>Helix 内置了语言服务器支持,能在任何语言中轻松执行诸如“重命名此符号”之类的操作,感觉很棒。</p> <h3 id="the-search-is-great">搜索功能很棒</h3> <p>Helix 中我最喜欢的一点是它的搜索功能!如果我在整个代码库中搜索某个字符串,它会让我滚动浏览可能的匹配文件,并看到匹配行的完整上下文,就像这样:</p> <img src="/images/helix-search.png"> <p>作为对比,这里是我之前一直在用的 Vim ripgrep 插件的样子:</p> <img src="/images/vim-ripgrep.png"> <p>它没有显示该行周围的其他上下文。</p> <h3 id="the-quick-reference-is-nice">快速参考提示很好</h3> <p>我喜欢 Helix 的一点是,当我按下 <code>g</code> 键时,会弹出一个小帮助菜单,告诉我可以跳转到哪里。我非常欣赏这一点,因为我不常使用“跳转到定义”或“跳转到引用”功能,经常忘记相应的键盘快捷键。</p> <img …
Show original
<p>Hello! Earlier this summer I was talking to a friend about how much I <a href="https://jvns.ca/blog/2024/09/12/reasons-i--still--love-fish/">love using fish</a>, and how I love that I don&rsquo;t have to configure it. They said that they feel the same way about the <a href="https://helix-editor.com/">helix</a> text editor, and so I decided to give it a try.</p> <p>I&rsquo;ve been using it for 3 months now and here are a few notes.</p> <h3 id="why-helix-language-servers">why helix: language servers</h3> <p>I think what motivated me to try Helix is that I&rsquo;ve been trying to get a working language server setup (so I can do things like &ldquo;go to definition&rdquo;) and getting a setup that feels good in Vim or Neovim just felt like too much work.</p> <p>After using Vim/Neovim for 20 years, I&rsquo;ve tried both &ldquo;build my own custom configuration from scratch&rdquo; and &ldquo;use someone else&rsquo;s pre-buld configuration system&rdquo; and even though I love Vim I was exci…
Read article Original

新Zine:终端的神秘规则

Translated AI Summary eng
[AI 摘要] 本文介绍了新Zine《终端的神秘规则》的发布,解释了终端内部工作原理和写作背景。
View content
<p>你好!经过数月深入撰写关于终端的博客文章,我于周二发布了一本新Zine,名为《终端的神秘规则》!</p> <p>你可以在这里以12美元购买:<a href="https://wizardzines.com/zines/terminal">https://wizardzines.com/zines/terminal</a>,或者在此获取<a href="https://wizardzines.com/zines/all-the-zines/">我所有Zine的15本套装</a>。</p> <p>这是封面:</p> <div align="center"> <a href="https://wizardzines.com/zines/terminal"> <img width="600px" src="https://jvns.ca/images/terminal-cover-small.jpg"> </a> </div> <h3 id="the-table-of-contents">目录</h3> <p>以下是目录:</p> <a href="https://wizardzines.com/zines/terminal/toc.png"> <img width="600px" src="https://jvns.ca/images/terminal-toc-small.png"> </a> <h3 id="why-the-terminal">为什么是终端?</h3> <p>我已经使用终端20年了,但尽管我对终端非常自信,我总是对它有一点不安的感觉。通常事情运行顺利,但有时出问题时,感觉调查起来不可能,或者至少像会引发一大堆问题。</p> <p>所以我开始尝试列出我在终端中遇到的一些奇怪问题,并意识到终端有许多微小的不一致性,比如:</p> <ul> <li>有时你可以使用方向键移动,但有时按下方向键只会打印<code>^[[D</code></li> <li>有时你可以用鼠标选择文本,但有时不能</li> <li>有时运行命令时会被保存到历史记录中,有时则不会</li> <li>有些shell允许你用上箭头查看之前的命令,有些则不允许</li> </ul> <p>如果你每天使用终端10或20年,即使你不完全理解<em>为什么</em>这些事情会发生,…
Show original
<p>Hello! After many months of writing deep dive blog posts about the terminal, on Tuesday I released a new zine called &ldquo;The Secret Rules of the Terminal&rdquo;!</p> <p>You can get it for $12 here: <a href="https://wizardzines.com/zines/terminal">https://wizardzines.com/zines/terminal</a>, or get an <a href="https://wizardzines.com/zines/all-the-zines/">15-pack of all my zines here</a>.</p> <p>Here&rsquo;s the cover:</p> <div align="center"> <a href="https://wizardzines.com/zines/terminal"> <img width="600px" src="https://jvns.ca/images/terminal-cover-small.jpg"> </a> </div> <h3 id="the-table-of-contents">the table of contents</h3> <p>Here&rsquo;s the table of contents:</p> <a href="https://wizardzines.com/zines/terminal/toc.png"> <img width="600px" src="https://jvns.ca/images/terminal-toc-small.png"> </a> <h3 id="why-the-terminal">why the terminal?</h3> <p>I&rsquo;ve been using the terminal every day for 20 years but even though I&rsquo;m very confident in the terminal, I&…
Read article Original

使用 `make` 编译 C 程序(面向非 C 程序员)

Translated AI Summary eng
[AI 摘要] 这篇文章介绍非 C 程序员如何使用 `make` 工具来编译 C 程序,并提供了实用步骤和技巧。
View content
<p>我从来不是一名 C 程序员,但偶尔需要从源代码编译 C/C++ 程序。这对我来说一直有点困难:很长一段时间,我的方法基本上是“安装依赖项,运行 <code>make</code>,如果不行,就试着找到别人编译好的二进制文件,或者放弃”。</p> <p>“希望别人已经编译好”在我使用 Linux 时效果不错,但自从两年前我开始使用 Mac 后,我遇到更多必须自己编译程序的情况。</p> <p>所以,让我们来谈谈编译 C 程序可能需要做什么!我将使用几个我编译过的 C 程序示例,并讨论一些可能出错的地方。以下是三个我们将要讨论编译的程序:</p> <ul> <li><a href="https://mj.ucw.cz/sw/paperjam/">paperjam</a></li> <li><a href="https://www.sqlite.org/download.html">sqlite</a></li> <li><a href="https://git.causal.agency/src/tree/bin/qf.c">qf</a>(一个分页器,可以使用 <code>rg -n THING | qf</code> 从搜索结果快速打开文件)</li> </ul> <h3 id="step-1-install-a-c-compiler">步骤 1:安装 C 编译器</h3> <p>这很简单:在 Ubuntu 系统上,如果我没有 C 编译器,我会用以下命令安装一个:</p> <pre><code>sudo apt-get install build-essential </code></pre> <p>这会安装 <code>gcc</code>、<code>g++</code> 和 <code>make</code>。在 Mac 上的情况更复杂,但大致是“安装 Xcode 命令行工具”。</p> <h3 id="step-2-install-the-program-s-dependencies">步骤 2:安装程序的依赖项</h3> <p>与一些较新的编程语言不同,C 没有依赖管理器。因此,如果程序有任何依赖项,你需要自己寻找它们。幸运的是,正因为如此,C 程序员通常保持依赖项非常 minimal,并且依赖项通常可以在你使用的任何包管理器中找到。</p> <p>几…
Show original
<p>I have never been a C programmer but every so often I need to compile a C/C++ program from source. This has been kind of a struggle for me: for a long time, my approach was basically &ldquo;install the dependencies, run <code>make</code>, if it doesn&rsquo;t work, either try to find a binary someone has compiled or give up&rdquo;.</p> <p>&ldquo;Hope someone else has compiled it&rdquo; worked pretty well when I was running Linux but since I&rsquo;ve been using a Mac for the last couple of years I&rsquo;ve been running into more situations where I have to actually compile programs myself.</p> <p>So let&rsquo;s talk about what you might have to do to compile a C program! I&rsquo;ll use a couple of examples of specific C programs I&rsquo;ve compiled and talk about a few things that can go wrong. Here are three programs we&rsquo;ll be talking about compiling:</p> <ul> <li><a href="https://mj.ucw.cz/sw/paperjam/">paperjam</a></li> <li><a href="https://www.sqlite.org/download.html">sqlite<…
Read article Original

ANSI 转义码的标准

Translated AI Summary eng
[AI 摘要] 本文探讨了 ANSI 转义码的相关标准(如 ECMA-48、xterm 序列、terminfo)及其尚未完全统一的现状,展望了终端体验未来改善的可能性。
View content
<p>大家好!今天我想聊聊 ANSI 转义码。</p> <p>长期以来,我对 ANSI 转义码只有一个模糊的概念(“就是在终端里把文字变红之类的东西”),但完全不清楚它们应该在哪里定义,是否存在相关标准。我对它们总有一种“神龙见首不见尾”的模糊感觉。今年在学习终端相关知识时,我了解到:</p> <ol> <li>ANSI 转义码对终端的可用性改进功不可没(你知道在 SSH 连接到远程机器时,有办法复制到系统剪贴板吗??这涉及到一个名为 <a href="https://jvns.ca/til/vim-osc52/">OSC 52</a> 的转义码!)</li> <li>它们并未完全标准化,因此并不总是能可靠地工作。而且由于它们是不可见的,排查转义码相关问题会令人极其沮丧。</li> </ol> <p>所以我想为自己整理一份关于现有转义码标准的清单,因为我想知道它们是否<em>注定</em>要显得不可靠且令人头疼,或者未来我们是否可以更放心地依赖它们。</p> <ul> <li><a href="#what-s-an-escape-code">什么是转义码?</a></li> <li><a href="#ecma-48">ECMA-48</a></li> <li><a href="#xterm-control-sequences">xterm 控制序列</a></li> <li><a href="#terminfo">terminfo</a></li> <li><a href="#should-programs-use-terminfo">程序应该使用 terminfo 吗?</a></li> <li><a href="#is-there-a-single-common-set-of-escape-codes">是否存在“单一通用集”的转义码?</a></li> <li><a href="#some-reasons-to-use-terminfo">使用 terminfo 的一些理由</a></li> <li><a href="#some-more-documents-standards">更多文档/标准</a></li> <li><a href="#why-i-think-this-is-interesting">为什么我觉得这很有趣</a></li> </ul> …
Show original
<p>Hello! Today I want to talk about ANSI escape codes.</p> <p>For a long time I was vaguely aware of ANSI escape codes (&ldquo;that&rsquo;s how you make text red in the terminal and stuff&rdquo;) but I had no real understanding of where they were supposed to be defined or whether or not there were standards for them. I just had a kind of vague &ldquo;there be dragons&rdquo; feeling around them. While learning about the terminal this year, I&rsquo;ve learned that:</p> <ol> <li>ANSI escape codes are responsible for a lot of usability improvements in the terminal (did you know there&rsquo;s a way to copy to your system clipboard when SSHed into a remote machine?? It&rsquo;s an escape code called <a href="https://jvns.ca/til/vim-osc52/">OSC 52</a>!)</li> <li>They aren&rsquo;t completely standardized, and because of that they don&rsquo;t always work reliably. And because they&rsquo;re also invisible, it&rsquo;s extremely frustrating to troubleshoot escape code issues.</li> </ol> <p>So I wa…
Read article Original

如何将目录添加到你的PATH

Translated AI Summary eng
[AI 摘要] 本文提供了在bash、zsh和fish中添加目录到PATH环境变量的详细步骤、配置文件查找和常见问题解决方案。
View content
<p>今天我和一个朋友聊到如何将目录添加到PATH。对我来说,这似乎“显而易见”,因为我长期使用终端,但当我搜索操作说明时,实际上找不到一个解释所有步骤的——很多只是说“将此添加到<code>~/.bashrc</code>”,但如果你不用bash呢?如果你的bash配置文件在另一个文件里呢?而且,你该如何确定要添加哪个目录?</p> <p>因此,我想尝试写下更完整的指导,并提及我多年来遇到的一些陷阱。</p> <p>以下是目录:</p> <ul> <li><a href="#step-1-what-shell-are-you-using">步骤1:你使用的是哪个shell?</a></li> <li><a href="#step-2-find-your-shell-s-config-file">步骤2:找到你的shell配置文件</a> <ul> <li><a href="#a-note-on-bash-s-config-file">关于bash配置文件的说明</a></li> </ul> </li> <li><a href="#step-3-figure-out-which-directory-to-add">步骤3:确定要添加的目录</a> <ul> <li><a href="#step-3-1-double-check-it-s-the-right-directory">步骤3.1:确认是正确的目录</a></li> </ul> </li> <li><a href="#step-4-edit-your-shell-config">步骤4:编辑你的shell配置</a></li> <li><a href="#step-5-restart-your-shell">步骤5:重启你的shell</a></li> <li>问题: <ul> <li><a href="#problem-1-it-ran-the-wrong-program">问题1:运行了错误的程序</a></li> <li><a href="#problem-2-the-program-isn-t-being-run-from-your-shell">问题2:程序未从你的shell运行</a></li> <li><a href="#problem-3-duplicate-path-entries-mak…
Show original
<p>I was talking to a friend about how to add a directory to your PATH today. It&rsquo;s something that feels &ldquo;obvious&rdquo; to me since I&rsquo;ve been using the terminal for a long time, but when I searched for instructions for how to do it, I actually couldn&rsquo;t find something that explained all of the steps &ndash; a lot of them just said &ldquo;add this to <code>~/.bashrc</code>&rdquo;, but what if you&rsquo;re not using bash? What if your bash config is actually in a different file? And how are you supposed to figure out which directory to add anyway?</p> <p>So I wanted to try to write down some more complete directions and mention some of the gotchas I&rsquo;ve run into over the years.</p> <p>Here&rsquo;s a table of contents:</p> <ul> <li><a href="#step-1-what-shell-are-you-using">step 1: what shell are you using?</a></li> <li><a href="#step-2-find-your-shell-s-config-file">step 2: find your shell&rsquo;s config file</a> <ul> <li><a href="#a-note-on-bash-s-config-file…
Read article Original

一些终端使用中的挫败感

Translated AI Summary eng
[AI 摘要] 该文分类总结了一项针对1600名资深终端用户的调查结果,列举了他们在使用终端时遇到的主要挫败点。
View content
<p>几周前,我进行了一次终端使用调查(你可以<a href="https://jvns.ca/terminal-survey/results-bsky.html">在此查看结果</a>),在调查的最后我问了这样一个问题:</p> <blockquote> <p>对你来说,使用终端最令人感到挫败的是什么?</p> </blockquote> <p>有1600人回答了这个问题,我决定花几天时间将所有回复分类。在这个过程中,我了解到对定性数据进行分类并不容易,但我尽力了。为了加快分类速度,我专门构建了一个<a href="https://github.com/jvns/classificator">工具</a>。</p> <p>与我的所有调查一样,这个方法论并不是特别科学。我只是在Mastodon和Twitter上发布了调查,运行了几天,收集了那些恰好看到并愿意回答的人的意见。</p> <p>以下是主要的挫败感类别!</p> <p>我认为在阅读这些评论时,有必要记住以下几点:</p> <ul> <li>参与此调查的人中,有40%使用终端已超过<strong>21年</strong>。</li> <li>参与调查的人中,有95%使用终端至少有4年。</li> </ul> <p>这些评论并非来自完全的初学者。</p> <p>以下是各类挫败感!括号中的数字是持有该种挫败感的人数。我主要将这些记录下来是因为我自己正在尝试编写一本关于终端的小册子,我想了解人们遇到了哪些困难。</p> <h3 id="remembering-syntax-115">记忆语法(115)</h3> <p>人们提到了记忆以下内容的困难:</p> <ul> <li>awk、jq、sed等命令行工具的语法</li> <li>重定向的语法</li> <li>tmux、文本编辑器等的快捷键</li> </ul> <p>一个示例评论:</p> <blockquote> <p>要掌握全部功能,有太多细小的“琐碎”细节需要记忆。即使过了这么多年,我有时还是会忘记标准错误输出是2还是1,或者忘记<code>&gt;</code>和<code>&gt;&gt;</code>哪个是哪个。</p> </blockquote> <h3 id="switching-terminals-is-hard-91">切换终端环境很难(9…
Show original
<p>A few weeks ago I ran a terminal survey (you can <a href="https://jvns.ca/terminal-survey/results-bsky.html">read the results here</a>) and at the end I asked:</p> <blockquote> <p>What’s the most frustrating thing about using the terminal for you?</p> </blockquote> <p>1600 people answered, and I decided to spend a few days categorizing all the responses. Along the way I learned that classifying qualitative data is not easy but I gave it my best shot. I ended up building a custom <a href="https://github.com/jvns/classificator">tool</a> to make it faster to categorize everything.</p> <p>As with all of my surveys the methodology isn&rsquo;t particularly scientific. I just posted the survey to Mastodon and Twitter, ran it for a couple of days, and got answers from whoever happened to see it and felt like responding.</p> <p>Here are the top categories of frustrations!</p> <p>I think it&rsquo;s worth keeping in mind while reading these comments that</p> <ul> <li>40% of people answering th…
Read article Original

什么是配置"现代"终端环境所涉及的?

Translated AI Summary eng
[AI 摘要] 本文探讨了配置一个功能齐全的现代终端环境所涉及的复杂性和诸多挑战。
View content
<p>你好!最近我进行了一次终端使用调查,并询问了用户们对哪些方面感到困扰。其中一人评论道:</p> <blockquote> <p>要获得现代终端体验,涉及太多组件了。真希望它们能开箱即用。</p> </blockquote> <p>我最初的反应是“哦,配置现代终端体验并不难,你只需要……”,但想得越多,“你只需要……”的清单就越长,而且我不断想到越来越多的注意事项。</p> <p>因此,我决定写些笔记,谈谈我个人对“现代”终端体验的理解,以及我认为什么因素让人们难以实现它。</p> <h3 id="what-is-a-modern-terminal-experience">什么是“现代终端体验”?</h3> <p>以下是我个人认为重要的几点,并注明了系统中由哪部分负责实现:</p> <ul> <li><strong>多行复制粘贴支持</strong>:如果你在shell中粘贴3条命令,它不应该立即全部执行!那太吓人了!(<strong>shell</strong>,<strong>终端模拟器</strong>)</li> <li><strong>无限的shell历史记录</strong>:如果我在shell中运行了一个命令,它应该被永久保存,而不是在500条历史记录后就被删除。另外,我希望命令在运行时立即保存到历史记录,而不是在退出shell会话时才保存(<strong>shell</strong>)</li> <li><strong>有用的提示符</strong>:没有在提示符中显示<strong>当前目录</strong>和<strong>当前git分支</strong>,我简直无法工作(<strong>shell</strong>)</li> <li><strong>24位色</strong>:这对我很重要,因为发现在支持24位色的终端中配置neovim的主题比在仅支持256色的终端中容易得多(<strong>终端模拟器</strong>)</li> <li><strong>剪贴板集成</strong>:让vim和我的操作系统实现剪贴板集成,这样当我在Firefox中复制内容后,只需在vim中按<code>p</code>键就能粘贴(<strong>文本编辑器</strong>,可能还需要操作系统/终端模拟器的支持)</li> <li><strong>良好…
Show original
<p>Hello! Recently I ran a terminal survey and I asked people what frustrated them. One person commented:</p> <blockquote> <p>There are so many pieces to having a modern terminal experience. I wish it all came out of the box.</p> </blockquote> <p>My immediate reaction was &ldquo;oh, getting a modern terminal experience isn&rsquo;t that hard, you just need to&hellip;.&rdquo;, but the more I thought about it, the longer the &ldquo;you just need to&hellip;&rdquo; list got, and I kept thinking about more and more caveats.</p> <p>So I thought I would write down some notes about what it means to me personally to have a &ldquo;modern&rdquo; terminal experience and what I think can make it hard for people to get there.</p> <h3 id="what-is-a-modern-terminal-experience">what is a &ldquo;modern terminal experience&rdquo;?</h3> <p>Here are a few things that are important to me, with which part of the system is responsible for them:</p> <ul> <li><strong>multiline support for copy and paste</strong>…
Read article Original

终端程序所遵循的“规则”

Translated AI Summary eng
[AI 摘要] 这篇文章描述了终端程序遵循的一些常见但非官方的、观察到的行为“规则”。
View content
最近我一直在思考,终端中发生的一切都是以下部分的某种组合: <ol> <li>你的<strong>操作系统</strong>的任务</li> <li>你的<strong>shell</strong>的任务</li> <li>你的<strong>终端模拟器</strong>的任务</li> <li><strong>你恰好正在运行的程序</strong>(比如 <code>top</code> 或 <code>vim</code> 或 <code>cat</code>)的任务</li> </ol> <p>前三个(你的操作系统、shell和终端模拟器)都算是已知量——如果你在Linux上的GNOME终端中使用bash,你大概可以推断出所有这些组件如何互动,它们的一些行为也被POSIX标准化。</p> <p>但第四个(“你恰好正在运行的程序”)感觉可能做任何事情。你怎么知道一个程序会如何表现?</p> <p>这篇文章有点长,所以这里有一个快速的目录:</p> <ul> <li><a href="#programs-behave-surprisingly-consistently">程序表现得出奇地一致</a></li> <li><a href="#these-are-meant-to-be-descriptive-not-prescriptive">这些是描述性的,而非规定性的</a></li> <li><a href="#it-s-not-always-obvious-which-rules-are-the-program-s-responsibility-to-implement">并非总是显而易见哪些“规则”是程序应实现的责任</a></li> <li><a href="#rule-1-noninteractive-programs-should-quit-when-you-press-ctrl-c">规则1:非交互式程序应在你按 <code>Ctrl-C</code> 时退出</a></li> <li><a href="#rule-2-tuis-should-quit-when-you-press-q">规则2:TUI应在你按 <code>q</code> 时退出</a></li> <li><a href="#rule-3-repls-should-quit-whe…
Show original
<p>Recently I&rsquo;ve been thinking about how everything that happens in the terminal is some combination of:</p> <ol> <li>Your <strong>operating system</strong>&rsquo;s job</li> <li>Your <strong>shell</strong>&rsquo;s job</li> <li>Your <strong>terminal emulator</strong>&rsquo;s job</li> <li>The job of <strong>whatever program you happen to be running</strong> (like <code>top</code> or <code>vim</code> or <code>cat</code>)</li> </ol> <p>The first three (your operating system, shell, and terminal emulator) are all kind of known quantities &ndash; if you&rsquo;re using bash in GNOME Terminal on Linux, you can more or less reason about how how all of those things interact, and some of their behaviour is standardized by POSIX.</p> <p>But the fourth one (&ldquo;whatever program you happen to be running&rdquo;) feels like it could do ANYTHING. How are you supposed to know how a program is going to behave?</p> <p>This post is kind of long so here&rsquo;s a quick table of contents:</p> <ul> <…
Read article Original

管道为何有时会“卡住”:缓冲机制

Translated AI Summary eng
[AI 摘要] 本文解释了Unix管道有时输出延迟的原因是程序缓冲机制,并提供了多种解决方案来禁用缓冲。
View content
<p>这是一个困扰我多年的终端小众问题,但直到几周前我才真正理解。假设你运行以下命令来监视日志文件中的特定输出:</p> <pre><code>tail -f /some/log/file | grep thing1 | grep thing2 </code></pre> <p>如果日志行添加到文件的速度相对较慢,我看到的结果就是……什么都没有!无论日志文件中是否有匹配项,都不会有任何输出。</p> <p>我默认接受了这个现象:“呃,我猜管道有时候就是会卡住,不显示输出,真奇怪”,然后我会改用 <code>grep thing1 /some/log/file | grep thing2</code> 来处理,这样就能工作。</p> <p>所以在过去几个月深入研究终端时,我非常兴奋地终于明白了这到底是为什么。</p> <h3 id="why-this-happens-buffering">原因:缓冲</h3> <p>“管道卡住”的原因在于,程序在将输出写入管道或文件之前进行缓冲是非常常见的做法。所以管道本身工作正常,问题在于程序根本没有将数据写入管道!</p> <p>这是出于性能考虑:立即将所有输出写入会使用更多系统调用,因此更高效的做法是积累数据直到有大约 8KB 的数据要写入(或直到程序退出),然后再将其写入管道。</p> <p>在这个例子中:</p> <pre><code>tail -f /some/log/file | grep thing1 | grep thing2 </code></pre> <p>问题在于 <code>grep thing1</code> 会保存所有匹配项,直到积累大约 8KB 的数据才写入,而这可能永远不会发生。</p> <h3 id="programs-don-t-buffer-when-writing-to-a-terminal">程序写入终端时不进行缓冲</h3> <p>我觉得这很令人困惑的部分原因是,<code>tail -f file | grep thing</code> 完全可以正常工作,但当你添加第二个 <code>grep</code> 时,它就停止工作了!原因是 <code>grep</code> 处理缓冲的方式取决于它是否写入终端。</p> <p>以下是 <code>grep</code>(以及许多其他程序)决定…
Show original
<p>Here&rsquo;s a niche terminal problem that has bothered me for years but that I never really understood until a few weeks ago. Let&rsquo;s say you&rsquo;re running this command to watch for some specific output in a log file:</p> <pre><code>tail -f /some/log/file | grep thing1 | grep thing2 </code></pre> <p>If log lines are being added to the file relatively slowly, the result I&rsquo;d see is&hellip; nothing! It doesn&rsquo;t matter if there were matches in the log file or not, there just wouldn&rsquo;t be any output.</p> <p>I internalized this as &ldquo;uh, I guess pipes just get stuck sometimes and don&rsquo;t show me the output, that&rsquo;s weird&rdquo;, and I&rsquo;d handle it by just running <code>grep thing1 /some/log/file | grep thing2</code> instead, which would work.</p> <p>So as I&rsquo;ve been doing a terminal deep dive over the last few months I was really excited to finally learn exactly why this happens.</p> <h3 id="why-this-happens-buffering">why this happens: buffe…
Read article Original

如何在无构建系统的情况下导入前端 JavaScript 库

Translated AI Summary eng
[AI 摘要] 本文介绍了在没有构建系统的情况下导入前端JavaScript库的方法,包括不同文件类型的识别和使用工具如import maps、esm.sh等。
View content
<p>我喜欢在没有构建系统的情况下编写 JavaScript(<a href="https://jvns.ca/blog/2023/02/16/writing-javascript-without-a-build-system/">without a build system</a>),昨天我又一次遇到了需要在不使用构建系统的情况下导入 JavaScript 库的问题,花了很长时间才弄清楚如何导入,因为库的设置说明假定你正在使用构建系统。</p> <p>幸运的是,到现在我基本上已经学会了如何处理这种情况,要么成功使用该库,要么决定它太难而切换到另一个库,所以这是我希望多年前就有的关于导入 JavaScript 库的指南。</p> <p>我将只讨论在前端使用 JavaScript 库,并且只关于如何在无构建系统的设置中使用它们。</p> <p>在这篇文章中,我将讨论:</p> <ol> <li>库可能提供的三种主要 JavaScript 文件类型(ES 模块、"经典"全局变量类型和 CommonJS)</li> <li>如何确定 JavaScript 库在其构建中包含了哪些类型的文件</li> <li>在代码中导入每种类型文件的方法</li> </ol> <h3 id="the-three-kinds-of-javascript-files">三种 JavaScript 文件类型</h3> <p>库可以提供 3 种基本类型的 JavaScript 文件:</p> <ol> <li>定义全局变量的"经典"类型文件。这种文件你可以直接使用 <code>&lt;script src&gt;</code>,它就能正常工作。如果你能得到它,这很好,但并非总是可用。</li> <li>一个 ES 模块(可能依赖或不依赖其他文件,我们将谈到这一点)。</li> <li>一个"CommonJS"模块。这是用于 Node 的,如果不使用构建系统,你根本无法在浏览器中使用它。</li> </ol> <p>我不确定"经典"类型是否有更好的名称,但我将只称它为"经典"。另外,有一种叫"AMD"的类型,但我不确定它在 2024 年的相关性。</p> <p>现在我们知道了三种文件类型,让我们谈谈如何确定库实际提供了哪些类型!</p> <h3 id="where-to-find-the-files…
Show original
<p>I like writing Javascript <a href="https://jvns.ca/blog/2023/02/16/writing-javascript-without-a-build-system/">without a build system</a> and for the millionth time yesterday I ran into a problem where I needed to figure out how to import a Javascript library in my code without using a build system, and it took FOREVER to figure out how to import it because the library&rsquo;s setup instructions assume that you&rsquo;re using a build system.</p> <p>Luckily at this point I&rsquo;ve mostly learned how to navigate this situation and either successfully use the library or decide it&rsquo;s too difficult and switch to a different library, so here&rsquo;s the guide I wish I had to importing Javascript libraries years ago.</p> <p>I&rsquo;m only going to talk about using Javacript libraries on the frontend, and only about how to use them in a no-build-system setup.</p> <p>In this post I&rsquo;m going to talk about:</p> <ol> <li>the three main types of Javascript files a library might provid…
Read article Original

新推出的TIL微博客

Translated AI Summary eng
[AI 摘要] 作者开设了“今日所学”微博客板块,专门保存不便单独成文的实用工具与知识片段。
View content
<p>几周前,我在网站上新增了一个名为<a href="https://jvns.ca/til/">TIL</a>("今日所学")的板块。</p> <h3 id="the-goal-save-interesting-tools-facts-i-posted-on-social-media">目标:保存我在社交媒体上分享的有趣工具与知识</h3> <p>我喜欢在Mastodon/Bluesky上发布类似"嘿,这个东西很酷"的内容,例如<a href="https://github.com/dbcli/litecli">出色的SQLite交互工具litecli</a>,或是Go语言交叉编译直接就能用这个惊人特性,又或是<a href="https://www.latacora.com/blog/2018/04/03/cryptographic-right-answers/">加密技术的正确答案</a>,以及<a href="https://diffdiff.net/">这款优秀的差异比较工具</a>。通常我不愿为此类内容撰写完整博文,因为我除了"这东西很有用"外确实说不出更多。</p> <p>最近我发现没有地方存放这些内容很困扰——比如前些天想使用<a href="https://diffdiff.net/">diffdiff</a>时,完全想不起它的名字。</p> <h3 id="the-solution-make-a-new-section-of-this-blog">解决方案:为博客新增板块</h3> <p>于是我快速创建了<a href="https://jvns.ca/til/">/til/</a>目录,添加了自定义样式(让文章看起来更像推文),制作了快速创建新文章的Rake任务(<code>rake new_til</code>),并设置了独立的RSS订阅源。</p> <p>这个板块或许更像为自己而建:现在若忘记"加密技术正确答案"的链接,我希望能通过TIL页面查找。(你可能想问"朱莉娅,为何不用书签?"但使用书签这事我半生都未能坚持,也不指望未来会改变——不知为何,公开发布内容对我来说更容易坚持)</p> <p>目前效果不错,通常我能在两分钟内快速发布内容,这正是我的初衷。</p> <h3 id="inspired-by-simon-willison-s-…
Show original
<p>I added a new section to this site a couple weeks ago called <a href="https://jvns.ca/til/">TIL</a> (&ldquo;today I learned&rdquo;).</p> <h3 id="the-goal-save-interesting-tools-facts-i-posted-on-social-media">the goal: save interesting tools &amp; facts I posted on social media</h3> <p>One kind of thing I like to post on Mastodon/Bluesky is &ldquo;hey, here&rsquo;s a cool thing&rdquo;, like <a href="https://github.com/dbcli/litecli">the great SQLite repl litecli</a>, or the fact that cross compiling in Go Just Works and it&rsquo;s amazing, or <a href="https://www.latacora.com/blog/2018/04/03/cryptographic-right-answers/">cryptographic right answers</a>, or <a href="https://diffdiff.net/">this great diff tool</a>. Usually I don&rsquo;t want to write a whole blog post about those things because I really don&rsquo;t have much more to say than &ldquo;hey this is useful!&rdquo;</p> <p>It started to bother me that I didn&rsquo;t have anywhere to put those things: for example recently I wa…
Read article Original

我终端中的ASCII控制字符

Translated AI Summary eng
[AI 摘要] 文章介绍了终端中ASCII控制字符的功能、限制和历史背景。
View content
<p>你好!我最近一直在思考终端,昨天对所有这些“控制码”,比如 <code>Ctrl-A</code>、<code>Ctrl-C</code>、<code>Ctrl-W</code> 等,产生了好奇。它们到底是什么情况?</p> <h3 id="a-table-of-ascii-control-characters">ASCII控制字符表</h3> <p>这里有一个包含所有33个ASCII控制字符的表格,以及它们在我的机器上(运行Mac OS)大致的功能。虽然有很多注意事项,但我会解释它的含义以及我所知道的这个图表的所有问题。</p> <p><a href="https://jvns.ca/ascii.html"><img src="https://jvns.ca/images/ascii-control.png"></a></p> <p>你也可以以<a href="https://jvns.ca/ascii.html">HTML页面形式</a>查看(我把它做成图片只是为了在RSS中显示)。</p> <h3 id="different-kinds-of-codes-are-mixed-together">不同类型的码混杂在一起</h3> <p>关于这个图表,让我感到惊讶的第一件事是,有33个控制码,大致可以分为以下几类:</p> <ol> <li>由操作系统终端驱动程序处理的码,例如当操作系统看到 <code>3</code>(<code>Ctrl-C</code>)时,它会向当前程序发送 <code>SIGINT</code> 信号</li> <li>其他所有码都原样传递给应用程序,应用程序可以随心所欲地处理它们。其中一些子类别: <ul> <li>对应键盘上实际按键的码(<code>Enter</code>、<code>Tab</code>、<code>Backspace</code>)。例如,当你按下 <code>Enter</code> 时,你的终端会接收到 <code>13</code>。</li> <li><code>readline</code> 使用的码:“应用程序可以随心所欲”通常意味着“它会或多或少地执行 <code>readline</code> 库的功能,无论应用程序是否实际使用 <code>readline</code>”,因此我标记了 …
Show original
<p>Hello! I&rsquo;ve been thinking about the terminal a lot and yesterday I got curious about all these &ldquo;control codes&rdquo;, like <code>Ctrl-A</code>, <code>Ctrl-C</code>, <code>Ctrl-W</code>, etc. What&rsquo;s the deal with all of them?</p> <h3 id="a-table-of-ascii-control-characters">a table of ASCII control characters</h3> <p>Here&rsquo;s a table of all 33 ASCII control characters, and what they do on my machine (on Mac OS), more or less. There are about a million caveats, but I&rsquo;ll talk about what it means and all the problems with this diagram that I know about.</p> <p><a href="https://jvns.ca/ascii.html"><img src="https://jvns.ca/images/ascii-control.png"></a></p> <p>You can also view it <a href="https://jvns.ca/ascii.html">as an HTML page</a> (I just made it an image so it would show up in RSS).</p> <h3 id="different-kinds-of-codes-are-mixed-together">different kinds of codes are mixed together</h3> <p>The first surprising thing about this diagram to me is that ther…
Read article Original

在《Mess With DNS》中用更少内存查找IP地址

Translated AI Summary eng
[AI 摘要] 作者通过优化内存中的IP地址数据库,成功将Mess With DNS服务的内存占用减少了70MB。
View content
<p>过去三年左右,我遇到了一个问题:<a href="https://messwithdns.net/">Mess With DNS</a> 定期因内存不足而被OOM终止。</p> <p>这对我而言并非紧急事务:通常它只会宕机几分钟然后重启,且最多每天发生一次,所以我一直未予理会。但上周它开始真正造成问题,因此我决定深入研究。</p> <p>这是一段曲折的探索过程,我学到了很多,以下是目录:</p> <ul> <li><a href="#there-s-about-100mb-of-memory-available">可用内存约100MB</a></li> <li><a href="#the-problem-oom-killing-the-backup-script">问题:OOM终止备份脚本</a></li> <li><a href="#attempt-1-use-sqlite">尝试一:使用SQLite</a> <ul> <li><a href="#problem-how-to-store-ipv6-addresses">问题:如何存储IPv6地址</a></li> <li><a href="#problem-it-s-500x-slower">问题:速度慢了500倍</a></li> <li><a href="#time-for-explain-query-plan">分析EXPLAIN QUERY PLAN的时刻</a></li> </ul> </li> <li><a href="#attempt-2-use-a-trie">尝试二:使用字典树</a> <ul> <li><a href="#some-notes-on-memory-profiling">关于内存分析的几点说明</a></li> </ul> </li> <li><a href="#attempt-3-make-my-array-use-less-memory">尝试三:让我的数组占用更少内存</a> <ul> <li><a href="#idea-3-1-deduplicate-the-name-and-country">想法3.1:去重Name和Country字段</a></li> <li><a href="#how-big-are-asns">ASN有多大?</a></li> <li><…
Show original
<p>I&rsquo;ve been having problems for the last 3 years or so where <a href="https://messwithdns.net/">Mess With DNS</a> periodically runs out of memory and gets OOM killed.</p> <p>This hasn&rsquo;t been a big priority for me: usually it just goes down for a few minutes while it restarts, and it only happens once a day at most, so I&rsquo;ve just been ignoring. But last week it started actually causing a problem so I decided to look into it.</p> <p>This was kind of winding road where I learned a lot so here&rsquo;s a table of contents:</p> <ul> <li><a href="#there-s-about-100mb-of-memory-available">there&rsquo;s about 100MB of memory available</a></li> <li><a href="#the-problem-oom-killing-the-backup-script">the problem: OOM killing the backup script</a></li> <li><a href="#attempt-1-use-sqlite">attempt 1: use SQLite</a> <ul> <li><a href="#problem-how-to-store-ipv6-addresses">problem: how to store IPv6 addresses</a></li> <li><a href="#problem-it-s-500x-slower">problem: it&rsquo;s 500x s…
Read article Original