在Chrome 61中,增加了对JavaScript模块的支持。现在我正在运行Chrome 63。
我试图在Chrome扩展内容脚本中使用import
/export
语法来使用模块。
在manifest.json
中
"content_scripts": [
{
"js": [
"content.js"
],
}
]
在my-script.js
(与content.js
):相同的目录)中
'use strict';
const injectFunction = () => window.alert('hello world');
export default injectFunction;
在content.js
中
'use strict';
import injectFunction from './my-script.js';
injectFunction();
我收到这个错误:Uncaught SyntaxError: Unexpected identifier
如果我将导入语法更改为import {injectFunction} from './my-script.js';
,则会得到以下错误:import {injectFunction} from './my-script.js';
在Chrome扩展中在content.js
中使用这种语法有什么问题(因为在<script type="module" src="script.js">
中您必须使用<script type="module" src="script.js">
语法),还是我做错了什么?令人感到奇怪的是,谷歌竟然忽视了对扩展的支持。
发布于 2018-01-05 21:36:48
我设法为找到了一个解决的方法。
免责声明
首先,重要的是要说到2018年1月,内容脚本不支持模块。通过将模块script
标记嵌入到导致扩展的页面中,这一解决方案避开了限制。
解决办法
这是我的manifest.json
"content_scripts": [ {
"js": [
"content.js"
]
}],
"web_accessible_resources": [
"main.js",
"my-script.js"
]
请注意,web_accessible_resources
中有两个脚本。
这是我的content.js
'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);
这将将main.js
作为模块脚本插入到网页中。
我所有的业务逻辑现在都在main.js
中。
要使此方法工作,main.js
(以及我将import
的所有脚本)必须在清单中的web_accessible_resources
中。
示例用法:my-script.js
'use strict';
const injectFunction = () => window.alert('hello world');
export {injectFunction};
在main.js
中,这是一个导入脚本的示例:
'use strict';
import {injectFunction} from './my-script.js';
injectFunction();
这行得通!没有错误被抛出,我很高兴。:)
发布于 2018-10-28 15:58:19
如前所述,对于背景脚本来说,使用background.page
和使用<script type="module">
来启动JavaScript是个好主意。
问题是content script
,将<script>
标记注入type
属性可以是一个解决方案。
与注入脚本标记相比,另一种方法是使用dynamic import
函数。通过这种方法,您不需要松散chrome
模块的范围,仍然可以使用chrome.runtime
或其他模块。
在content_script.js
中,它看起来像是
(async () => {
const src = chrome.runtime.getURL("your/content_main.js");
const contentMain = await import(src);
contentMain.main();
})();
您还需要在清单的Web可访问资源中声明导入的脚本
// ManifestV3
"web_accessible_resources": [{
"matches": ["<all_urls>"],
"resources": ["your/content_main.js"]
}],
// ManifestV2
"web_accessible_resources": [
"your/content_main.js"
]
欲知更多详情:
希望能帮上忙。
发布于 2019-09-27 15:16:02
import
在内容脚本中不可用。
这里有一个使用全局范围的解决方案。
因为内容脚本存在于自己的“孤立的世界”中--它们共享相同的全局命名空间。只有在manifest.json
中声明的内容脚本才能访问它。
以下是实现:
manifest.json
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": [
"content-scripts/globals.js",
"content-scripts/script1.js",
"content-scripts/script2.js"
]
}
],
globals.js
globalThis.foo = 123;
script1.js
some_fn_that_needs_foo(globalThis.foo);
同样,您可以筛选出可重用的函数和其他参与者,否则您将在内容脚本文件中使用import
。
注:除了内容脚本之外,任何页面都无法使用内容脚本的全局命名空间--因此几乎没有全局范围污染。
如果您需要导入一些libs -您必须使用像Parcel
这样的绑定器将内容脚本文件和所需的库打包到一个huge-content-script.js
中,然后在manifest.json
中处理它。
P.S.:globalThis上的文档
https://stackoverflow.com/questions/48104433
复制相似问题