Frontend

Make Chrome Extension - manifest.json

rachel_13 2025. 4. 7. 20:06

๐Ÿง  ํฌ๋กฌ ์ต์Šคํ…์…˜ ๊ตฌ์กฐ ๊ฐœ๋… ์ •๋ฆฌ

ํฌ๋กฌ ์ต์Šคํ…์…˜์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์›น ๊ธฐ์ˆ ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ž‘์€ ์•ฑ์ด๋‹ค.

๊ธฐ๋ณธ์ ์ธ ๊ตฌ์„ฑ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

- mainfest.json : ์ต์Šคํ…์…˜ ์„ค์ • ํŒŒ์ผ (ํ•„์ˆ˜) (์ด ํŒŒ์ผ์ด ์žˆ์–ด์•ผ ํฌ๋กฌ ์ต์Šคํ…์…˜์œผ๋กœ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋‹ค.)

- popup : ํฌ๋กฌ ํˆด๋ฐ”์—์„œ ์•„์ด์ฝ˜์„ ํด๋ฆญํ•˜๋ฉด ๋‚˜์˜ค๋Š” UI

- background script : ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ณ„์† ๋™์ž‘ํ•˜๋Š” JS

- content script : ์›น ํŽ˜์ด์ง€์— ์‚ฝ์ž…๋˜๋Š” JS

- options page : ์‚ฌ์šฉ์ž ์„ค์ • ํŽ˜์ด์ง€

- permissions : ์–ด๋–ค ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ• ์ง€ ์„ค์ • (์˜ˆ: ํƒญ ์ ‘๊ทผ, ์Šคํ† ๋ฆฌ์ง€)

 

์˜ˆ์‹œ)

{
  "manifest_version": 3, // ๋ฒ„์ „ 3 ์‚ฌ์šฉ (๋ฒ„์ „ 2๋Š” ์ง€์› ์ข…๋ฃŒ)
  "name": "My First Extension", // ์ต์Šคํ…์…˜ ์ด๋ฆ„
  "version": "0.1.0", // ํ˜„์žฌ ๋ฒ„์ „ (์•ฑ ์ฒ˜๋Ÿผ ๊ด€๋ฆฌ๋จ)
  "description": "This is a beginner-friendly Chrome extension.", // ์ต์Šคํ…์…˜ ์„ค๋ช…
  "icons": { // ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ ์•„์ด์ฝ˜ ํŒŒ์ผ ๊ฒฝ๋กœ
    "16": "assets/icon-16.png",
    "48": "assets/icon-48.png",
    "128": "assets/icon-128.png"
  },
  "action": { // ํฌ๋กฌ ํˆด๋ฐ”์—์„œ ํด๋ฆญํ–ˆ์„ ๋•Œ ๋‚˜์˜ค๋Š” ํŒ์—… ์„ค์ •
    "default_popup": "src/popup.html", // ์•„์ด์ฝ˜ ํด๋ฆญ ์‹œ ํ‘œ์‹œ๋  HTML ํŒŒ์ผ ๊ฒฝ๋กœ
    "default_icon": "assets/icon-48.png" // ์•„์ด์ฝ˜ ํŒŒ์ผ ๊ฒฝ๋กœ
  },
  "background": { 
    "service_worker": "src/background.js" // ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ณ„์† ์‹คํ–‰๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ
  },
  "permissions": ["storage", "tabs"], // ์ต์Šคํ…์…˜์ด ์‚ฌ์šฉํ•˜๋ ค๋Š” ๊ธฐ๋Šฅ๋“ค
  // storage: ๋ฐ์ดํ„ฐ ์ €์žฅ , tabs: ํƒญ ์กฐ์ž‘
  "host_permissions": ["https://example.com/*"], // ํŠน์ • ๋„๋ฉ”์ธ ์ ‘๊ทผ ๊ถŒํ•œ ์„ค์ •
  "content_scripts": [ // ์›น ํŽ˜์ด์ง€์— ์‚ฝ์ž…๋˜๋Š” JS ์„ค์ •
    {
      "matches": ["https://*/*"], // ์–ด๋–ค URL์—์„œ ์ฝ˜ํ…์ธ  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ• ์ง€ ๋ช…์‹œ
      "js": ["src/content.js"] // ์‹คํ–‰ํ•  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ ๊ฒฝ๋กœ
    }
  ]
}

 

 

๐Ÿงฉ ์™œ popup.html์„ ์จ์•ผ ํ• ๊นŒ?

๋‚˜๋Š” React ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋‚ด ๊ฒฝ์šฐ src/Popup.tsx ์•ˆ์— ํŒ์—… ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž‘์„ฑํ•ด๋‘์—ˆ๋‹ค.

 

๊ทธ๋Ÿฐ๋ฐ, ํฌ๋กฌ ์ต์Šคํ…์…˜์€ default_popup์— HTML ํŒŒ์ผ ๊ฒฝ๋กœ๋งŒ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

React ์ปดํฌ๋„ŒํŠธ(popup.tsx)๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ง์ ‘ ์ดํ•ดํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ˜๋“œ์‹œ HTML๋กœ ๊ฐ์‹ธ์ค˜์•ผ ํ•œ๋‹ค.

 

์ฆ‰, popup.tsx๋Š” ์ง์ ‘ ๋„ฃ์„ ์ˆ˜ ์—†๊ณ ,

"action": {
  "default_popup": "popup.html"
}

 

์ด๋Ÿฐ ์‹์œผ๋กœ ์จ์•ผ ํ•˜๊ณ , popup.html ์•ˆ์—์„œ React ์•ฑ(popup.tsx)์„ ๋งˆ์šดํŠธํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 


๐Ÿ“ ๊ตฌ์กฐ ์˜ˆ์‹œ

src/
โ”œโ”€โ”€ popup.tsx
โ”œโ”€โ”€ popup.html

 

popup.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Popup</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/popup.tsx"></script>
  </body>
</html>

 

popup.tsx

import React from 'react'
import ReactDOM from 'react-dom/client'

function Popup() {
  return <div className="text-xl text-blue-500">Hello from Popup!</div>
}

const root = document.getElementById('root')!
ReactDOM.createRoot(root).render(<Popup />)

 


๐Ÿ›  Vite ์„ค์ • ํŒ

 

Vite๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ index.html์„ ๊ธฐ์ค€์œผ๋กœ ์ž‘๋™ํ•˜์ง€๋งŒ, ์—ฌ๋Ÿฌ ๊ฐœ์˜ entry HTML์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'

export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      input: {
        popup: resolve(__dirname, 'src/popup.html'),
        // background ์Šคํฌ๋ฆฝํŠธ๋‚˜ content script๋Š” entry๋งŒ ๋“ฑ๋กํ•ด์ค˜๋„ ๋จ
      },
      output: {
        // ํด๋” ๊ตฌ์กฐ ๊น”๋”ํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ ์กฐ์ •
      }
    },
    outDir: 'dist',
  },
})

 

๐Ÿš€ ๋””๋ฒ„๊น… ํ•˜๋Š” ๋ฐฉ๋ฒ•

 

๐Ÿ“Œ ๊ฐ€์ด๋“œ

- ๋ฆฌ์•กํŠธ๋กœ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, build ํ›„, dist/ ํด๋”์—๋„ manifest.json์„ ๋ณต์‚ฌํ•œ๋‹ค.

- ํฌ๋กฌ ์ฃผ์†Œ์ฐฝ์— chrome://extensions๋ฅผ ์ž…๋ ฅํ•œ๋‹ค.

 

- "๊ฐœ๋ฐœ์ž ๋ชจ๋“œ"๋ฅผ ํ™œ์„ฑํ™”ํ•œ๋‹ค.

์šฐ์ธก ์ƒ๋‹จ ํ† ๊ธ€ on


- "์••์ถ•ํ•ด์ œ๋œ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์„ ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค" ๋ฒ„ํŠผ์„ ํด๋ฆญํ•œ๋‹ค. (Load unpacked ๋ฒ„ํŠผ ํด๋ฆญ)
- ํ”„๋กœ์ ํŠธ ํด๋”๋ฅผ ์„ ํƒํ•œ๋‹ค. (๋กœ์ปฌ ๋””๋ฐ”์ด์Šค์˜ dist ํด๋” ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•„์„œ ์—…๋กœ๋“œํ•ด ์ค€๋‹ค. )
- ์ •์ƒ์ ์œผ๋กœ ๋กœ๋“œ๋˜์—ˆ๋‹ค๋ฉด ํˆด๋ฐ”์— ์•„์ด์ฝ˜์ด ๋‚˜ํƒ€๋‚  ๊ฒƒ์ด๋‹ค.

 

 

๐Ÿ“Œ ์ฐธ๊ณ  ์‚ฌํ•ญ

background์™€ content_scripts๋Š” ๊ฐ๊ฐ ๋ณ„๋„์˜ ๋””๋ฒ„๊น… ์ฝ˜์†”์„ ๊ฐ€์ง„๋‹ค.