Vue.js ν¬νκ³Ό ν΅ν©λλ React κΈ°λ° AI Agent Chrome Extension μμ νλ‘μ νΈμ λλ€.
μ΄ λ ν¬μ§ν 리λ λ κ°μ λ 립μ μΈ νλ‘μ νΈλ‘ ꡬμ±λμ΄ μμ΅λλ€:
react-addon/
βββ chrome-extension/     # React κΈ°λ° Chrome Extension
β   βββ popup/           # Extension νμ
 UI
β   βββ content.js       # μ½ν
μΈ  μ€ν¬λ¦½νΈ
β   βββ background.js    # λ°±κ·ΈλΌμ΄λ μ컀
β   βββ manifest.json    # Extension μ€μ 
β
βββ vue-portal/          # Vue.js ν¬ν μμ
    βββ src/
    β   βββ views/       # νμ΄μ§ μ»΄ν¬λνΈ
    β   βββ stores/      # Pinia μν κ΄λ¦¬
    β   βββ router/      # Vue Router
    βββ index.html
React 18 + Viteλ‘ κ΅¬μΆλ Chrome ExtensionμΌλ‘, Vue.js ν¬νκ³Ό ν΅ν©λμ΄ AI Agent κΈ°λ₯μ μ 곡ν©λλ€.
μ£Όμ κΈ°λ₯:
- π± React κΈ°λ° νμ UI
- π Vue.js ν¬ν μλ κ°μ§
- π¬ μ€μκ° μλ°©ν₯ ν΅μ
- π ν¬ν λ°μ΄ν° μΆμΆ (DOM, μ¬μ©μ μ 보, λ€λΉκ²μ΄μ )
- π€ AI 쿼리 μ²λ¦¬
Vue 3 + Pinia + Vue Routerλ‘ κ΅¬μΆλ μμ ν¬νλ‘, Chrome Extensionκ³Όμ ν΅ν©μ ν μ€νΈν μ μμ΅λλ€.
μ£Όμ κΈ°λ₯:
- π ν, λμ보λ, νλ‘ν νμ΄μ§
- π‘ Extensionκ³Ό μ€μκ° ν΅μ
- π§ͺ Extension ν μ€νΈ κΈ°λ₯
- π¦ Pinia μν κ΄λ¦¬
# Extension ν΄λλ‘ μ΄λ
cd chrome-extension
# μμ‘΄μ± μ€μΉ
npm install
# λΉλ
npm run buildChromeμμ Extension μ€μΉ:
- chrome://extensions/μ μ
- "κ°λ°μ λͺ¨λ" νμ±ν
- "μμΆν΄μ λ νμ₯ νλ‘κ·Έλ¨μ λ‘λν©λλ€" ν΄λ¦
- chrome-extension/dist/ν΄λ μ ν
# ν¬ν ν΄λλ‘ μ΄λ
cd vue-portal
# μμ‘΄μ± μ€μΉ
npm install
# κ°λ° μλ² μ€ν
npm run devν¬νμ΄ http://localhost:3000μμ μ€νλ©λλ€.
- λΈλΌμ°μ μμ http://localhost:3000μ μ
- Chrome Extension μμ΄μ½ ν΄λ¦νμ¬ νμ μ΄κΈ°
- μ°κ²° μν νμΈ: "ν¬ν μ°κ²°λ¨" νμ νμΈ
- νμ μμ AI 쿼리 μ λ ₯ λ° μ μ‘
- λΈλΌμ°μ  μ½μ(F12)μμ λ©μμ§ λ‘κ·Έ νμΈ
βββββββββββββββββββ
β   Vue Portal    β
β (localhost:3000)β
ββββββββββ¬βββββββββ
         β postMessage
         β
ββββββββββ΄βββββββββ
β Content Script  β  ββββ Extensionμ ν¬ν ν΅ν© λ μ΄μ΄
ββββββββββ¬βββββββββ
         β Chrome API
         β
ββββββββββ΄βββββββββββββ
β Background Worker   β  ββββ AI μ²λ¦¬ λ° λ©μμ§ μ€κ³
ββββββββββ¬βββββββββββββ
         β Chrome API
         β
ββββββββββ΄βββββββββ
β  Popup (React)  β  ββββ μ¬μ©μ μΈν°νμ΄μ€
βββββββββββββββββββ
| νμ | μ€λͺ | λ°μ΄ν° | 
|---|---|---|
| ADDON_READY | Extension μ€λΉ μλ£ | { source: 'react-addon' } | 
| AI_QUERY | AI 쿼리 μ μ‘ | { message, timestamp } | 
| GET_DOM_DATA | DOM λ°μ΄ν° μμ² | - | 
| νμ | μ€λͺ | λ°μ΄ν° | 
|---|---|---|
| PORTAL_READY | ν¬ν μ€λΉ μλ£ | { appVersion, capabilities } | 
| PORTAL_RESPONSE | AI 쿼리 μλ΅ | { text, timestamp } | 
| DOM_DATA | DOM λ°μ΄ν° μ μ‘ | { url, title, userInfo, ... } | 
cd chrome-extension
# κ°λ° λͺ¨λ (hot reload μμ, μλ reload νμ)
npm run dev
# νλ‘λμ
 λΉλ
npm run buildλλ²κΉ :
- νμ : νμ μ°ν΄λ¦ β κ²μ¬
- Content Script: ν¬ν νμ΄μ§μμ F12 β Console
- Background: chrome://extensions/β "μλΉμ€ μ컀" ν΄λ¦
cd vue-portal
# κ°λ° μλ² (hot reload μ§μ)
npm run dev
# νλ‘λμ
 λΉλ
npm run buildλλ²κΉ :
- λΈλΌμ°μ  μ½μ(F12)μμ Extension λ©μμ§ λ‘κ·Έ νμΈ
- Vue Devtools μ¬μ© κΆμ₯
const sendNewMessageType = async () => {
  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true })
  chrome.tabs.sendMessage(tab.id, {
    type: 'NEW_MESSAGE_TYPE',
    data: { ... }
  })
}window.addEventListener('message', (event) => {
  if (event.data.source === 'react-addon') {
    switch (event.data.type) {
      case 'NEW_MESSAGE_TYPE':
        // μ²λ¦¬ λ‘μ§
        break
    }
  }
})- 
λΉλ: cd chrome-extension npm run build
- 
ZIP νμΌ μμ±: cd dist zip -r ../extension.zip * 
- 
Chrome Web Store μ λ‘λ: - Chrome Web Store Developer Dashboard μ μ
- μ νλͺ© μ λ‘λ
- extension.zipνμΌ μ ν
 
- 
λΉλ: cd vue-portal npm run build
- 
λ°°ν¬: - dist/ν΄λλ₯Ό μΉ μλ²μ λ°°ν¬
- Netlify, Vercel, AWS S3 λ± μ¬μ© κ°λ₯
 
- 
Extension manifest μ λ°μ΄νΈ: "content_scripts": [ { "matches": ["https://your-actual-domain.com/*"], ... } ] 
chrome-extension/background.js νμΌμμ:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'PROCESS_AI') {
    // μ€μ  AI API νΈμΆ
    const response = await fetch('https://your-ai-api.com', {
      method: 'POST',
      body: JSON.stringify(message.data)
    })
    const result = await response.json()
    chrome.runtime.sendMessage({
      type: 'PORTAL_RESPONSE',
      data: { text: result.answer }
    })
  }
})chrome-extension/manifest.jsonμμ:
"content_scripts": [
  {
    "matches": ["https://your-portal.com/*"],  // μ€μ  URLλ‘ λ³κ²½
    "js": ["content.js"]
  }
]cd vue-portal
# 1. μ μ»΄ν¬λνΈ μμ±
touch src/views/NewPage.vue
# 2. λΌμ°ν°μ μΆκ° (src/router/index.js)- β
 manifest.jsonμ matchesURL νμΈ
- β Extensionμ΄ νμ±νλμ΄ μλμ§ νμΈ
- β νμ΄μ§ μλ‘κ³ μΉ¨ (F5)
- β
 Extension μ¬λ‘λ (chrome://extensions/)
- β λΈλΌμ°μ  μ½μμμ μλ¬ νμΈ
- β
 event.data.sourceκ° νμΈ
- β Content Scriptκ° λ‘λλμλμ§ νμΈ
- β λ©μμ§ λ¦¬μ€λκ° λ±λ‘λμλμ§ νμΈ
- β Node.js λ²μ  νμΈ (v16 μ΄μ κΆμ₯)
- β
 node_modulesμμ  ν μ¬μ€μΉ
- β
 μΊμ ν΄λ¦¬μ΄: npm cache clean --force
- βοΈ React 18.2
- β‘ Vite 5.0
- π¨ CSS3
- π§ Chrome Extension Manifest V3
- π Vue 3.3
- π Pinia 2.1 (μν κ΄λ¦¬)
- π£οΈ Vue Router 4.2
- β‘ Vite 5.0
- Chrome Extension κ°λ° κ°μ΄λ
- Vue Portal κ°λ° κ°μ΄λ
- Chrome Extension API λ¬Έμ
- Vue.js 곡μ λ¬Έμ
- React 곡μ λ¬Έμ
- Fork the Project
- Create your Feature Branch (git checkout -b feature/AmazingFeature)
- Commit your Changes (git commit -m 'Add some AmazingFeature')
- Push to the Branch (git push origin feature/AmazingFeature)
- Open a Pull Request
MIT License
μ΄ νλ‘μ νΈλ λ€μκ³Ό κ°μ μλ리μ€μ νμ©ν μ μμ΅λλ€:
- π€ μΉ ν¬νμ AI μ΄μμ€ν΄νΈ μΆκ°
- π ν¬ν λ°μ΄ν° λΆμ λ° μΈμ¬μ΄νΈ μ 곡
- π λ κ±°μ μμ€ν μ νλμ μΈ UI/UX μΆκ°
- π― μ¬μ©μ νλ μΆμ  λ° κ°μ μ μ
- π 컨ν μ€νΈ κΈ°λ° λμλ§ μμ€ν 
λ¬Έμμ¬νμ΄λ μ μμ΄ μμΌμλ©΄ Issueλ₯Ό μμ±ν΄μ£ΌμΈμ!
Made with β€οΈ using React, Vue, and Chrome Extension API