mirror of
https://github.com/jbranchaud/til
synced 2026-01-20 15:38:02 +00:00
Compare commits
1 Commits
016c1f84f2
...
ea5fa3076e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea5fa3076e |
12
README.md
12
README.md
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||||
|
|
||||||
_1466 TILs and counting..._
|
_1460 TILs and counting..._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -19,7 +19,6 @@ _1466 TILs and counting..._
|
|||||||
* [Ack](#ack)
|
* [Ack](#ack)
|
||||||
* [Amplify](#amplify)
|
* [Amplify](#amplify)
|
||||||
* [Ansible](#ansible)
|
* [Ansible](#ansible)
|
||||||
* [Astro](#astro)
|
|
||||||
* [Brew](#brew)
|
* [Brew](#brew)
|
||||||
* [Chrome](#chrome)
|
* [Chrome](#chrome)
|
||||||
* [Clojure](#clojure)
|
* [Clojure](#clojure)
|
||||||
@@ -99,11 +98,6 @@ _1466 TILs and counting..._
|
|||||||
|
|
||||||
- [Loop Over A List Of Dictionaries](ansible/loop-over-a-list-of-dictionaries.md)
|
- [Loop Over A List Of Dictionaries](ansible/loop-over-a-list-of-dictionaries.md)
|
||||||
|
|
||||||
### Astro
|
|
||||||
|
|
||||||
- [Generate Types For A Content Collection](astro/generate-types-for-a-content-collection.md)
|
|
||||||
- [Markdown Files Are Of Type MarkdownInstance](astro/markdown-files-are-of-type-markdown-instance.md)
|
|
||||||
|
|
||||||
### Brew
|
### Brew
|
||||||
|
|
||||||
- [Configure Brew Environment Variables](brew/configure-brew-environment-variables.md)
|
- [Configure Brew Environment Variables](brew/configure-brew-environment-variables.md)
|
||||||
@@ -455,7 +449,6 @@ _1466 TILs and counting..._
|
|||||||
- [Check If A Number Is Positive Or Negative](javascript/check-if-a-number-is-positive-or-negative.md)
|
- [Check If A Number Is Positive Or Negative](javascript/check-if-a-number-is-positive-or-negative.md)
|
||||||
- [Check If File Exists Before Reading It](javascript/check-if-file-exists-before-reading-it.md)
|
- [Check If File Exists Before Reading It](javascript/check-if-file-exists-before-reading-it.md)
|
||||||
- [Check If Something Is An Array](javascript/check-if-something-is-an-array.md)
|
- [Check If Something Is An Array](javascript/check-if-something-is-an-array.md)
|
||||||
- [Check Media Queries From JavaScript](javascript/check-media-queries-from-javascript.md)
|
|
||||||
- [Check The Password Confirmation With Yup](javascript/check-the-password-confirmation-with-yup.md)
|
- [Check The Password Confirmation With Yup](javascript/check-the-password-confirmation-with-yup.md)
|
||||||
- [Compare The Equality Of Two Date Objects](javascript/compare-the-equality-of-two-date-objects.md)
|
- [Compare The Equality Of Two Date Objects](javascript/compare-the-equality-of-two-date-objects.md)
|
||||||
- [Computed Property Names In ES6](javascript/computed-property-names-in-es6.md)
|
- [Computed Property Names In ES6](javascript/computed-property-names-in-es6.md)
|
||||||
@@ -997,7 +990,6 @@ _1466 TILs and counting..._
|
|||||||
- [Skip Validations When Creating A Record](rails/skip-validations-when-creating-a-record.md)
|
- [Skip Validations When Creating A Record](rails/skip-validations-when-creating-a-record.md)
|
||||||
- [Specify New Attributes For #find_or_create_by](rails/specify-new-attributes-for-find-or-create-by.md)
|
- [Specify New Attributes For #find_or_create_by](rails/specify-new-attributes-for-find-or-create-by.md)
|
||||||
- [Temporarily Disable strong_params](rails/temporarily-disable-strong-params.md)
|
- [Temporarily Disable strong_params](rails/temporarily-disable-strong-params.md)
|
||||||
- [Temporarily Turn Off Pending Migrations Error](rails/temporarily-turn-off-pending-migrations-error.md)
|
|
||||||
- [Test For A Subset Of Attributes On A Model](rails/test-for-a-subset-of-attributes-on-a-model.md)
|
- [Test For A Subset Of Attributes On A Model](rails/test-for-a-subset-of-attributes-on-a-model.md)
|
||||||
- [Test If An Instance Variable Was Assigned](rails/test-if-an-instance-variable-was-assigned.md)
|
- [Test If An Instance Variable Was Assigned](rails/test-if-an-instance-variable-was-assigned.md)
|
||||||
- [Test If deliver_later Is Called For A Mailer](rails/test-if-deliver-later-is-called-for-a-mailer.md)
|
- [Test If deliver_later Is Called For A Mailer](rails/test-if-deliver-later-is-called-for-a-mailer.md)
|
||||||
@@ -1454,7 +1446,6 @@ _1466 TILs and counting..._
|
|||||||
- [List The Stack Of Remembered Directories](unix/list-the-stack-of-remembered-directories.md)
|
- [List The Stack Of Remembered Directories](unix/list-the-stack-of-remembered-directories.md)
|
||||||
- [Load Env Vars In Bash Script](unix/load-env-vars-in-bash-script.md)
|
- [Load Env Vars In Bash Script](unix/load-env-vars-in-bash-script.md)
|
||||||
- [Look Through All Files That Have Been Git Stashed](unix/look-through-all-files-that-have-been-git-stashed.md)
|
- [Look Through All Files That Have Been Git Stashed](unix/look-through-all-files-that-have-been-git-stashed.md)
|
||||||
- [Make Direnv Less Noisy](unix/make-direnv-less-noisy.md)
|
|
||||||
- [Map A Domain To localhost](unix/map-a-domain-to-localhost.md)
|
- [Map A Domain To localhost](unix/map-a-domain-to-localhost.md)
|
||||||
- [Negative Look-Ahead Search With ripgrep](unix/negative-look-ahead-search-with-ripgrep.md)
|
- [Negative Look-Ahead Search With ripgrep](unix/negative-look-ahead-search-with-ripgrep.md)
|
||||||
- [Occupy A Local Port With Netcat](unix/occupy-a-local-port-with-netcat.md)
|
- [Occupy A Local Port With Netcat](unix/occupy-a-local-port-with-netcat.md)
|
||||||
@@ -1679,7 +1670,6 @@ _1466 TILs and counting..._
|
|||||||
- [Advance Through Search Results](vscode/advance-through-search-results.md)
|
- [Advance Through Search Results](vscode/advance-through-search-results.md)
|
||||||
- [Enable Breadcrumbs For Version 1.26 Release](vscode/enable-breadcrumbs-for-version-126-release.md)
|
- [Enable Breadcrumbs For Version 1.26 Release](vscode/enable-breadcrumbs-for-version-126-release.md)
|
||||||
- [Find The Location Of User Settings JSON File](vscode/find-the-location-of-user-settings-json-file.md)
|
- [Find The Location Of User Settings JSON File](vscode/find-the-location-of-user-settings-json-file.md)
|
||||||
- [Jump To Problems In The Current File](vscode/jump-to-problems-in-the-current-file.md)
|
|
||||||
- [Open An Integrated Terminal Window](vscode/open-an-integrated-terminal-window.md)
|
- [Open An Integrated Terminal Window](vscode/open-an-integrated-terminal-window.md)
|
||||||
- [Pop Open The Quick Fix Window](vscode/pop-open-the-quick-fix-window.md)
|
- [Pop Open The Quick Fix Window](vscode/pop-open-the-quick-fix-window.md)
|
||||||
- [Step Through Project-Wide Search Results](vscode/step-through-project-wide-search-results.md)
|
- [Step Through Project-Wide Search Results](vscode/step-through-project-wide-search-results.md)
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
# Generate Types For A Content Collection
|
|
||||||
|
|
||||||
Let's say I'm using Astro to publish posts via markdown. One of the best ways
|
|
||||||
to do that is as a _Content Collection_. The posts will live in `src/content`
|
|
||||||
probably under a `posts` directory. Plus a config file will define the
|
|
||||||
collection and specify validations for the frontmatter.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
// src/content/config.ts
|
|
||||||
import { defineCollection, z } from 'astro:content';
|
|
||||||
|
|
||||||
const postsCollection = defineCollection({
|
|
||||||
schema: z.object({
|
|
||||||
title: z.string(),
|
|
||||||
description: z.string(),
|
|
||||||
tags: z.array(z.string())
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
export const collections = {
|
|
||||||
'posts': postsCollection,
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
When I first add this to my project and get the collection, it won't know what
|
|
||||||
the types are.
|
|
||||||
|
|
||||||
```astro
|
|
||||||
---
|
|
||||||
import { getCollection } from "astro:content";
|
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
|
||||||
const blogEntries = await getCollection("posts");
|
|
||||||
// ^^^ any
|
|
||||||
|
|
||||||
return blogEntries.map((entry) => ({
|
|
||||||
params: { slug: entry.slug },
|
|
||||||
props: { entry },
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
---
|
|
||||||
```
|
|
||||||
|
|
||||||
I can tell Astro to generate a fresh set of types for things like content
|
|
||||||
collections by running the [`astro sync`
|
|
||||||
command](https://docs.astro.build/en/reference/cli-reference/#astro-sync).
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ npm run astro sync
|
|
||||||
```
|
|
||||||
|
|
||||||
This updates auto-generated files under the `.astro` directory which get pulled
|
|
||||||
in to your project's `env.d.ts` file.
|
|
||||||
|
|
||||||
All of these types will also be synced anytime I run `astro dev`, `astro
|
|
||||||
build`, or `astro check`.
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# Markdown Files Are Of Type MarkdownInstance
|
|
||||||
|
|
||||||
One of the things Astro excels at is rendering markdown files as HTML pages in
|
|
||||||
your site. And at some point we'll want to access a listing of those markdown
|
|
||||||
files in order to do something like display a list of them on an index page.
|
|
||||||
For that, we'll use
|
|
||||||
[`Astro.glob()`](https://docs.astro.build/en/reference/api-reference/#astroglob).
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
---
|
|
||||||
const allPosts = await Astro.glob("../posts/*.md");
|
|
||||||
---
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
{allPosts.map(post => {
|
|
||||||
return <Post title={post.frontmatter.title} slug={post.frontmatter.slug} />
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
```
|
|
||||||
|
|
||||||
This looks great, but we'll run into a type error on that first line:
|
|
||||||
`'allPosts' implicitly has type 'any'`. We need to declare the type
|
|
||||||
of these post instances that are being read-in by Astro.
|
|
||||||
|
|
||||||
These are of [type
|
|
||||||
`MarkdownInstance`](https://docs.astro.build/en/reference/api-reference/#markdown-files).
|
|
||||||
That's a generic though, so we need to tell it a bit more about the shape of a
|
|
||||||
post.
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
import type { MarkdownInstance } from "astro";
|
|
||||||
|
|
||||||
export type BarePost = {
|
|
||||||
layout: string;
|
|
||||||
title: string;
|
|
||||||
slug: string;
|
|
||||||
tags: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Post = MarkdownInstance<BarePost>;
|
|
||||||
```
|
|
||||||
|
|
||||||
We can then update that first line:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const allPosts: Post[] = await Astro.glob("../posts/*.md");
|
|
||||||
```
|
|
||||||
|
|
||||||
Alternatively, you can specify the generic on `glob`:
|
|
||||||
|
|
||||||
```typescript
|
|
||||||
const allPosts = await Astro.glob<BarePost>("../posts/*.md");
|
|
||||||
```
|
|
||||||
@@ -15,10 +15,4 @@ $ godoc -http=:6060
|
|||||||
|
|
||||||
and then visit `localhost:6060`.
|
and then visit `localhost:6060`.
|
||||||
|
|
||||||
Note: if you do not already have `godoc` installed, you can install it with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ go install golang.org/x/tools/cmd/godoc@latest
|
|
||||||
```
|
|
||||||
|
|
||||||
[source](http://www.andybritcliffe.com/post/44610795381/offline-go-lang-documentation)
|
[source](http://www.andybritcliffe.com/post/44610795381/offline-go-lang-documentation)
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
# Check Media Queries From JavaScript
|
|
||||||
|
|
||||||
I'm usually thinking about and [using media
|
|
||||||
queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries)
|
|
||||||
from a CSS context. I use them to control what styles are displayed for a
|
|
||||||
variety of scenarios, such as at different screen widths, when a user prefers
|
|
||||||
reduced motion, or when the user prefers a dark color scheme.
|
|
||||||
|
|
||||||
The current value of various media queries can be checked from a JavaScript
|
|
||||||
context as well.
|
|
||||||
|
|
||||||
For instance, if we want to see if the user prefers a _dark_ color schema, we
|
|
||||||
can look for a _match_ on that media query with
|
|
||||||
[`matchMedia`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia).
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
> window.matchMedia('(prefers-color-scheme: dark)')
|
|
||||||
MediaQueryList {media: '(prefers-color-scheme: dark)', matches: true, onchange: null}
|
|
||||||
> window.matchMedia('(prefers-color-scheme: dark)')['matches']
|
|
||||||
true
|
|
||||||
```
|
|
||||||
|
|
||||||
This queries for the [`prefers-color-scheme` media
|
|
||||||
feature](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
|
|
||||||
|
|
||||||
The [Astro.build Blog
|
|
||||||
Tutorial](https://docs.astro.build/en/tutorial/6-islands/2/#add-client-side-interactivity)
|
|
||||||
shows an example of using this to wire up a Light/Dark mode toggle.
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Temporarily Turn Off Pending Migrations Error
|
|
||||||
|
|
||||||
Whenever I'm working on an end-to-end feature in a Rails app, soon or later I
|
|
||||||
am going to see the _Pending Migrations_ error page. I try to visit one of the
|
|
||||||
routes in the browser and the Rails app serves this error page instead of my
|
|
||||||
actual request response.
|
|
||||||
|
|
||||||
This is typically what I want. If there are migrations just sitting there that
|
|
||||||
haven't been run yet, that's probably an issue. Maybe I just pulled down the
|
|
||||||
latest changes from my teammates. The app isn't going to work properly without
|
|
||||||
whatever schema changes are prescribed in those pending migrations.
|
|
||||||
|
|
||||||
The thing to do is run those migrations.
|
|
||||||
|
|
||||||
In some special cases though, I know what I'm doing and I would like to operate
|
|
||||||
my app locally with specific migrations not yet applied.
|
|
||||||
|
|
||||||
To skip the error, I can change this `config/environments/development.rb`
|
|
||||||
setting from:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
config.active_record.migration_error = :page_load
|
|
||||||
```
|
|
||||||
|
|
||||||
to:
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
config.active_record.migration_error = false
|
|
||||||
```
|
|
||||||
|
|
||||||
I just need to make sure to switch it back when I'm done.
|
|
||||||
|
|
||||||
[source](https://til.hashrocket.com/posts/ujcixh5rwi-rails-ignore-pending-migrations)
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
# Make Direnv Less Noisy
|
|
||||||
|
|
||||||
I've been using [`direnv`](https://direnv.net/) to manage project and folder
|
|
||||||
specific environment variables for a bit now. I've found it to be pretty
|
|
||||||
seamless. It can feel like it is littering my shell with too much output when I
|
|
||||||
change directories though.
|
|
||||||
|
|
||||||
There are two levers to control its output.
|
|
||||||
|
|
||||||
First, the direnv logs (e.g. `direnv: loading ~/.../.envrc`) can be controlled
|
|
||||||
with the `DIRENV_LOG_FORMAT` env var. Add this to the
|
|
||||||
`~/.config/direnv/direnvrc` file (add that directory and file if necessary).
|
|
||||||
You can leave it blank to altogether hide log messages or you can gray-out the
|
|
||||||
log messages like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
export DIRENV_LOG_FORMAT=$'\033[2mdirenv: %s\033[0m'
|
|
||||||
```
|
|
||||||
|
|
||||||
Second, you can hide the env var diff with a separate config. This diff is not
|
|
||||||
covered under the umbrella of logs controlled by the above setting. Set
|
|
||||||
[`hide_env_diff` in the `~/.config/direnv/direnv.toml`
|
|
||||||
file](https://direnv.net/man/direnv.toml.1.html#codehideenvdiffcode):
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[global]
|
|
||||||
hide_env_diff = true
|
|
||||||
```
|
|
||||||
|
|
||||||
This second config was only added as of `v2.34.0`.
|
|
||||||
|
|
||||||
[source](https://esham.io/2023/10/direnv)
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# Jump To Problems In The Current File
|
|
||||||
|
|
||||||
VSCode has a system for different extensions to report problems. The editor
|
|
||||||
will visually flag those problems in the editor with a red squiggly underline.
|
|
||||||
It will also list them in the _Problems_ tab of the bottom tray (hit `Cmd+j` to
|
|
||||||
pop that tray open).
|
|
||||||
|
|
||||||
If there are some active problems in your current file, you can jump right to
|
|
||||||
them.
|
|
||||||
|
|
||||||
Hit `F8` and you'll jump to the next problem after wherever the cursor is. Hit
|
|
||||||
`F8` again and it will go to the next one.
|
|
||||||
|
|
||||||
Want to track back through the file? Hit `Shift+F8` and you'll jump to the
|
|
||||||
closest problem _behind_ the current cursor position.
|
|
||||||
|
|
||||||
Using these two, you can quickly survey the current problems in your file
|
|
||||||
before deciding how to proceed.
|
|
||||||
Reference in New Issue
Block a user