はじめに
色々なところで**「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自体は難しいことはなく、実務でも使えそうなのでどこかのタイミングで導入してみたいです。