等待条件配置
injectsWaitCondition 和 externalsWaitCondition 允许您配置代码执行前的等待条件,确保依赖的资源已经准备就绪。
Injects 内置等待条件
injects 代码会自动等待 externals 加载完成后再执行,无需手动配置。内置等待条件为:
javascript
!!window["${extensionId}"] && !!window["${extensionId}_externals"]!!window["${extensionId}"] && !!window["${extensionId}_externals"]这意味着即使你不配置 injectsWaitCondition,injects 代码也会确保 externals 中的库(react、antd 等)已就绪后才执行,避免因加载顺序导致的运行时错误。
内置条件默认使用 30 秒超时、50ms 检查间隔。
TIP
如果你同时配置了 injectsWaitCondition,你的条件会与内置条件自动合并(AND 关系),最终条件为:(内置条件) && (你的条件),超时和间隔使用你配置的值。
功能介绍
在某些场景下,网站可能有异步加载的模块或资源,如果直接执行 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 代码执行前的附加等待条件(会与内置 externals 就绪检查自动合并)
injectsWaitCondition: {
condition: "!!document.querySelector('#app')",
timeoutSeconds: 10,
checkInterval: 100,
},
}),
],
});// 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 代码执行前的附加等待条件(会与内置 externals 就绪检查自动合并)
injectsWaitCondition: {
condition: "!!document.querySelector('#app')",
timeoutSeconds: 10,
checkInterval: 100,
},
}),
],
});配置参数
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 附加等待条件(内置的 externals 就绪检查无需手动配)
injectsWaitCondition: {
condition: "!!document.querySelector('#app')",
timeoutSeconds: 10,
checkInterval: 100,
},
}),
],
});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 附加等待条件(内置的 externals 就绪检查无需手动配)
injectsWaitCondition: {
condition: "!!document.querySelector('#app')",
timeoutSeconds: 10,
checkInterval: 100,
},
}),
],
});使用场景
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. 等待 DOM 特定状态
injects 已自动等待 externals 就绪,如果还需要额外等待页面状态,可以配置 injectsWaitCondition:
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
}最终生效的条件为:(!!window["my-extension"] && !!window["my-extension_externals"]) && (!!document.querySelector('#app') && !!window.APP_INITIALIZED)
生成的代码示例
配置等待条件后,生成的代码会被包装在等待函数中:
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