【问题标题】:Using webpack worker-loader with nuxt.js将 webpack worker-loader 与 nuxt.js 一起使用
【发布时间】:2018-08-15 02:57:43
【问题描述】:

我正在尝试在 nuxt.js framework 中使用 Web Worker,但不断收到引用错误。 ReferenceError: Worker is not defined.

我已经通过 npm 安装了worker-loader 1.1.1,并将以下规则添加到我的nuxt.config.js

module.exports = {
  build: {
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
      // Web Worker support
      config.module.rules.push({
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader' },
        exclude: /(node_modules)/
      })
    }
  }
}

如果我通过 nuxt build 创建构建,它看起来就像创建了 web worker 文件。

Asset                           Size                      
2a202b9d805e69831a05.worker.js  632 bytes          [emitted]

我将它导入到 vuex 模块中,如下所示:

import Worker from '~/assets/js/shared/Loader.worker.js'

console.log(Worker)
const worker = new Worker // <- this line fails!

在控制台中,我得到了一个看起来像创建工作者的函数:

ƒ () {
  return new Worker(__webpack_require__.p + "345c16d02e75e9312f73.worker.js");
}

在worker内部,我只是有一些虚拟代码来看看它是否真的有效:

const msg = 'world!'

self.addEventListener('message', event => {
  console.log(event.data)
  self.postMessage({ hello: msg })
})

self.postMessage({ hello: 'from web worker' })

【问题讨论】:

  • 我也尝试过使用 workerize-loader 但得到了不同的错误。我确定这与我的配置有关,但我仍然不知道该怎么做。 github.com/developit/workerize-loader/issues/27
  • 不应该是new Worker()吗?
  • @lukas-reineke 如果您不向 JS 中的构造函数发送参数,那么括号是可选的。 stackoverflow.com/a/3034952/205696 无论如何,我都尝试了(以及许多其他方法),但都失败了。
  • 尝试以这种方式导入 import * as Worker from "worker-loader!~/assets/js/shared/Loader.worker.js'"; 这种类型的导入然后创建一个实例。

标签: webpack nuxt.js


【解决方案1】:

让我们先解决一些问题:

  • worker 仅在客户端可用 -> 无 ssr

所以要么你需要使用no ssr component,要么需要将应用程序设置为无ssr

有了这些知识,我们将nuxt.config.js修改如下:

mode: 'spa',
build: {
  extend(config, { isDev, isClient }) {
    ...
    // Web Worker support
    if (isClient) {
      config.module.rules.push({
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader' },
        exclude: /(node_modules)/
      })
    }
  }
}

npm run buildnpm run start 之后,它应该像一个魅力一样工作。

我为你创建了一个 repo,它是一个标准的 nuxt 模板,使用了 worker-loader:Github Repo

【讨论】:

  • 最后 - 谢谢@Greaka!直到现在,我明白了为什么,我遇到了另一个问题。如何使用仅客户端的 Web Worker 构建支持 SSR 的普通版本的 nuxt?我不使用 &lt;no-ssr&gt; 的主要问题是 web worker 是在 vuex 模块中使用来进行预取的。
  • 看来我可以将它实现为插件-但不确定如何在vuex代码中使用该插件...github.com/nuxt/nuxt.js/issues/1607#issuecomment-328489139
  • 好的。它在 ssr 设置为 false 的插件中工作。 { src: '~/plugins/load-ww', ssr: false } 但 vuex 文件在插件之前运行,因此我无法通过 Vue.use() 使网络工作者访问存储文件。
  • 我玩弄了它并以一个示例 PR 结束:github.com/nuxt/nuxt.js/pull/3044
  • @husayt 看起来你自己在github.com/nuxt/nuxt.js/pull/3480#issuecomment-404150387回答了这个问题
【解决方案2】:

使用worker-loader,有the fallback option,但就我个人而言(这就是我正在做的),我只会将通信代码保留在直接的worker文件中,导入具有实际工作负载的第二个文件。这样第二个文件也可以在服务器端导入。 很可能在分叉线程/线程池中,除非您在 FaaS 上下文中并且您的主线程实际上无事可做。

另外,您是否必须在nuxt.config.js 中使用以下内容?对我来说,没有它,它就是“窗口未定义”。 (在浏览器中,尝试实例化工作者时)

extend(config, ctx) {
    /*
    ** Required for HotModuleReloading to work with worker-loader
    */
    config.output.globalObject = 'this'
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-02-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-27
  • 2019-05-26
  • 2018-08-16
  • 2018-10-17
  • 2021-04-10
相关资源
最近更新 更多