検索エンジン、いや、検索機能のない辞書とは何ですか?
基本辞書の実装中に、この特定の機能に備えて、これらの静的な検索フォーム (ホームページに 1 つと、単語レイアウトで使用されるナビゲーションバーに 1 つ) を作成しました。


そこからすぐに取り出して、動作させるだけでした。それが本当であれば、簡単な作業です。
過去の何か
最初のコミットで次のことを認めたように、私の当初の計画は Nextra で jargons.dev をビルドすることであったことを繰り返しておくことが重要です。
...Nextra (実際、これは光沢のある鎧を着た私の騎士で、Nextra で構築しようとしていました)。
私は React ⚛️ のファンで、Next.js が大好きです。 Nextra は、Next.js 上に構築されたコンテンツ中心の Web フレームワークです。それで、なぜ Nextra がその騎士のように聞こえたのか理解できると思います。 Nextra を最初に調べたとき、1 つの機能が目に留まりました。全文検索 — これに関してはよだれを垂らしました(告白しなければなりません)。
この機能は、ゼロデプス全文検索ライブラリである flexsearch によって強化されました。ああ、私は軽量で依存関係がないか、依存性が低いの大ファンです。 Nextra がこれを使用して、検索用のビルド時にコンテンツのインデックスを作成する方法を詳しく調べました。面白かったです。
それで!?
Astro と出会った初期の頃、私は flexsearch を使ってハッキングしていたことに気づきました。 astro ドキュメントのブログ構築チュートリアルに従って、さらに一歩進んで、検索機能を非常に簡単に実装しました。
それでは、この実装からの経験; jargons.dev.
の検索エンジンに渡しました。
検索エンジン
タスクは非常に簡単でした。必要な作業は...
- 単語の辞書ディレクトリ内のすべてのファイルへのアクセスを取得するか、参照と呼びます。この時点では、それは src/pages/word ディレクトリでした
- flexsearch でこれらのファイルのコンテンツのインデックスを取得します
- 検索フォームを接続してブームを表示しますか?
とても簡単そうですね!おそらく、検索のインデックス作成と実際の検索の場合はそうでした。しかし、そこに至るまでにはたくさんのことが必要でした。
jargons.dev に最初の「Island」を統合する
Astro はデフォルトでサーバーファーストのアプローチを採用します。つまり、サーバー上でサイトの HTML/CSS を構築し、クライアント側の JavaScript (JS) をすべて自動的に削除します (特に指定しない限り)。すべての JS を削除するとパフォーマンスは確実に向上しますが、JS がないということは対話性がないことを意味します。しかし、インタラクティブ性が必要な場合は、アストロ アイランドがおすすめの方法の 1 つです。検索エンジンにインタラクティブ性が必要なので、アイランドです!
それにしても「島」って何だ!
簡単に言えば、アイランドは Web ページ上の独立したインタラクティブなコンポーネントであり、その HTML/CSS はサーバー側でレンダリングされ、クライアント側の JavaScript も (ハイドレートされて) バンドルされています -削除されませんでした。
TILConf'24 でアイランドについて講演しました。詳しくはこちらをご覧ください。
アストロの提供品
Astro は、Islands を他の多くの私のお気に入りの UI ライブラリ (そう、ご想像のとおり、React) とすぐに統合できるサポートを提供してくれました。これにより、静的な検索フォームを機能的なものに構築できるようになりました。
私がやったこと
- 統合する必要があるアイランドに統合モジュール (@astrojs/react) を追加することから始めました。 npx astro add reverse コマンド
を使用すると非常に簡単に実行できます
- すべての静的検索フォームを単一の React コンポーネントに転送しました (これらは 2 つの異なるサイズのフォームです)。指定された props.
に基づいて必要なサイズでこれらをレンダリングするようにコンポーネントを構成しました。
- 同じ検索コンポーネント内でローカルでのみ使用されるサブコンポーネントも実装しました。これらは...
- SearchDialog - 検索操作が実行されるメインコンポーネント
- SearchResult コンポーネントなど...
- 検索コンポーネント (今後はこれを「検索アイランド」と呼びたいと思います) との対話を可能にする、いくつかのカスタム キーボード ショートカットとキーバインドを実装しました。これらは...
-
CTRL K または ⌘K で検索を開始します
-
ESC で検索を終了
- ...検索結果内を移動するために必要な基本ナビゲーション ボタン
- また、探索島の作業をスムーズに進めるために、いくつかのカスタム フックも追加しました。これらは...
-
useLockBody - 検索ダイアログが開いたらスクロールを無効にするフック
-
useRouter - いくつかの window.location メソッドのラッパーとして作成したフックで、React の既知のルーター ライブラリのように感じられます。これは、検索結果コンポーネントのナビゲーション ボタンのキーバインドの ENTER ボタンのクリック ハンドラーで特に使用したフックです。探索島にて。
- および useIsMacOS - 検索フォーム トリガーでレンダリングする適切な説明テキストを決定するために、マシンが MacOS であるかどうかをチェックします。つまり、CTRL K または ⌘K
- 命令型モジュール - flexsearch; を追加しました。
- Astro.glob() 関数を使用して、単語のディレクトリにあるファイルへのアクセスを非常に簡単に取得しました (この関数がどれほど強力であるかについて話すことができなかったのが残念です。この関数がすぐに Astro に存在して本当に良かったと思います)そして、この検索エンジンを起動して実行するフローがどれほど簡単になったか)、返された単語オブジェクトの配列を、nanostore (もう 1 つの美しい機能がそこにあります) を利用した $dictionary 状態 (これをストアと呼ぶべきかもしれません) に接続しました。
- この $dictionary は flexsearch でインデックス付けされ、後の検索に備えます。
もう 1 つの必須機能: 最近の検索
これは、話さなければならないもう 1 つの必須の機能です。この機能は、検索されたアイテムを追跡し、それらをローカルストレージに保存して、ページのリロード時に永続化します。これらのストアで検索された項目は、辞書のホームページ上のリストに表示されます。

また、アイランドとして統合し、ナノストアを利用した $recentSearches 状態で値を保持することも必要でした。
この機能の実装は完全とは言えません。ここでは、そのルートをさらに進めるために (執筆時点で) 修正が必要ないくつかの問題のリストを示します (完璧には決して到達できませんが、そうです)確かに)
- 最近の検索アイランドに読み込みコンポーネントを追加 - https://github.com/devjargons/jargons.dev/issues/31
- バグ: Navbar の検索フォームで実行される検索操作により LocalStorage が上書きされる - https://github.com/devjargons/jargons.dev/issues/10
- 機能強化: Word Editor - 2 番目のイテレーション機能 - https://github.com/devjargons/jargons.dev/issues/9
PR
これは少し長くなりましたが、短く読みたいと思います...PR は次のとおりです
特技: 辞書検索エンジンを実装する
#5
このプル リクエストは、辞書プロジェクトに検索機能を実装します。 @astro/react 統合を使用して Islands を強化し、状態管理用の nanostore とテキスト検索ライブラリとして flexsearch を組み合わせます。
変更内容
- テキスト検索に必要な次の astrojs 統合とライブラリを追加しました
- @astrojs/react
- @nanostores/react
- フレックスサーチ
- 他のサブコンポーネントが内部使用のために実装されている場所に、検索アイランド (反応コンポーネント) を実装しました。
- 2 つの異なるサイズの検索フィールドをレンダリングし、Web ページ上の 2 つの異なる場所で使用される SearchTrigger コンポーネントを実装しました...
- size md - ウェブアプリのメインページで使用されます
- サイズ sm - 辞書の単語レイアウト ナビゲーション セクションで使用されます
- SearchTrigger がクリックされた場合にのみレンダリングされる SearchDialog コンポーネントを実装しました
- SearchInfo コンポーネントを実装し、フォーム フィールドに検索語が入力されていない場合にデフォルトのプレースホルダーとしてレンダリングします
- SearchResult コンポーネントを実装し、検索結果または検索結果が見つからない場合のメッセージを表示します
- 検索アイランド内にキーバインドを実装し、指定されたキーボード ショートカットで次の操作を可能にしました
-
CTRL K または ⌘K を押すと、検索トリガーをクリックせずに検索ダイアログが開きます
-
ArrowUp、ArrowDown、および Enter で検索結果リストのナビゲーションを可能にします
-
ESC で検索ダイアログを閉じることができます
- 検索アイランドで使用するためのカスタム フックを追加しました
-
useIsMacOS - 現在のユーザーが MacOS マシンで Web アプリを閲覧しているかどうかを確認します。これは、検索トリガーでレンダリングする適切な短編を決定するために使用されます。つまり、CTRL K または ⌘K
-
useLockBody - 検索ダイアログが開いているときに現在のビューポートのスクロールを無効にするために使用されます
-
useRouter - (react-router を deps に追加する代わりに) このフックは window.location をラップし、assign オブジェクトをプッシュとして使用します。主に、選択/クリックされた結果ページにルーティングするために SearchResult コンポーネントで使用されます
- flexsearch の Document メソッドを優先オプションとして使用して、検索アイランドに searchIndexing を実装しました
- nanostores と @nanostores/react 統合を使用して検索関連の状態を管理するための新しい検索ストアを追加しました
- 次のストア値とアクションを追加しました
-
$isSearchOpen - SearchDialog の状態を管理するためのグローバル状態
-
$recentSearches - 最近検索された単語を追跡するための状態。 localStorage と連携して動作し、タブがリロードされた後でも値を保持します
-
$addToRecentSearchesFn - 新しいアイテムを $recentSearches ストア値に追加するストア アクション
- 辞書エントリ全体を管理するための $dictionary ストアを追加しました。クライアントがアクセスできるようにし、検索アイランドの searchIndex の値として使用します。
- 辞書ディレクトリ全体のインデックスを作成する Astro.glob() メソッドを使用して、レイアウト/ベースからできるだけ早く辞書ストアの値を計算します
- $recentSearches ストアから値を読み取り、ホームページに表示する RecentSearches アイランドを追加しました
スクリーンキャスト
完全なデモ
スクリーンキャスト-bpconcjcammlapcogcnnelfmaeghhagj-2024.03.25-13_32_30.webm
?
GitHub で表示