跳轉到主要內容
你將建立一個 Omnibox(網址列)捷徑。在網址列輸入 gh、再輸入查詢字串,就會直接前往 GitHub 搜尋結果。過程中你會串接一份 manifest.json,並在背景 service worker 中處理輸入。同時也會熟悉每個專案都會遵循的開發循環(createdevbuild)。

你會做出什麼

能力你會獲得的成果
Omnibox 關鍵字流程在瀏覽器網址列輸入 gh 觸發擴充功能行為
背景事件處理透過 service worker 處理使用者輸入
本地開發循環快速執行、載入並驗證擴充功能行為
漸進式強化在基本流程運作後加入即時的 GitHub 搜尋建議

計畫

讓 GitHub 搜尋速度像瀏覽器原生捷徑一樣快。擴充功能會保留關鍵字 gh;當你輸入 gh 加上查詢字串後,會打開 GitHub 的搜尋結果。

步驟 1:建立擴充功能

使用 Extension.js 的 create 指令來建立一個名為 github-search 的最小擴充功能。
npx extension@latest create github-search

步驟 2:建立 manifest 檔案

每個擴充功能都從 manifest 檔案開始。它定義中繼資料、權限與執行階段檔案。根據上述計畫,設定 gh 捷徑並加入處理使用者事件的 service worker。
{
  "manifest_version": 3,
  "name": "GitHub Search",
  "version": "1.0",
  "omnibox": { "keyword": "gh" },
  "background": {
    "service_worker": "service_worker.js"
  }
}
  • omnibox.keyword:當你輸入 gh 時,瀏覽器會觸發事件。
  • background.service_worker:監聽你觸發的事件。

步驟 3:建立背景 service worker

在瀏覽器擴充功能中,背景 service worker(一個獨立於任何可見頁面執行的腳本)負責處理瀏覽器事件。 在這個範例中,加入一段腳本來監聽 Omnibox 輸入,並把查詢字串導向 GitHub 搜尋。 建立 service_worker.js
// When the user has accepted what is typed into the omnibox.
chrome.omnibox.onInputEntered.addListener((text) => {
  // Convert any special character (spaces, &, ?, etc)
  // into a valid character for the URL format.
  const encodedSearchText = encodeURIComponent(text);
  const url = `https://github.com/search?q=${encodedSearchText}&type=issues`;

  chrome.tabs.create({ url });
});
上面這段腳本會在你於網址列輸入「gh」之後再輸入任何內容時,開啟一個顯示 GitHub 搜尋結果的新分頁。

步驟 4:載入你的擴充功能

你的 package.json 檔案現在看起來像這樣:
{
  "scripts": {
    "dev": "extension dev",
    "start": "extension start",
    "build": "extension build"
  },
  "devDependencies": {
    "extension": "latest"
  }
}
這些 script 是 Extension.js 預設的指令。第一次執行擴充功能:
npm run dev
如果設定正確,Extension.js 會啟動使用全新設定檔的 Chrome、以未封裝擴充功能的方式載入 github-search,並在終端機印出就緒訊息。Chrome 的網址列現在已認得 gh 為關鍵字。 輸入 gh 接著按一下空白鍵,輸入 extension.js,按下 Enter。會開啟新分頁前往 https://github.com/search?q=extension.js&type=issues
你現在有一個可以搜尋 GitHub 的可運作擴充功能了。

步驟 5:讓它變得更好

透過 Omnibox 輸入監聽器,在網址列直接顯示建議,藉此改善搜尋體驗。 更新 service_worker.js,在輸入時抓取 GitHub 建議並顯示出來。
service_worker.js
// Create a debounce function to avoid excessive
// calls to the GitHub API while the user is still
// typing the search query.
function debounce(fn, delay) {
  let timeoutID;
  return function (...args) {
    if (timeoutID) clearTimeout(timeoutID);
    timeoutID = setTimeout(() => fn(...args), delay);
  };
}

// When the user has changed what is typed into the omnibox.
chrome.omnibox.onInputChanged.addListener(
  debounce(async (text, suggest) => {
    const response = await fetch(
      `https://api.github.com/search/issues?q=${text}`,
    );
    const data = await response.json();
    const suggestions = data.items.map((issue) => ({
      content: issue.html_url,
      description: issue.title,
    }));

    suggest(suggestions);
  }, 250),
);

// When the user has accepted what is typed into the omnibox.
chrome.omnibox.onInputEntered.addListener((text) => {
  // Convert any special character (spaces, &, ?, etc)
  // into a valid character for the URL format.
  const encodedSearchText = encodeURIComponent(text);
  const url = `https://github.com/search?q=${encodedSearchText}&type=issues`;

  chrome.tabs.create({ url });
});
這段程式碼會在網址列直接加入即時的 GitHub 建議。 你現在有一個可運作的 GitHub 搜尋擴充功能。繼續迭代,調整成符合自己工作流程的版本。

後續步驟