这篇内容是在有道云旧笔记基础上重新整理的 Vue/Vite 工程实践 笔记。原始记录偏碎片化,这里补充了使用场景、阅读顺序和落地时需要注意的边界,方便以后在项目里快速复用。

适用场景 ​

  • Vue/Vite 项目中遇到配置、组件封装、构建或运行时问题时,作为排查入口。
  • 需要把一次性调试经验沉淀成团队内可复用的前端工程实践。
  • 迁移旧项目或升级依赖时,用来对照检查环境变量、插件和组件行为差异。

核心要点 ​

  • 正文以代码或命令片段为主,阅读时建议先确认目标问题,再挑选对应片段验证。
  • 保留了 1 段可直接参考的代码或命令,主要涉及 javascript,复制前需要按当前项目路径、版本和变量名做调整。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
schedule.worker.js

// schedule.worker.js

/**
* 获取距离下次指定时间的毫秒数
* @param {number} hour - 小时 (0-23)
* @param {number} minute - 分钟 (0-59)
* @param {number} second - 秒 (0-59)
*/
function getMsUntilNextTarget(hour, minute = 0, second = 0) {
const now = new Date();
const target = new Date(now);

target.setHours(hour, minute, second, 0);

// 如果目标时间已经过去,则设为明天
if (target.getTime() <= now.getTime()) {
target.setDate(target.getDate() + 1);
}

return target.getTime() - now.getTime();
}

/**
* 启动定时任务
* @param {Array<{hour:number,minute?:number,second?:number}>} times - 每天的多个触发时刻
*/
function startSchedule(times) {
function scheduleNext() {
// 找出离当前最近的触发时间
let minMs = Infinity;
let nextTime = null;

for (const t of times) {
const ms = getMsUntilNextTarget(t.hour, t.minute || 0, t.second || 0);
if (ms < minMs) {
minMs = ms;
nextTime = t;
}
}

setTimeout(() => {
postMessage({ type: 'trigger', time: nextTime });
// 继续下一轮
scheduleNext();
}, minMs);
}

scheduleNext();
}

// 监听主线程传过来的配置
globalThis.onmessage = (e) => {
if (e.data.type === 'start') {
startSchedule(e.data.times || []);
}
};


// hooks/useSolarTerms.js
import SolarTerms from '@/workers/schedule.worker.js?worker';

export default function useSolarTerms() {
const solarTermsData = ref(null);
let solarTermsWorker = null;
onMounted(() => {
solarTermsWorker = new SolarTerms();
// 配置每天的触发时间(多个时间点)
solarTermsWorker.postMessage({
type: 'start',
times: [
{ hour: 0, minute: 0 }, // 每天凌晨
{ hour: 17, minute: 40 }, // 每天下午 16:00
],
});
// 监听 Web Worker 消息
solarTermsWorker.onmessage = (e) => {
if (e.data.type === 'trigger') {
const { hour, minute = 0 } = e.data.time;
solarTermsData.value = { hour, minute };
console.log('%c [ 触发时间: ]-85', 'font-size:14px; background:#cf222e; color:#fff;', `触发时间: ${hour}:${minute}`);
}
};
});

onUnmounted(() => {
if (solarTermsWorker) solarTermsWorker.terminate();
});

return { solarTermsData };
}

// stores/schedule.js
import { acceptHMRUpdate, defineStore } from 'pinia';

import ScheduleWorker from '@/workers/schedule.worker.js?worker';

const useSchedule = defineStore('schedule', {
state: () => ({
solarTermsData: {},
}),
actions: {
startScheduler() {
const solarTermsWorker = new ScheduleWorker();
// 配置每天的触发时间(多个时间点)
solarTermsWorker.postMessage({
type: 'start',
times: [
{ hour: 0, minute: 0 }, // 每天凌晨
{ hour: 17, minute: 56 }, // 每天下午 16:00
],
});
// 监听 Web Worker 消息
solarTermsWorker.onmessage = (e) => {
if (e.data.type === 'trigger') {
const { hour, minute = 0 } = e.data.time;
this.solarTermsData = { hour, minute };
console.log('%c [ 触发时间: ]-85', 'font-size:14px; background:#cf222e; color:#fff;', `触发时间: ${hour}:${minute}`);
}
};
this._solarTermsWorker = solarTermsWorker; // 保存引用以便后续销毁
},
stopScheduler() {
if (this._solarTermsWorker) {
this._solarTermsWorker.terminate();
this._solarTermsWorker = null;
this.solarTermsData = {};
}
},
},
});

if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useSchedule, import.meta.hot));
}

export default useSchedule;


// vue
import useSolarTerms from '@/hooks/useSolarTerms';

const schedule = useSchedule();
const { solarTermsData } = storeToRefs(schedule);

{{ solarTermsData }}

实践检查清单 &#8203;

  • 先确认 Vue、Vite、Node、包管理器版本,再判断示例是否需要按当前工程结构调整。
  • 涉及构建或插件配置时,建议同时验证开发环境和生产构建结果。
  • 涉及 UI 或浏览器行为时,至少在桌面端和移动端各验证一次关键路径。

复盘小结 &#8203;

这篇笔记更适合作为问题排查或方案落地前的速查材料。后续如果在真实项目中再次遇到同类问题,可以继续把具体版本、报错信息、最终取舍和验证结果补到对应小节里,让它从代码片段逐步沉淀成完整方案。