欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue 中使用 worker-loader 及遇到的问题

程序员文章站 2022-07-03 17:06:43
...

Web Worker 使用教程
Worker - Web API 接口参考 | MDN

版本

  • Vue CLI 3
  • webpack 4
  • worker-loader 3

vue-cli3 中依赖的 webpack 版本是 "webpack": "^4.0.0",而 "worker-loader": "^3.0.0" 要求的 webpack 版本是 4 | 5
使用前要检查下各个依赖对应版本,不然会引发一些错误。
不同版本配置文件会有所不同,后面介绍。

使用

参考:vue中使用web worker

webpack 配置

vue-cli 的 webpack 配置在 vue.config.js 文件中,Vue CLI 内部的 webpack 配置是通过 webpack-chain 维护的,采用链式操作的写法:

vue.config.js

chainWebpack: config => {
	// 配置
    config.module
      .rule('worker')
      .test(/\.worker\.js$/)
      .use('worker')
      .loader('worker-loader')
      .options({
        inline: 'fallback'
      })
    // 解决 "window is undefined", 这是因为 worker 线程中不存在 window 对象, 要用 this 代替: (不过我的项目中配置了这个也不行, 用的 self 代替, 后面介绍)
    config.output.globalObject('this')
  },
  // 解决打包的时报错: (由于一些原因我的项目最后没有使用 worker, 也就没有研究打包遇到的问题...)
  parallel: false,

worker 文件

my.worker.js

本来要在子线程做一个异步请求,但我本地调试的时候访问的是测试地址,所以就出现了跨域问题。由于一些原因我的项目最后没有使用 worker, 也就没有研究跨域的问题…
不过 for 循环那里已经能看到效果了:

// import ajax from './ajax'

function getData(params) {
  console.log('异步... ', params)
  let count = 0
  for (let i = 0; i < 10000000000; i++) {
    // console.log(i)
    count = i
  }
  console.log('count: ', count)
  // ajax(
  //   '请求的 url, 相对路径会报错',
  //   params,
  //   function(res) {
  //     console.log(123, res)
  //     postMessage(res)
  //   },
  //   function(err) {
  //     console.log(456, err)
  //   }
  // )
}

onmessage = function(event) {
  if (event.data) {
    getData(event.data)
  }
}

ajax.js

上面说遇到了跨域问题,所以这里也没法测试参数什么的。仅供参考吧:

export default function ajax(url, params, fnSucc, fnFaild) {
  console.log(111, params)
  // 1.创建ajax对象
  var oAjax = null
  // self 用在了这里
  if (self.XMLHttpRequest) {
    oAjax = new XMLHttpRequest()
  } else {
    oAjax = new ActiveXObject('Microsoft.XMLHTTP')
  }

  // 2.连接服务器 open(方法, url, 是否异步)
  oAjax.open('GET', `${url}?page=${params.page}&pagesize=${params.pagesize}, true)

  // 3.发送请求
  oAjax.send()

  // 4.接收返回 OnReadyStateChange
  oAjax.onreadystatechange = function() {
    if (oAjax.readyState === 4) {
      if (oAjax.status === 200) {
        fnSucc(oAjax.responseText)
      } else {
        if (fnFaild) {
          fnFaild()
        }
      }
    }
  }
}

在组件中使用

我是用在单文件组件中:

import Worker from './my.worker'

const worker = new Worker()
const params = this.getParams()
worker.postMessage(params)
worker.onmessage = function (e) {
  console.log(333, e.data)
  worker.terminate()
}
worker.onerror = function (error) {
  console.log(444, error, error.message)
  worker.terminate()
}

热更新问题

每次修改完 worker.js 文件或 ajax.js 给它们重新命名。

可能遇到的问题

  1. npm run dev 启动不了,并且 webpack 报错:检查下 webpack worker-loader 的版本。
  2. 控制台报错包含 not a functionnot a constructor:检查下 webpck 配置。最好是查看英文文档 webpack,因为中文文档更新不及时。
  3. 终端报错包含 namefallbackoptions 关键字:同2,查看英文文档写法。
  4. 控制台报错 window is not defined:改成 self 试试。参考 Webpack worker-loader - import doesn’t work

以上。