开发者问题收集

将 webpack worker-loader 与 nuxt.js 结合使用

2018-03-07
7133

我正在尝试在 nuxt.js 框架 中使用 Web Worker,但一直收到引用错误。 ReferenceError: Worker 未定义

我已经通过 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!

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

ƒ () {
  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' })
2个回答

我们先解决一些问题:

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

因此,您要么需要使用 无 ssr 组件 ,要么需要将应用程序设置为无 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,它是一个使用了 worker-loader 的标准 nuxt 模板: Github Repo

Greaka
2018-03-16

使用 worker-loader,有一个 后备选项 ,但就我个人而言(这就是我正在做的),我只会将通信代码保留在直接工作文件中,并导入第二个包含实际工作负载的文件。这样,第二个文件也可以在服务器端导入。 最有可能是在分叉线程/线程池中,除非您处于 FaaS 上下文中,并且您的主线程实际上没有其他事情可做。

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

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