3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue + Vuex + TypeScriptでWeb Workerを試してみる

Posted at

はじめに

色々なところで**「Web Worker」**という単語は見聞きするのですが、いまだに使ったことがなかったので試してみました。

今回勉強がてらVue CLI 4で作成したアプリケーションにVuexとTypeScriptも導入したので、

  • vue-property-decorator
  • vuex-module-decorators

を利用しています。

また、素で使ってみたかったので**「Web Worker」**に関するライブラリは使いません。

設定

npm i worker-loader -D
vue.config.js
module.exports = {
  publicPath: process.env.VUE_APP_PUBLIC_PATH,
  transpileDependencies: ['vuetify'],
  configureWebpack: {
    module: {
      rules: [
        {
          test: /\.worker\.ts$/,
          use: {
            loader: 'worker-loader',
          },
        },
        {
          test: /\.worker\.ts$/,
          use: ['ts-loader'],
          exclude: /node_modules/,
        },
      ],
    },
  },
}
  • worker-loaderを追加
  • 今回はインラインにしませんが、検索するとインラインでやっている方が多かったのはなぜなのかわかっていません

あと、自分の環境だけなのか「worker-loader」の書き方が悪いと、↓のエラーが出て動きません
解決に半日かかりました……

Uncaught SyntaxError: Unexpected token '<'

VuexのActionとMutation

store/datatable.Ts
import {
  Module,
  VuexModule,
  Action,
  Mutation,
  getModule,
} from 'vuex-module-decorators'
import store from '@/store'

const SampleWorker = require('@/worker/sample.worker')

@Module({
  dynamic: true,
  store,
  name: 'DataTableModule',
  namespaced: true,
})
class DataTableModule extends VuexModule {
  private datalist: any[] = []

  public get GET_DATA_LIST() {
    return this.datalist
  }

  @Mutation
  private SET_DATA_LIST(payload: any[]) {
    this.datalist = payload
  }

  @Action
  public async fetch() {
    const w: Worker = new SampleWorker()
    const params = {}

    // web worker側でAPI Callさせる(今回はパラメータはなし)
    w.postMessage({ params })

    // Getした値を受け取る
    w.addEventListener('message', e => {
      this.SET_DATA_LIST(e.data.message)
      w.terminate()
    })
  }
}

export default getModule(DataTableModule)
  • require('@/worker/sample.worker')ではなく、importにするとエラーとなる

Cannot use 'new' with an expression whose type lacks a call or construct signature.

Web Worker

sample.worker.ts
import axios from '@/plugins/axios'

const w: Worker = self as any

w.addEventListener('message', async e => {
  const res = await axios.get('/comments')

  // web worker側でデータを加工してメインスレッドに返すほうがぽい気がしたので
  const message = res.data.length ? res.data.slice() : []
  
  w.postMessage({ message })
})

export default w

まとめ

worker-loaderの使い方がよくわからずまあまあハマりました。

Web Worker自体は難しいことはなく、実務でも使えそうなのでどこかのタイミングで導入してみたいです。

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?