0

我正在使用 React/Redux 开发一个 Chrome 扩展。为此,我正在使用 Webpack,现在我正在使用 WebPack DLLReference 插件将一些资源迁移到一个单独的文件中,以优化构建过程。

然后我需要将生成的 dll/dll.vendor.js 加载到我的弹出窗口和注入的内容中。对于弹出窗口它工作正常,但它不适用于注入的内容。

我已将其添加到清单中

"web_accessible_resources": [
    "dll/dll.vendor.js"
],

该文件在那里,我什至可以使用以下路径访问它:chrome-extension:///dll/dll.vendor.js

但它不存在于注入的内容中,因为我可以看到打开开发者工具 - > 源,当然,稍后会生成丢失对象的错误。

在迁移到 DLLReferencePlugin 之前一切正常。

我的 DLL webpack 配置文件:https ://pastebin.com/z9RjRUqm

我的内容 webpack 配置文件:https ://pastebin.com/0Niw2Fqm

我收到的错误

触发错误的行:

module.exports = vendor;

如果我检查弹出窗口,它有相同的行,如果我在那里设置一个断点并观察它定义的变量,问题只发生在内容中。

将我的扩展工具栏注入页面的代码:content/src/index.js

import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-redux';
import {Store} from 'react-chrome-redux';

const anchor = document.createElement('div');
anchor.id = 'my-anchor';
document.body.appendChild(anchor)

const vendorUrl = chrome.runtime.getURL("dll/dll.vendor.js")

render(
  <Provider store={proxyStore}>
      <div>
          <script src={vendorUrl}></script>
          <link id='semantic-ui' rel='stylesheet' type='text/css'
                href='https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.2/semantic.min.css' media='all' />
          <AppContainer>
              <ToolbarContent />
          </AppContainer>
      </div>
  </Provider>
  , document.getElementById('my-anchor'));

知道还有什么可能是导致此问题的原因吗?有什么更好的方法来调试资源对内容环境不可用的原因?

更新

根据我最后的发现,这是因为依赖于 dll.vendor 的代码是在页面上发生注入之前执行的,但我不知道如何避免这种情况发生。

4

1 回答 1

1

您对内容脚本的理解缺少一件事,即孤立世界范式

内容脚本在称为孤立世界的特殊环境中执行。他们可以访问被注入页面的 DOM,但不能访问页面创建的任何 JavaScript 变量或函数。它查看每个内容脚本,就好像它正在运行的页面上没有执行其他 JavaScript。反过来也是如此:在页面上运行的 JavaScript 不能调用任何函数或访问由内容脚本定义的任何变量。

这有什么关系?好吧,如果您<script>要向页面的 DOM 添加元素,代码将在页面的上下文中执行 - 而不是您的内容脚本的上下文。这种技术称为“页面级”或“注入”脚本

然而,这不是你想要的。您希望它在内容脚本上下文中,因此您可以使用这些库。然后你有选择:

  1. 如果您总是需要相同的脚本配置,最好将脚本作为数组添加到清单中。加载顺序很重要:

    "js" : [ "library.js", "actual_code.js" ]
    
  2. 如果您出于某种原因需要在运行时从现有内容脚本动态加载代码,您可以请求后台页面以编程方式为您注入代码。如果您已经这样做了,只需按正确的顺序链接调用即可。

  3. 不是技术上理想的解决方案,但您可以 XHR 您的内部资源,然后eval()从内容脚本上下文。

于 2017-05-31T16:58:42.827 回答