Como usar o jQuery na extensão do Chrome?

Eu estou escrevendo uma extensão de cromo. E eu quero usar o jQuery na minha extensão. Não estou usando nenhuma página de plano de fundo, apenas um script de plano de fundo.

Aqui estão meus arquivos:

manifest.json

 { "manifest_version": 2, "name": "Extension name", "description": "This extension does something,", "version": "0.1", "permissions": [ "activeTab" ], "browser_action": { "default_icon": "images/icon_128.png" }, "background": { "scripts": ["background.js"], "persistent": false }, "icons": { "16": "images/icon_16.png", "48": "images/icon_48.png", "128": "images/icon_128.png" } } 

Meu arquivo background.js apenas executa outro arquivo chamado work.js

 // Respond to the click on extension Icon chrome.browserAction.onClicked.addListener(function (tab) { chrome.tabs.executeScript({ file: 'work.js' }); }); 

A lógica principal da minha extensão está dentro do work.js O conteúdo do qual não acho que importa aqui para esta questão.

O que eu quero perguntar é como posso usar o jQuery na minha extensão. Desde que eu não estou usando nenhuma página de fundo. Eu não posso simplesmente adicionar o jQuery a ele. Então, como posso adicionar e usar o jQuery na minha extensão?

Eu tentei executar o jQuery junto com o meu trabalho.js do arquivo background.js .

 // Respond to the click on extension Icon chrome.browserAction.onClicked.addListener(function (tab) { chrome.tabs.executeScript({ file: 'thirdParty/jquery-2.0.3.js' }); chrome.tabs.executeScript({ file: 'work.js' }); }); 

E funciona bem, mas estou tendo a preocupação se os scripts adicionados para serem executados dessa maneira estão sendo executados de forma assíncrona. Se sim, então pode acontecer que o work.js rode mesmo antes do jQuery (ou outras bibliotecas que eu possa adicionar no futuro).

E também gostaria de saber qual é a maneira correta e melhor de usar bibliotecas de terceiros na minha extensão do Chrome.

Você precisa adicionar seu script jquery ao seu projeto de extensão chrome e à seção de background de background do manifest.json desta forma:

  "background": { "scripts": ["thirdParty/jquery-2.0.3.js", "background.js"] } 

Se você precisa de jquery em um content_scripts, você tem que adicioná-lo no manifesto também:

 "content_scripts": [ { "matches":["http://website*"], "js":["thirdParty/jquery.1.10.2.min.js", "script.js"], "css": ["css/style.css"], "run_at": "document_end" } ] 

Isso foi o que eu fiz.

Além disso, se bem me lembro, os scripts de fundo são executados em uma janela de fundo que você pode abrir via chrome://extensions .

É muito fácil fazer o seguinte:

adicione a seguinte linha no seu mainfest.json

 "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'", 

agora você está livre para carregar o jquery diretamente do url

   

Fonte: google doc

E funciona bem, mas estou tendo a preocupação se os scripts adicionados para serem executados dessa maneira estão sendo executados de forma assíncrona. Se sim, então pode acontecer que o work.js rode mesmo antes do jQuery (ou outras bibliotecas que eu possa adicionar no futuro).

Isso não deve ser uma preocupação: você coloca scripts em fila para serem executados em um determinado contexto JS e esse contexto não pode ter uma condição de corrida, já que é de encadeamento único.

No entanto, a maneira correta de eliminar essa preocupação é encadear as chamadas:

 chrome.browserAction.onClicked.addListener(function (tab) { chrome.tabs.executeScript({ file: 'thirdParty/jquery-2.0.3.js' }, function() { // Guaranteed to execute only after the previous script returns chrome.tabs.executeScript({ file: 'work.js' }); }); }); 

Ou generalizado:

 function injectScripts(scripts, callback) { if(scripts.length) { var script = scripts.shift(); chrome.tabs.executeScript({file: script}, function() { if(chrome.runtime.lastError && typeof callback === "function") { callback(false); // Injection failed } injectScripts(scripts, callback); }); } else { if(typeof callback === "function") { callback(true); } } } injectScripts(["thirdParty/jquery-2.0.3.js", "work.js"], doSomethingElse); 

Ou, promisified (e trouxe mais de acordo com a assinatura adequada):

 function injectScript(tabId, injectDetails) { return new Promise((resolve, reject) => { chrome.tabs.executeScript(tabId, injectDetails, (data) => { if (chrome.runtime.lastError) { reject(chrome.runtime.lastError.message); } else { resolve(data); } }); }); } injectScript(null, {file: "thirdParty/jquery-2.0.3.js"}).then( () => injectScript(null, {file: "work.js"}) ).then( () => doSomethingElse ).catch( (error) => console.error(error) ); 

Ou, por que diabos não, async / aguardado para uma syntax ainda mais clara:

 function injectScript(tabId, injectDetails) { return new Promise((resolve, reject) => { chrome.tabs.executeScript(tabId, injectDetails, (data) => { if (chrome.runtime.lastError) { reject(chrome.runtime.lastError.message); } else { resolve(data); } }); }); } try { await injectScript(null, {file: "thirdParty/jquery-2.0.3.js"}); await injectScript(null, {file: "work.js"}); doSomethingElse(); } catch (err) { console.error(err); } 

Note que no Firefox você pode usar o browser.tabs.executeScript já que ele retornará um Promise.

Além das soluções já mencionadas, você também pode baixar o jquery.min.js localmente e usá-lo –

Para baixar –

 wget "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js" 

manifest.json –

 "content_scripts": [ { "js": ["/path/to/jquery.min.js", ...] } ], 

em html –

  

Referência – https://developer.chrome.com/extensions/contentSecurityPolicy