Rag*_*nar 31 javascript google-chrome google-chrome-extension ecmascript-6
在Chrome 61中,增加了对JavaScript模块的支持.现在我正在运行Chrome 63.
我试图弄清楚如何在Chrome扩展内容脚本中使用导入/导出语法来使用模块.
在manifest.json中:
"content_scripts":[{
"content_scripts": [
{
"js": [
"content.js"
],
}
]
Run Code Online (Sandbox Code Playgroud)
在my-script.js中,与content.js位于同一目录中
'use strict';
const injectFunction = () => window.alert('hello world');
export default injectFunction;
Run Code Online (Sandbox Code Playgroud)
在content.js中
'use strict';
import injectFunction from './my-script.js';
injectFunction();
Run Code Online (Sandbox Code Playgroud)
我收到此错误: Uncaught SyntaxError:意外的标识符
如果我将导入语法更改为import {injectFunction} from './my-script.js';I,则会收到以下错误:Uncaught SyntaxError:Unexpected token {
在Chrome扩展中的content.js中使用此语法是否存在一些问题,因为在HTML中您必须使用<script type="module" src="script.js">语法,或者我做错了什么?谷歌会忽略对扩展的支持,这似乎很奇怪.
Rag*_*nar 21
我设法找到了解决方法.
首先,重要的是说内容脚本自2018年1月起不支持模块.但是您可以通过将模块脚本标记嵌入到返回扩展的页面中来使其工作.
这是我的表现
"content_scripts": [ {
"js": [
"content.js"
]
}],
"web_accessible_resources": [
"main.js",
"my-script.js"
]
Run Code Online (Sandbox Code Playgroud)
请注意,我在Web可访问资源中有两个脚本.
我的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);
Run Code Online (Sandbox Code Playgroud)
这会将main.js作为模块脚本插入到网页中.我的所有业务逻辑现在都在main.js和main中,而且我将要导入的所有脚本都必须位于清单中的web_accessible_resources中.
这是my-script.js的示例内容:
'use strict';
const injectFunction = () => window.alert('hello world');
export {injectFunction};
Run Code Online (Sandbox Code Playgroud)
在main.js中,这是导入脚本的示例:
'use strict';
import {injectFunction} from './my-script.js';
injectFunction();
Run Code Online (Sandbox Code Playgroud)
这工作,没有错误被抛出,我很高兴:)
oti*_*i10 15
正如已经提到的那样,对于后台脚本,最好使用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();
})();
Run Code Online (Sandbox Code Playgroud)
更多细节:
希望能帮助到你.
ava*_*he1 13
imports 在内容脚本中不可用。
这是使用全局范围的解决方法。
由于内容脚本存在于它们自己的“孤立世界”中- 它们共享相同的全局命名空间。它只能被 中声明的内容脚本访问manifest.json。
这是实现:
清单文件
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": [
"content-scripts/globals.js",
"content-scripts/script1.js",
"content-scripts/script2.js"
]
}
],
Run Code Online (Sandbox Code Playgroud)
globals.js
globalThis.foo = 123;
Run Code Online (Sandbox Code Playgroud)
脚本1.js
some_fn_that_needs_foo(globalThis.foo);
Run Code Online (Sandbox Code Playgroud)
以同样的方式,您可以将可重用的功能和其他角色分解import出内容脚本文件中的其他角色。
注意:除了内容脚本之外,任何页面都无法使用内容脚本的全局命名空间 - 因此几乎没有全局范围污染。
如果您需要导入一些库 - 您将不得不使用一个Parcel打包器,比如将您的内容脚本文件与所需的库huge-content-script.js打包成一个文件,然后在manifest.json.
小智 12
最好的方法是使用像 webpack 或 Rollup 这样的打包器。
我摆脱了基本配置
const path = require('path');
module.exports = {
entry: {
background: './background.js',
content: './content.js',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../build')
}
};
Run Code Online (Sandbox Code Playgroud)
使用命令运行文件
webpack --config ./ext/webpack-ext.config.js
Run Code Online (Sandbox Code Playgroud)
捆绑器组合相关文件,我们可以在 chrome 扩展中使用模块化!:D
您需要在构建文件夹中保留所有其他文件,如清单和静态文件。
玩弄它,你最终会找到让它工作的方法!
我只是在尝试自己解决同样的问题时偶然发现了这个问题。
无论如何,我认为有一个更简单的解决方案可以将您自己的自定义模块注入您的内容脚本。我正在研究 Jquery 是如何注入的,我发现您可以通过创建一个IIFE(立即调用的函数表达式),并在你的manifest.json 中声明它
它是这样的:
在您的 manifest.json 中:
"content_scripts": [
{
"matches": ["https://*"],
"css": ["css/popup.css"],
"js": ["helpers/helpers.js"]
}],
Run Code Online (Sandbox Code Playgroud)
然后在 helpers/helpers.js 中创建一个 IIFE:
var Helpers = (function() {
var getRandomArbitrary = function(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
return {
getRandomArbitrary: getRandomArbitrary
}
})()
Run Code Online (Sandbox Code Playgroud)
现在,您可以在内容脚本中自由使用辅助函数:
Helpers.getRandomArbitrary(0, 10) // voila!
Run Code Online (Sandbox Code Playgroud)
我认为如果您使用这种方法来重构您的一些通用函数,那就太好了。希望这可以帮助!
有一个名为crxjs的很棒的插件,您只需更新它vite.config.ts并提供您的路径manifest.json(它仅适用于manifets_version >= 3)。
请按照以下步骤运行脚本:
npm install --save-dev @crxjs/vite-plugin
Run Code Online (Sandbox Code Playgroud)
manifest.json:
{
"manifest_version": 3,
"name": "CRXJS React Vite Example",
"version": "1.0.0",
"action": { "default_popup": "index.html" }
}
Run Code Online (Sandbox Code Playgroud)
vite.config.ts使用清单的路径
更新您的文件:import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { crx } from '@crxjs/vite-plugin'
import manifest from './manifest.json'
export default defineConfig({
plugins: [
react(),
crx({ manifest }),
],
})
Run Code Online (Sandbox Code Playgroud)
设置完成后,运行您的项目。现在config.js将被捆绑,您可以在其中导入包。
| 归档时间: |
|
| 查看次数: |
9012 次 |
| 最近记录: |