安装Webpack插件
VueCli 项目中默认是没有加载 worker
的配置,需要额外安装 webpack
插件来实现,让我们开始安装 worker-loader
插件
# npm
npm install worker-loader
# pnpm
pnpm install worker-loader
# yarn
yarn add worker-loader
配置Webpack插件
然后我们开始配置 vue.config.js
增加下面配置
{
// ...
chainWebpack: config => {
// 配置 worker-loader 插件,匹配处理 *.worker.js 文件
config.module.rule('worker')
.test(/\.worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.tap(() => ({ worker: 'SharedWorker' }))
.end();
// 排除 *.worker.js 解决无法热更新问题
config.module.rule('js').exclude.add(/\.worker\.js$/);
}
// ...
}
编写SharedWorker
然后我们在 src/*
任意目录下创建 *.worker.js
文件,例如 src/test.worker.js
// path: src/test.worker.js
const ports = [];
onconnect = (event) => {
const port = event.ports[0];
ports.push(port);
port.onmessage = (event) => {
const data = event.data;
console.log('[Main] 收到消息', event.data);
// 关闭连接
if (data === 'close') {
const index = ports.findIndex(vo => vo === port);
index > -1 && ports.splice(index, 1);
}
// 测试连接
if (data === 'ping') {
port.postMessage('ok');
}
// 广播消息
if (data === 'broadcast') {
ports.forEach((vo) => vo.postMessage('say'));
}
};
};
编写App.vue
然后我们在应用中去初始化 src/test.worker.js
并测试调用
// path: src/App.vue
import TestWorker from './test.worker.js';
export default {
// ...
created() {
const worker = new TestWorker()
worker.port.start();
worker.port.onmessage = (event) => {
console.log('[Main] 收到消息', event.data);
};
setTimeout(() => {
worker.port.postMessage('ping');
}, 1000);
setTimeout(() => {
worker.port.postMessage('broadcast');
}, 2000);
// 监听当前页面关闭主动销毁端口
window.addEventListener('beforeunload', () => {
worker.port.postMessage('close');
});
}
// ...
};
开始调试
SharedWorker 在浏览器所有归属当前应用页签都关闭后会直接结束
浏览器输入 chrome://inspect/#workers 点击查看 Shared workers 即可查看当前运行中的 Shared workers 其中,inspect 是打开调试控制台,terminate 是结束当前任务
当焦点标签页关闭后,主动删除 port 可以优化内存,用于维护活跃的页面列表