web-dev-qa-db-fra.com

Comment importer des modules ES6 dans un script de contenu pour Chrome Extension

Dans Chrome 61 , le support des modules en JavaScript a été ajouté. En ce moment, je suis sous Chrome 63.

J'essaie de comprendre comment utiliser la syntaxe d'importation/exportation dans le script de contenu d'extension Chrome pour utiliser des modules.

Dans manifest.json :

"content_scripts": [ {

        "js": [
            "content.js"
        ],

Dans my-script.js dans le même répertoire que content.js

'use strict';

const injectFunction = () => window.alert('hello world');

export default injectFunction;

Dans content.js

'use strict';

import injectFunction from './my-script.js';
injectFunction();

Je reçois cette erreur: Uncaught SyntaxError: Identifiant inattendu

Si je change la syntaxe d'importation en import {injectFunction} from './my-script.js'; j'obtiens cette erreur: Uncaught SyntaxError: Jeton inattendu {

Existe-t-il un problème d'utilisation de cette syntaxe dans content.js dans l'extension Chrome? En HTML, vous devez utiliser la syntaxe <script type="module" src="script.js">, ou est-ce que je fais quelque chose de mal? Il semble étrange que Google ignore le support des extensions.

17
Ragnar

J'ai réussi à trouver une solution de contournement .

Tout d'abord, il est important de préciser que les scripts de contenu ne prennent pas en charge les modules à partir de janvier 2018. Mais vous pouvez le faire fonctionner en incorporant une balise script de module dans la page qui renvoie à votre extension.

Ceci est dans mon manifeste

"content_scripts": [ {
   "js": [
     "content.js"
   ]
}],
"web_accessible_resources": [
   "main.js",
   "my-script.js"
]

Notez que j'ai deux scripts dans les ressources accessibles sur le Web.

Mon content.js contient uniquement cette logique:

'use strict';

const script = document.createElement('script');
script.setAttribute("type", "module");
script.setAttribute("src", chrome.extension.getURL('main.js'));
const head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
head.insertBefore(script, head.lastChild);

Ceci insérera main.js dans la page Web en tant que script de module. Toute ma logique métier est maintenant dans main.js et main, ainsi que tous les scripts que je vais importer doivent figurer dans web_accessible_resources dans le manifeste.

Voici l'exemple de contenu de my-script.js :

'use strict';

const injectFunction = () => window.alert('hello world');

export {injectFunction};

Et dans main.js voici un exemple d'importation du script:

'use strict';

import {injectFunction} from './my-script.js';
injectFunction();

Cela fonctionne, aucune erreur n'est commise et je suis heureux :)

11
Ragnar

Comme il a déjà été mentionné, pour le script d'arrière-plan, il est judicieux d'utiliser background.page et d'utiliser <script type="module"> pour lancer votre JavaScript.

Le problème est content script et l'injection de la balise <script> avec l'attribut type peut constituer une solution.

Une autre approche que l’injection de balise de script consiste à utiliser la fonction dynamic import. Avec cette approche, vous n’avez pas besoin de perdre la portée du module chrome et pouvez toujours utiliser chrome.runtime ou d’autres modules.

Dans content_script.js, cela ressemble à

(async () => {
  const src = chrome.extension.getURL("your/content_main.js");
  const contentMain = await import(src);
  contentMain.main();
})();

Pour plus de détails:

J'espère que ça aide.

5
otiai10

Je suis tombé sur cette question en essayant de résoudre la même chose moi-même.

Quoi qu'il en soit, je pense qu'il existe une solution plus simple pour injecter vos propres modules personnalisés dans votre script de contenu . Je regardais comment Jquery est injecté et il me semble que vous pouvez faire la même chose en créant unIIFE(expression de fonction immédiate), et en le déclarant dans votre manifest.json

Ca fait plutot comme ca:

Dans votre manifeste.json:

"content_scripts": [
{
  "matches": ["https://*"],
  "css": ["css/popup.css"],
  "js": ["helpers/helpers.js"]
}],

Ensuite, créez simplement un IIFE dans vos helpers/helpers.js:

var Helpers = (function() {
  var getRandomArbitrary = function(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
  }
  return {
    getRandomArbitrary: getRandomArbitrary
  }
})()

Maintenant, vous pouvez utiliser librement vos fonctions d'assistance dans votre script de contenu:

Helpers.getRandomArbitrary(0, 10) // voila!

Je pense que c’est bien si vous utilisez cette méthode pour refactoriser certaines de vos fonctions génériques. J'espère que cela t'aides!

2
Daniel Chan