0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Chrome MV3拡張で Kuromojin を安定利用したい

Last updated at Posted at 2025-09-17

Chrome MV3拡張で Kuromojin を安定利用したい

Chrome 拡張(MV3)で日本語形態素解析を行う場合、Kuromoji / Kuromojin が便利です。しかし、MV3 の Service Worker から辞書を fetch すると、次のエラーがよく発生しました。

background.js:1 Kuromoji Error: TypeError: Failed to fetch

ここでは、MV3 の制約や fetch の仕組み を含めて、安定して Kuromojin を使う方法を詳しく解説します。
結構苦労したのでここに残します


1️⃣ fetch とは?

基本

fetch は JavaScript の組み込み API で、HTTP/HTTPS リクエストを送るために使います。

fetch("https://example.com/data.json")
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

非同期で動作する

Promise を返す

ブラウザ側でネットワーク接続を管理

fetch のよくある失敗原因

ネットワーク接続の問題

URL が間違っている(スペル、プロトコルなど)

CORS 制約でアクセスが拒否される

MV3 の Service Worker 内で制約に引っかかる

MV3 の Service Worker では、fetch が## 拡張内リソースや外部ファイルに対して失敗する## ことがあります。何度も失敗してとても大変でした。


2️⃣ MV3(Manifest V3)の特徴と fetch との関係

従来の MV2 との違い

項目 MV2 MV3

Background Script 常駐型 Service Worker 型(必要なときだけ起動)
fetch 制約 少なめ Service Worker 内では制限あり
セキュリティ 緩め CSP が強化、権限が限定
リソース使用 常駐 必要な時だけ起動 → 軽量化

Service Worker の制約

fetch がブラウザの通常コンテキストと異なる環境で動作

拡張内部リソース(辞書ファイル)を fetch すると Failed to fetch が発生しやすい

外部ネットワークでは CORS や CSP に引っかかる可能性もある

結論: Service Worker から辞書ファイルを fetch するのは不安定


3️⃣ Failed to fetch が起きる理由(MV3 + fetch)

fetch はリクエストを送信してレスポンスを待つが、Service Worker 内では一部制限がある

拡張内リソース(dict/*.json など)を Service Worker から直接読み込もうとすると失敗

ネットワークの問題ではなく、MV3 の設計による制約


4️⃣ 解決策:Content Script で fetch を実行

基本の仕組み

[Content Script] → fetch + Kuromojin 初期化 + 形態素解析 + ローマ字変換


[Background Script (Service Worker)] ← 解析結果のみ受信

メリット

Content Script は ウェブページのコンテキストで動く → fetch 制限なし

拡張内リソースの fetch が安定

Service Worker は軽量で安定


5️⃣ プロジェクト構成例

my-extension/
├─ manifest.json
├─ background.js ← Service Worker
├─ content.js ← Content Script
├─ dict/ ← Kuromojin 辞書
└─ package.json


6️⃣ manifest.json 設定例

{
  "manifest_version": 3,
  "name": "Kuromojin MV3 Example",
  "version": "1.0",
  "background": { "service_worker": "background.js" },
  "content_scripts": [
    { "matches": ["<all_urls>"], "js": ["content.js"] }
  ],
  "web_accessible_resources": [
    { "resources": ["dict/*"], "matches": ["<all_urls>"] }
  ],
  "permissions": ["scripting", "activeTab"]
}

web_accessible_resources に辞書ファイルを登録 → Content Script で fetch 可能

Content Script 内で fetch すると Service Worker の制約を回避可能できる


7️⃣ Content Script 実装例(fetch + Kuromojin)

import kuromojin from "kuromojin";

async function analyzePage() {
  const text = document.body.innerText;

  try {
    // Kuromojin 初期化(内部で fetch が走る)
    const tokens = await kuromojin.tokenize(text);

    const romaji = tokens.map(t => convertToRomaji(t.surface_form));

    // Background に送信
    chrome.runtime.sendMessage({
      type: "ANALYZED_TEXT",
      data: romaji.join(" ")
    });
  } catch (e) {
    console.error("fetch または Kuromojin 初期化エラー:", e);
  }
}

function convertToRomaji(japanese: string): string {
  // wanakana を使うと精度向上
  return japanese;
}

analyzePage();

Content Script はページコンテキストで動くため fetch が安定

Kuromojin の内部 fetch も問題なし
これに少し苦戦した…


8️⃣ Background Script 実装例

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.type === "ANALYZED_TEXT") {
    console.log("ローマ字変換済みテキスト:", msg.data);
  }
});

Service Worker は解析をせず、軽量で安定!

fetch によるエラーはほぼ発生しない(はず…)


9️⃣ 注意点!

  1. 辞書ファイルは web_accessible_resources に登録

  2. Content Script で fetch + Kuromojin 初期化

  3. 非同期処理で大規模ページも安定

4. ローマ字変換は wanakana などで精度向上!

  1. Service Worker は解析や fetch を避け、軽量化

10️⃣ まとめ

MV3 の Service Worker は fetch が不安定

Content Script に fetch + Kuromojin 初期化を移すことで安定化

Background Script は解析済み結果のみ受け取る

manifest.json の設定と辞書ファイル配置が重要

私は今とある拡張機能を作っているのですがここまでこれに苦戦するとは思いませんでした。これの他にも実は結構エラーも出ているので一旦全体の設計を見直そうかとも考えています。typescriptをもっと勉強しなくては……


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?