web-dev-qa-db-fra.com

Plusieurs fichiers JS dans Chrome - comment les charger?

J'ai écrit une extension Chrome. Mon fichier background.js est assez volumineux, je veux donc le diviser en parties plus petites et charger les méthodes spécifiées si nécessaire (une sorte de chargement différé).

Je l'ai fait avec Firefox:

// ( call for load specified lib )
var libPath = redExt.basePath + 'content/redExt/lib/' + redExt.browser + '/' + libName + '.js';
var service = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
service.loadSubScript("chrome://" + libPath);
// ( executing loaded file )

Est-il possible de le faire de la même manière dans les navigateurs Webkit? J'ai trouvé des solutions pour injecter plusieurs fichiers JS dans des pages correspondantes (en utilisant manifest.json) mais ne peut pas trouver le moyen d'inclure le fichier JS juste pour l'extension.

24
Tomasz Banasiak

Solution possible trouvée. Il existe une implémentation simple de la méthode principale RequireJS, qui utilise la trace de rappel JavaScript pour rechercher un événement pour le chargement du fichier d'extension principal et la lie l'exécute avec le contexte d'extension. https://github.com/salsita/browser-require/blob/master/require.js

Cela semble fonctionner, mais cette solution a quelques inconvénients:

  • les rapports de bogues sont signalés dans la "ligne 1, colonne 1" car cette solution injecte du code directement dans func.call - le débogage est très difficile
  • Les fichiers JS chargés n'apparaissent pas dans la console/chromebug
  • Si l'onglet actuel utilise HTTPS Chrome interdira l'évaluation des scripts, en particulier à partir du contexte local (file:///), donc parfois ça ne marche pas comme prévu
1
Tomasz Banasiak

Vous pouvez également le faire de la manière extrêmement simple décrite ici: https://developer.chrome.com/extensions/background_pages#manifest

{
  "name": "My extension",
  ...
  "background": {
    "scripts": [
      "lib/fileone.js",
      "lib/filetwo.js",
      "background.js"
    ]
  },
  ...
}

Vous ne ferez pas de chargement paresseux, mais cela vous permet de diviser votre code en plusieurs fichiers et de spécifier l'ordre dans lequel ils sont chargés sur la page d'arrière-plan.

32
Omn

Si vous souhaitez charger un fichier javascript dans le contexte de votre page d'arrière-plan et éviter d'utiliser eval, vous pouvez simplement ajouter une balise script au DOM de votre page d'arrière-plan. Par exemple, cela fonctionne si vos fichiers sont présents dans le dossier lib de votre extension:

function loadScript(scriptName, callback) {
    var scriptEl = document.createElement('script');
    scriptEl.src = chrome.extension.getURL('lib/' + scriptName + '.js');
    scriptEl.addEventListener('load', callback, false);
    document.head.appendChild(scriptEl);
}
16
rsanchez

Vous pourriez peut-être essayer d'utiliser des employés Web. Dans votre background.js, incluez:

var worker = new Worker('new-script.js');

Les travailleurs Web peuvent générer de nouveaux travailleurs et même avoir une méthode importScript ("new-script.js").

Les travailleurs du Web peuvent cependant être très limités. Consultez ici pour un excellent article sur les travailleurs du Web.

Je ne sais pas s'ils fonctionneraient, cependant. L'autre option utilise XMLHTTPRequest (AJAX) pour récupérer dynamiquement le script et l'évaluer. Cependant, sur une connexion non HTTPS, cela est probablement bloqué en raison d'attaques d'homme au milieu. Alternativement, vous pouvez forcer Chrome à évaluer le script à partir d'une connexion non chiffrée (MAIS NE LE FAITES PAS) en l'ajoutant à manifest.json:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"permissions": ["http://badpractic.es/insecure.js"]

Voir Charger la page Web distante en page d'arrière-plan: Chrome pour une discussion plus approfondie de la méthode AJAX).

Vos options semblent donc limitées.

Bien sûr, cela les charge tous à la fois:

{
  "name": "My extension",
  ...
  "background": {
    "scripts": ["background.js","background2.js","background3.js"] //and so on
  },
  ...
}
3
mdenton8

Ce que j'ai fait n'est pas un chargement paresseux mais je charge certains fichiers avant les autres lorsque mon icône d'extension chrome est cliquée. Dans mon cas, je voulais mes fichiers util avant les autres qui les utilisent :

chrome.browserAction.onClicked.addListener(function() {
  chrome.tabs.executeScript(null, {file: "src/utils/utilFunction1.js"});
  chrome.tabs.executeScript(null, {file: "src/utils/utilFunction2.js"});
  chrome.tabs.executeScript(null, {file: "src/main.js"});
  chrome.tabs.executeScript(null, {file: "src/otherFeature.js"});
});
0
Ryan Walker