初心者がVue3を用いて検索結果の一部を非表示にする拡張機能を作成した話

どうも、なまけろです。
プログラミング初心者なので内容に間違いがある可能性が非常に高いので参考にする際には気をつけてください。
あと、記事を投稿するのは初めてですが、
この記事を見に来た人の全員は自分が作成した拡張機能の作り方を見に来た人だと思うので、ちゃんとした自己紹介は最後にしたいと思います。

# 環境

自分はVSCodeとWSL2を用いて拡張機能を作成しています。
あとOSはwindows11なのでそれ以外の方は参考にならないかもです。
この記事を読む方はほとんどの方が環境構築を終わらせていると思うので環境構築の方法は省きます。

# まず一言

先に言いますが、拡張機能をVueで作ったのではなく、
`拡張機能の一部をVue3を用いて作成した`だけです。
具体的には、画像右上のようなUIをVue3を用いて作成しただけです。
機能はTypeScriptを用いて作成しました。(大したコードじゃないから実質JavaScript)
![スクリーンショット 2023-09-25 175302.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557990/1b94a9bf-a7f9-53c1-c872-47a5fb6ca02b.png)

(UIがめちゃ手抜きなのは許して(^q^)

# 拡張機能でVue3を使用するのは比較的簡単(ソース：俺)

まず拡張機能を作成するに当たって最低限必要なものは、<br>以下の３つを持つディレクトリです。

1. manifest.json
1. ファイル名.html
1. ファイル名.js

この３つ、てかmanifest.jsonとhtmlさえあれば機能がなくても良いのであれば作成できます。

では、ここからVue3を用いて作成する方法を説明していこうと思ったのですが、[参考にしたサイト](https://www.memory-lovers.blog/entry/2023/01/14/150000)の丸パクリみたいな感じになったのでやっぱり説明するのをやめます。このサイト見れば作り方わかると思います。

# 機能について

自分はタイトルにも書いてある通りChromeの検索結果の一部を非表示にする拡張機能を作成しました。主に書いたファイルは

- App.vue
- content.ts

の２つです。App.vueはこんな感じです(ちゃんと作成したわけじゃないので、本職の方見たら発狂するコードだと思う)

~~~vue
<script setup lang="ts">
import { ref } from "vue";


interface Urls {
  id: number,
  url: string,
};
const urls = ref<Urls[]>([]);
let idNumber: number = 0;
let inputUrl: string = "";

const loadUrls = (): void => {
  chrome.storage.local.get(["url"], (result) => {
    if (result.url) {
      let urlArray = result.url.split(" ");
      for (let i = 0; i < urlArray.length; i++) {
        if (urlArray[i] !== "") {
          urls.value.push({
            id: ++idNumber,
            url: urlArray[i],
          });
        }
      }
    }
  });
}

loadUrls();

const addUrl = (url: string): void => {
  urls.value.push({
    id: ++idNumber,
    url: url,
  });
  inputUrl = "";
};

const sendUrls = (): void => {
  let arrayUrls = urls.value.map(url => url.url).join(" ");
  chrome.storage.local.set({ url: arrayUrls });
};

const removeUrl = (listId: number): void => {
  let arrayNumber: number = urls.value.findIndex((url) => url.id === listId);
  urls.value.splice(arrayNumber, 1);
};
</script>

<template>
  <div>
    <div>Input here some urls you consider unnecessary</div>
    <div>
      <input v-model="inputUrl">
      <button @click="addUrl(inputUrl)">add</button>
    </div>
    <div>
      <button @click="sendUrls()">setUrls</button>
    </div>
    <div v-for="{ url, id } in urls" :key="id" id="listDiv">
      <li>{{ url }}</li>
      <button @click="removeUrl(id)">remove</button>
    </div>
  </div>
</template>

<style scoped>
#listDiv {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

~~~

content.tsはこんな感じ

~~~ts
window.onload = async function () {
  chrome.storage.local.get(["url"], (result) => {
    if (result.url) {
      let removeUrl: [] = result.url.split(" ");
      let allSite = document.querySelectorAll('.g');
      allSite.forEach((site) => {
        let linkElement = site.querySelector("a");
        if (linkElement) {
          let url = linkElement.href;
          for (let i = 0; i < removeUrl.length; i++) {
            if (url.startsWith(removeUrl[i])) {
              (site as HTMLElement).style.display = "none";
            }
          }
        }
      });
    }
  });
};

~~~

拡張機能を作成するに当たって苦労したことが

1. vueファイルからcontent.tsにどうやってデータを送るか
1. どこをDOMで操作すれば特定のサイトを非表示にできるか

の2つです。
１つ目に関してはruntime.onMessageやruntime.sendMessageでデータを送ろうとしていたのですが、非同期関数を扱うのが下手でめちゃ手こずっていました。ただ、[拡張機能のchrome.storageAPI](https://developer.chrome.com/docs/extensions/reference/)を使うことによって簡単に作れることに気がつきました。

２つ目は[このサイト](https://qiita.com/yume_yu/items/a1e8c2646fc6820b2f04)のお陰でわかりました。あやうく一生デベロッパーツールとにらめっこするところだった。

初めてまともな(?)制作物が作れた(^q^)

# 余談

コードを書いている最中、chromeのnamespaceが存在しない的なエラーが出ました。調べてみたらVSCodeにVueの拡張機能を２ついれていたのですが、その片方が原因でした。同じエラーが出ている人は[このサイト](https://github.com/vuejs/vetur/issues/3476)が参考になると思います。

あと、この拡張機能を作成していて参考になったサイトを一部以下に書いておきます。

https://crxjs.dev/vite-plugin/

https://ja.vuejs.org/guide/introduction.html

https://reffect.co.jp/vue/vue3-composition/

https://developer.chrome.com/docs/extensions/mv3/getstarted/

https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules_typedoc_node_modules_typescript_lib_lib_dom_d_.htmlelement.html

# あらためて自己紹介

2023-04に大学生になって初めてコマンドラインというものを知って触ったプログラミング初心者です。それまではHTMLをプログラミング言語だと思い、hタグとpタグしか使ったことがないぐらいプログラミングとは無縁の生活を送っていました。あらためて自己紹介とか書いたけど、特に紹介するようなとこはない薄っぺらい人間なので書くの終わります。わざわざこの記事を見ていただき、ありがとうございます。