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

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

以上。

你可能感兴趣的:(Vue.js,web,worker,worker-loader)