特性
- 直接在 Storybook 中测试和模拟不同的用户代理
- 根据设备和浏览器检测结果差异化显示内容
- 通过实际解析用户代理,实现比基于屏幕尺寸更深入的设备检测
- 无需安装额外依赖即可使用
- 支持现代用户代理客户端提示 API,以实现更精确的浏览器和设备检测
安装与兼容性
Storybook 版本 | 安装命令 | 状态 |
---|---|---|
v8 | npm i -D storybook-addon-useragent@8 |
当前主要版本,积极维护中 |
v7 | npm i -D storybook-addon-useragent@7 |
遗留支持 |
v6 | npm i -D storybook-addon-useragent@6 |
遗留支持 |
您可以检查更新并升级到最新版本
npm outdated
npm install storybook-addon-useragent@latest
设置
在 .storybook/main.js
(或 .storybook/main.ts
) 中将此插件添加到您的 Storybook 配置
export default {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
// Other addons...
"storybook-addon-useragent",
],
};
用法
基本用法
安装后,UserAgent 插件将出现在您的 Storybook UI 中。您可以从预设的用户代理列表中选择,以模拟不同的浏览器和设备。
自定义用户代理列表
通过创建配置文件,您可以自定义插件中可用的用户代理列表
.storybook/userAgent.js
:
export const customUserAgents = [
{
name: "Windows_7-IE_11",
userAgent:
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
},
// Add more custom user agents as needed
];
然后将其导入并用于您的 .storybook/preview.js
文件
import { customUserAgents } from "./userAgent";
export const parameters = {
// Other parameters...
userAgent: customUserAgents,
};
在故事中设置默认用户代理
您可以为单个故事设置默认用户代理
import React from "react";
import { UserAgentExample } from "./UserAgentExample";
export default {
title: "Example/UserAgentExample",
component: UserAgentExample,
argTypes: { useragent: { control: "text" } },
};
const Template = (args) => <UserAgentExample {...args} />;
export const IOS = Template.bind({});
IOS.args = {
useragent:
"Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1 Mobile/15E148 Safari/604.1",
};
客户端提示支持
此插件支持用户代理客户端提示 API,这是一种比传统用户代理字符串更现代、更注重隐私的获取浏览器和设备信息的方式。
可用的客户端提示信息
- 浏览器信息(品牌、版本)
- 平台信息(平台、平台版本)
- 架构信息(架构、位数)
- 移动状态检测
- 设备型号信息
该插件在现代浏览器中自动使用客户端提示,而在旧版浏览器中则回退到传统用户代理字符串解析。
浏览器兼容性
此插件使用现代浏览器 API 来模拟用户代理
浏览器类别 | 支持级别 | 浏览器 | 备注 |
---|---|---|---|
完全支持 | ✅ | Chrome 89+、Edge 89+、Opera 75+ | 所有功能均按预期工作 |
良好支持 | ⚠️ | Firefox 90+、Safari 16.4+ | 大部分功能可用,存在一些限制 |
有限支持 | ⚠️ | Safari 15-16.3、Firefox 78-89 | 用户代理字符串可用,客户端提示受限 |
最低支持 | ⚠️ | IE11、旧版 Edge | 仅提供基本功能 |
在支持有限的浏览器中,插件会回退到基本功能,同时显示适当的警告。
性能考量
UserAgent 插件对 Storybook 性能影响极小
- 首次初始化:约 5-20ms
- 后续用户代理更改:约 1-5ms
- 内存使用量:可忽略不计(小于 1MB)
在极少数情况下,快速连续更改用户代理可能会导致 UI 暂时闪烁。我们建议:
- 避免在循环中更改用户代理
- 在两次用户代理更改之间留出足够的时间(大于 100ms)
- 考虑仅在需要它的特定故事中使用此插件
跨环境测试
测试工作流程示例
此示例展示了如何在多个设备上测试响应式组件
// ResponsiveComponent.stories.js
import { ResponsiveComponent } from "./ResponsiveComponent";
export default {
title: "Components/ResponsiveComponent",
component: ResponsiveComponent,
};
// Basic template
const Template = (args) => <ResponsiveComponent {...args} />;
// Create stories for different device types
export const Desktop = Template.bind({});
Desktop.args = {
// Default desktop user agent is used
};
export const iPhone = Template.bind({});
iPhone.args = {
useragent:
"Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1",
};
export const Android = Template.bind({});
Android.args = {
useragent:
"Mozilla/5.0 (Linux; Android 12; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.104 Mobile Safari/537.36",
};
您可以创建一个测试矩阵,以确保您的组件在不同浏览器中正常工作
- 在您的默认浏览器中测试基本功能
- 使用 UserAgent 插件在不同的模拟环境中进行测试
- 使用真实设备验证关键功能
安全注意事项
此插件修改 navigator
对象以模拟不同的用户代理。尽管我们已经采取了保护措施:
- 某些浏览器安全策略可能会限制这些修改
- 插件在可能的情况下使用代理和回退机制
- 更改仅限于 Storybook iframe 内部
- 故事更改时,所有修改都会被恢复
故障排除
常见问题
问题 | 可能原因 | 解决方案 |
---|---|---|
用户代理未更改 | 浏览器安全限制 | 尝试使用其他浏览器(Chrome 效果最佳) |
UI 组件对用户代理无响应 | 组件未使用用户代理检测 | 确保组件检查 navigator.userAgent |
更改用户代理时,故事显示错误 | 时间或清理问题 | 重新加载故事或检查控制台中的错误 |
行为不一致 | 缓存或陈旧状态 | 清除浏览器缓存并重启 Storybook |
调试技巧
如果您在使用 UserAgent 插件时遇到问题:
- 检查浏览器控制台中是否存在错误
- 通过添加以下代码验证用户代理是否实际正在更改:
console.log(window.navigator.userAgent);
- 首先使用简单组件测试以隔离问题
- 尝试独立使用 UserAgent 插件(禁用其他插件)
实际应用场景
响应式设计测试
测试您的组件如何适应除屏幕尺寸以外的不同设备特性
// DeviceResponsiveMenu.jsx
import React from "react";
import { useUserAgent } from "./useUserAgent";
export function DeviceResponsiveMenu({ items }) {
const { isMobile, isTablet, isMacOS } = useUserAgent();
// Adapt menu based on device type
return (
<nav className={`menu ${isMobile ? "mobile-menu" : "desktop-menu"}`}>
{items.map((item) => (
<MenuItem
key={item.id}
item={item}
useShortText={isMobile}
useTouchOptimized={isMobile || isTablet}
useNativeControls={isMacOS}
/>
))}
</nav>
);
}
浏览器特定功能检测
根据浏览器能力有条件地启用功能
function BrowserOptimizedVideo({ src }) {
const userAgent = window.navigator.userAgent;
const isSafari = /^((?!chrome|android).)*safari/i.test(userAgent);
return (
<video
src={src}
controls
playsInline={isSafari} // Safari-specific attribute
format={isSafari ? "hls" : "dash"} // Different format based on browser
/>
);
}
更新日志
我们维护所有版本和更新的详细更新日志
贡献
欢迎贡献!请随时提交 Pull Request。
报告问题
如果您遇到兼容性问题:
- 请检查您使用的插件版本是否与您的 Storybook 版本兼容
- 更新到插件的最新补丁版本
- 在以下地址报告问题并提供您的环境详细信息:GitHub Issues