Chrome Extension: Import ES6 modules in content scripts
P粉141035089
2023-08-27 22:19:00
<p>In <strong>Chrome 61</strong>, support for JavaScript modules was added. Now I'm running Chrome 63. </p>
<p>I'm trying to use a module in a Chrome extension content script using the <code>import</code>/<code>export</code> syntax. </p>
<p>In<strong><code>manifest.json</code></strong>:</p>
<pre class="brush:php;toolbar:false;">"content_scripts": [
{
"js": [
"content.js"
],
}
]</pre>
<p>In<strong><code>my-script.js</code></strong> (with <strong><code>content.js</code></strong> same directory):</p>
<pre class="brush:php;toolbar:false;">'use strict';
const injectFunction = () => window.alert('hello world');
export default injectFunction;</pre>
<p>In<strong><code>content.js</code></strong>:</p>
<pre class="brush:php;toolbar:false;">'use strict';
import injectFunction from './my-script.js';
injectFunction();</pre>
<p>I get this error:<strong><code>Uncaught syntax error: Unexpected identifier</code></strong></p>
<p>If I change the import syntax to <code>import {injectFunction} from './my-script.js';</code> I get this error: <strong><code>Uncaught SyntaxError: Unexpected token {</code></strong>< /p>
</p><p>Is there a problem using this syntax in <strong><code>content.js</code></strong> in the Chrome extension (because in HTML you have to use < ;code>
<script type="module" src="script.js "></code> syntax), or am I doing something wrong? It seems strange that Google is ignoring support for extensions. </p></script>
</code></p>
Use dynamic
import()
function.Unlike the unsafe workaround using
elements, this workaround runs in the same secure JS environment (isolated world of content scripts) and your imported modules can still access global variables As well as functions for the initial content script, including the built-in
chrome
API, such aschrome.runtime.sendMessage
.In
content_script.js
it looks likeYou also need to declare the imported script in the manifest's Web Accessible Resources:
// ManifestV3
// ManifestV2
Learn more details:
chrome.runtime.getURL
李>Hope it helps.
Disclaimer
First, it’s important to note that as of January 2018, content scripts do not support modules. This workaround works around the restriction to your extension by embedding the module
script
tag into the returned page.This is an unsafe solution!
Web scripts (or other extensions) can exploit your code and extract/spoof data by using setters/getters, proxies on
Object.prototype
and other prototypes functions and /or the global object, because the code inside thescript
element runs in the JS context of the page, rather than in the secure isolated JS environment that runs content scripts by default.A safe workaround is the dynamic import()
shown in another answer
here.Solution
This is my
manifest.json
:Please note that I have two scripts in
web_accessible_resources
.This is my
content.js
:This will insert
main.js
as a module script into the web page.All my business logic is now in
main.js
.For this method to work,
main.js
(and all the scripts Iimport
into) must be located in web_accessible_resources in themanifest
.Usage example:
my-script.js
In
main.js
, this is an example of the import script:This works! No errors were thrown and I was happy. :)