等待条件配置
injectsWaitCondition 和 externalsWaitCondition 允许您配置代码执行前的等待条件,确保依赖的资源已经准备就绪。
功能介绍
在某些场景下,网站可能有异步加载的模块或资源,如果直接执行 externals 或 injects 代码可能会因为依赖未就绪而报错。等待条件功能可以让代码在特定条件满足后再执行。
配置
typescript
// vite.config.ts
import { defineConfig } from "vite";
export default defineConfig({
// ...
plugins: [
// ...
ViteWebExtKits({
// externals 代码执行前的等待条件
externalsWaitCondition: {
condition: "!!window.MyApp && !!window.MyApp.ready",
timeoutSeconds: 10,
checkInterval: 100,
},
// injects 代码执行前的等待条件
injectsWaitCondition: {
condition: `!!window["my-extension_externals"]`,
timeoutSeconds: 5,
checkInterval: 50,
},
}),
],
});// vite.config.ts
import { defineConfig } from "vite";
export default defineConfig({
// ...
plugins: [
// ...
ViteWebExtKits({
// externals 代码执行前的等待条件
externalsWaitCondition: {
condition: "!!window.MyApp && !!window.MyApp.ready",
timeoutSeconds: 10,
checkInterval: 100,
},
// injects 代码执行前的等待条件
injectsWaitCondition: {
condition: `!!window["my-extension_externals"]`,
timeoutSeconds: 5,
checkInterval: 50,
},
}),
],
});配置参数
typescript
type WaitCondition = {
// 等待条件,字符串形式的条件表达式
condition: string;
// 超时时间(秒)
timeoutSeconds: number;
// 检查间隔(毫秒)
checkInterval: number;
};type WaitCondition = {
// 等待条件,字符串形式的条件表达式
condition: string;
// 超时时间(秒)
timeoutSeconds: number;
// 检查间隔(毫秒)
checkInterval: number;
};使用示例
typescript
import { ViteWebExtKits } from "@webextkits/vite-plugins";
export default defineConfig({
plugins: [
ViteWebExtKits({
extensionId: "my-extension",
// externals 代码执行前的等待条件
externalsWaitCondition: {
condition: "!!window.MyApp && !!window.MyApp.ready",
timeoutSeconds: 10,
checkInterval: 100,
},
// injects 代码执行前的等待条件
injectsWaitCondition: {
condition: `!!window["my-extension_externals"]`,
timeoutSeconds: 5,
checkInterval: 50,
},
}),
],
});import { ViteWebExtKits } from "@webextkits/vite-plugins";
export default defineConfig({
plugins: [
ViteWebExtKits({
extensionId: "my-extension",
// externals 代码执行前的等待条件
externalsWaitCondition: {
condition: "!!window.MyApp && !!window.MyApp.ready",
timeoutSeconds: 10,
checkInterval: 100,
},
// injects 代码执行前的等待条件
injectsWaitCondition: {
condition: `!!window["my-extension_externals"]`,
timeoutSeconds: 5,
checkInterval: 50,
},
}),
],
});使用场景
1. 等待网站模块加载完成
某些网站(如 Facebook)的模块是异步加载的,需要等待特定模块就绪:
typescript
externalsWaitCondition: {
condition: "!!window.require && !!window.require('react')",
timeoutSeconds: 15,
checkInterval: 200
}externalsWaitCondition: {
condition: "!!window.require && !!window.require('react')",
timeoutSeconds: 15,
checkInterval: 200
}2. 确保 externals 在 injects 之前加载
injects 代码通常依赖 externals 中的库,可以配置等待条件确保加载顺序:
typescript
injectsWaitCondition: {
condition: `!!window["${extensionId}_externals"]`,
timeoutSeconds: 10,
checkInterval: 100
}injectsWaitCondition: {
condition: `!!window["${extensionId}_externals"]`,
timeoutSeconds: 10,
checkInterval: 100
}3. 等待 DOM 特定状态
等待页面特定元素或状态就绪:
typescript
injectsWaitCondition: {
condition: "!!document.querySelector('#app') && !!window.APP_INITIALIZED",
timeoutSeconds: 30,
checkInterval: 500
}injectsWaitCondition: {
condition: "!!document.querySelector('#app') && !!window.APP_INITIALIZED",
timeoutSeconds: 30,
checkInterval: 500
}生成的代码示例
配置等待条件后,生成的代码会被包装在等待函数中:
javascript
// 生成的 externals.js 示例
(function () {
var startTime = Date.now();
var timeoutMs = 10000; // 10秒
var checkInterval = 100; // 100毫秒
function checkCondition() {
try {
return (function () {
return !!window.MyApp && !!window.MyApp.ready;
})();
} catch (e) {
return false;
}
}
function waitingForCondition(callback) {
function check() {
if (Date.now() - startTime > timeoutMs) {
console.error(
'[externals] 等待条件超时: "!!window.MyApp && !!window.MyApp.ready"'
);
console.error("[externals] 超过 10 秒未满足条件,代码未执行");
return; // 超时后不执行代码
}
if (checkCondition()) {
callback();
} else {
setTimeout(check, checkInterval);
}
}
check();
}
waitingForCondition(function () {
// 原始的 externals 代码在这里执行
(function () {
// ... externals 内容
})();
});
})();// 生成的 externals.js 示例
(function () {
var startTime = Date.now();
var timeoutMs = 10000; // 10秒
var checkInterval = 100; // 100毫秒
function checkCondition() {
try {
return (function () {
return !!window.MyApp && !!window.MyApp.ready;
})();
} catch (e) {
return false;
}
}
function waitingForCondition(callback) {
function check() {
if (Date.now() - startTime > timeoutMs) {
console.error(
'[externals] 等待条件超时: "!!window.MyApp && !!window.MyApp.ready"'
);
console.error("[externals] 超过 10 秒未满足条件,代码未执行");
return; // 超时后不执行代码
}
if (checkCondition()) {
callback();
} else {
setTimeout(check, checkInterval);
}
}
check();
}
waitingForCondition(function () {
// 原始的 externals 代码在这里执行
(function () {
// ... externals 内容
})();
});
})();注意事项
- 条件表达式:必须是可以被
eval执行的 JavaScript 表达式,返回布尔值 - 超时处理:超时后代码不会执行,会在控制台输出错误信息
- 性能影响:检查间隔不宜太小,建议 50-500ms 之间
- 错误处理:条件表达式执行出错会被捕获,视为条件未满足
Webextkits Docs