2022-11-24

  • ex_doc の検索機能の調査

ex_doc の検索機能を調べたら、 tinysearch にこだわらずに JavaScript で組むのもありかも知れないと思ってきた。 Rust はできないけど JS なら読めるしお手本コードもある。できる(?

けど、それだと Alpine 採用した方針と合わない気がするな。

Alpine.js と Fuse.js を組み合わせてどこまでできるか試してみることにする。

Lunr.js は日本語検索に対応させることができるようだけど、 Fuse.js は検索にかからないのでできないのかも。。

Alpine.js と Lunr.js ってうまく組み合わせられるだろうか?

2022-11-25 追記:Fuse.js で日本語文字列の検索もできた。なんで試した時はできなかったのか不明。

ex_doc の検索機能

search-page.js で実装されている。

"/search.html" に query parameter q をつけてアクセスすると search が動作する。

refs. https://github.com/elixir-lang/ex_doc/blob/v0.29.1/assets/js/search-page.js#L17-L39

入力フォームに入力すると動的に候補を表示する。

refs. https://github.com/elixir-lang/ex_doc/blob/v0.29.1/assets/js/sidebar/sidebar-search.js#L58-L60

検索機能には Lunr.js を使っている。

refs. https://github.com/elixir-lang/ex_doc/blob/v0.29.1/assets/js/search-page.js#L3

Lunr.js きっかけで Fuse.js というのがあることを知った。

Fuse.js

https://fusejs.io/ の As easy as 1,2,3 に従って試してみた。

<!DOCTYPE html>
<html>
  <head>
    <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/fuse.js/dist/fuse.js"></script>
  </head>
  <body>
    <div x-init="fuse = new Fuse(items, {keys: ['title']})",
         x-data="{
                   fuse: null,
                   search: '',
                   items: [ {title: 'apple'}, {title: 'banana'}, {title: 'guava'}, {title: 'ape'}, {title: 'bands'} ],
                   get searchResults () { return this.fuse.search(this.search) }
                 }">
      <input type="search" placeholder="Enter Keyword here" x-model="search">
      <ul>
        <template x-for="result in searchResults">
        <li x-text="result.item.title"></li>
        </template>
      </ul>
    </div>
  </body>
</html>

today i read