J'écris une extension chrome. Et je veux utiliser jQuery
dans mon extension. Je n'utilise aucun fond page, juste un fond script.
Voici mes fichiers:
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"
}
}
Mon fichier background.js
exécute simplement un autre fichier nommé work.js
// Respond to the click on extension Icon
chrome.browserAction.onClicked.addListener(function (tab) {
chrome.tabs.executeScript({
file: 'work.js'
});
});
La logique principale de mon extension est à l'intérieur de work.js
. Le contenu dont je ne pense pas que les questions importent ici pour cette question.
Ce que je veux demander, c'est comment utiliser jQuery dans mon extension. Depuis je n'utilise aucune page de fond. Je ne peux pas simplement y ajouter jQuery. Alors, comment puis-je ajouter et utiliser jQuery dans mon extension?
J'ai essayé d'exécuter jQuery avec mon fichier work.js à partir du fichier 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'
});
});
Et cela fonctionne bien, mais je me demande si les scripts ajoutés pour être exécutés de cette manière sont exécutés de manière asynchrone. Si oui, alors il peut arriver que work.js exécute même avant jQuery (ou d'autres bibliothèques que je pourrais ajouter à l'avenir).
Et j'aimerais également savoir quelle est la meilleure façon d'utiliser les bibliothèques tierces, dans mon extension chrome.
Vous devez ajouter votre script jQuery à votre projet chrome-extension et à la section background
de votre fichier manifest.json comme ceci:
"background":
{
"scripts": ["thirdParty/jquery-2.0.3.js", "background.js"]
}
Si vous avez besoin de jquery dans un content_scripts, vous devez également l'ajouter dans le manifeste:
"content_scripts":
[
{
"matches":["http://website*"],
"js":["thirdParty/jquery.1.10.2.min.js", "script.js"],
"css": ["css/style.css"],
"run_at": "document_end"
}
]
C'est ce que j'ai fait.
De plus, si je me souviens bien, les scripts d’arrière-plan sont exécutés dans une fenêtre d’arrière-plan que vous pouvez ouvrir via chrome://extensions
.
C'est très facile, il suffit de faire ce qui suit:
ajoute la ligne suivante dans votre mainfest.json
"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'",
maintenant vous êtes libre de charger jquery directement depuis l'url
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
Source: google doc
Et cela fonctionne bien, mais je me demande si les scripts ajoutés pour être exécutés de cette manière sont exécutés de manière asynchrone. Si c'est le cas, il peut arriver que work.js soit exécuté avant jQuery (ou d'autres bibliothèques que je pourrais ajouter à l'avenir).
Cela ne devrait pas vraiment être un problème: vous mettez en file d'attente les scripts à exécuter dans un certain contexte JS, et ce contexte ne peut pas avoir de condition de concurrence critique car il s'agit d'un thread unique.
Cependant, le moyen approprié d’éliminer ce problème consiste à enchaîner les appels:
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 généralisé:
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 (et apporté plus en conformité avec la signature appropriée):
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 alors pourquoi pas, async
/await
- ed pour une syntaxe encore plus claire:
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);
}
Notez que dans Firefox, vous pouvez simplement utiliser browser.tabs.executeScript
car il retournera une promesse.
Outre les solutions déjà mentionnées, vous pouvez également télécharger jquery.min.js
localement et l’utiliser ensuite -
Pour le téléchargement -
wget "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"
manifest.json -
"content_scripts": [
{
"js": ["/path/to/jquery.min.js", ...]
}
],
en html -
<script src="/path/to/jquery.min.js"></script>
Référence - https://developer.chrome.com/extensions/contentSecurityPolicy