M
M
Mikhail Vasiltsev2021-10-01 15:59:40
JavaScript
Mikhail Vasiltsev, 2021-10-01 15:59:40

How to enable import/export inside chrome.tabs.executeScript?

I am making a chrome plugin for my needs. Not an expert on the subject. Modularity for background.js and popup.js works, I just put it in html and everything is ok, imports / exports work. But here is such a case, an example of code in background.js:
<script type="module"...

chrome.tabs.onUpdated.addListener((tabId, _, tab) => {
  if(tab.url.match(/^myRegexpHere$/) )
    chrome.tabs.executeScript(tabId, { file: 'background/something.js' })   
});


So, in this something.js, I would also like to use imports, because there is a lot of code to write there, not to turn the file into a footcloth for 1000 lines.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Mikhail Vasiltsev, 2021-10-05
@mihail430899

In short, the answer to your own question turned out to be a decent footcloth. The current solution is in the second part of the answer, and in the first summary from the discussion on stackoverflow.
In general, here is a question on stackoverflow under which the most different solutions were collected https://stackoverflow.com/questions/48104433/how-t...
What I understood from all this:

  1. The best thing to do is get familiar with Webpack and build the browser plugin code through it. Perhaps another collector will also work, the same Parcel.
  2. You can do without import / export by connecting several scripts from top to bottom and using functions and variables from the top ones in the bottom one. But it seems to me that it is not so convenient for development. The imperative approach of such a multi-connection for plug-ins on mv2 (manifest.json v2) is inconvenient, because it is necessary to wrap one executeScript with another. The declarative one is a little more convenient, but then you need to sculpt all this directly into manifest.json, this also has its drawbacks. If you make a plug-in on mv3, the imperative is better there, because instead of file in executeScript, the files array is specified.
  3. A hack with an intermediate file in executeScript, which inserts our own script with business logic into the web page (and you also need to add scripts to web_accessible_resources in manifest.json). I tried it, it worked, but this solution does not look very elegant, and it was also criticized on stackoverflow. mv2 allows you to do this, mv3 does not skip such a rough method.
  4. It might also be a good idea to move the extension to manifest v3. This is generally correct, and there on stackoverflow they suggested a kind of good solution for mv3, which I also checked - it is slightly better than the previous one, but still not very good, especially if the plugin is large.

Well, for the convenient development of a large plugin, only option 1 (hike).
UPD : As a result, after another re-reading of the information from the indicated link on stackoverflow, I came up with an option that can only be called a mega-crutch. But it allows you to limit yourself to one intermediate file, and in 1 line, and through it to connect any number of files, where you can already freely use imports. And also this way is not as crude as inserting the script tag directly into the web page. In general, I even liked it.
Crutch uses 3 solutions:
  1. One executeScript nested within another
  2. Using globalThis
  3. Using Dynamic Import

And more specifically, in background.js I have this:
chrome.tabs.executeScript(tabId, { code: 'globalThis.path = "folder/your_content_script.js"'}, () => {
  chrome.tabs.executeScript(tabId, { file: 'folder/middle.js' })
})

middle.js is a 1 line file:
(async () => await import(chrome.runtime.getURL(globalThis.path)))()

And that's it, it works! In order not to write a nested executeScript in background.js every time, I made a helper function:
function executeImportedScript(tabId, path) {
  chrome.tabs.executeScript(tabId, { code: `globalThis.path = '${path}'`}, () => {
    chrome.tabs.executeScript(tabId, { file: 'folder/middle.js' })
  })
}

And in the right place just:
executeImportedScript(tabId, "folder/your_content_script.js")

Only in manifest.json in the web_accessible_resources key must there be paths to all content scripts + paths to all scripts from which content scripts import something. And in fact, this is the only problem that I see with this method so far - the swelling of manifest.json and web_accessible_resources in particular (for a large plugin).

P
profesor08, 2021-10-02
@profesor08

Connect all scripts at once.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question