跳转到内容

Environment

Environment 用来只读识别当前运行环境、操作系统和可用的 Web 平台能力。

快速开始

ts
import { createEnvironment } from '@freenotes/web-runtime';

export const environment = createEnvironment();

if (environment.supports('indexedDB')) {
  // 可以创建 DB capability;实际操作仍需要处理失败。
}

也可以从独立入口导入:

ts
import { createEnvironment } from '@freenotes/web-runtime/environment';

环境结果

ts
environment.runtime;
// 'browser' | 'webview' | 'worker' | 'server' | 'unknown'

environment.os;
// 'ios' | 'android' | 'macos' | 'windows' | 'linux' | 'unknown'

environment.secureContext;
environment.capabilities.clipboardWrite;

createEnvironment() 会综合 host adapter 与标准环境探测,返回最终的 Environment 结果。Environment 和 capabilities 都不可变,不会注册全局监听。能力值是创建时的快照;宿主或权限环境变化后,需要重新调用 createEnvironment() 获取新快照。创建时不写存储、不申请权限,也不打开数据库。

支持的 capability

ts
environment.supports('localStorage');
environment.supports('sessionStorage');
environment.supports('indexedDB');
environment.supports('clipboardRead');
environment.supports('clipboardWrite');
environment.supports('webCrypto');
environment.supports('cacheStorage');
environment.supports('serviceWorker');
environment.supports('webShare');
environment.supports('bridge');

supports() 只表示对应 API 存在且可以进行基础访问,不表示权限已经授予,也不保证具体调用一定成功。例如 Clipboard 写入仍可能因为非安全上下文、缺少用户手势或宿主策略而失败。

WebView host adapter

通用库无法可靠地只用 User-Agent 判断 WebView。客户端容器应注入自己掌握的宿主信息:

ts
import { createEnvironment, type EnvironmentHostAdapter } from '@freenotes/web-runtime';

const host: EnvironmentHostAdapter = {
  detect() {
    if (!clientBridgeAvailable()) {
      return null;
    }

    return {
      runtime: 'webview',
      os: getClientPlatform(),
      capabilities: {
        bridge: true
      }
    };
  }
};

export const environment = createEnvironment({ host });

host adapter 只需要返回能够确认的信息。它的结果优先级最高,因此完整的识别顺序是:host adapter(可指定 webview)→ browser → worker → server → unknown。adapter 抛出异常时,Environment 会回退到标准环境探测。

SSR

仅 import Environment 不读取浏览器全局对象。在 Node.js 或 SSR 中调用 createEnvironment() 也不会抛错:

ts
const environment = createEnvironment();

environment.runtime; // 'server'
environment.os; // 'unknown'
environment.supports('indexedDB'); // false

server 仅表示代码当前运行在 SSR 的服务端阶段,不表示 Web Runtime 提供 Node.js、数据库或文件系统能力。它可用于在服务端渲染时跳过浏览器能力初始化,并与 hydration 后的 browser 环境明确区分。

Web Worker

在 Web Worker 中,runtimeworker。Environment 会继续探测 Worker 中实际存在的 Web API:

ts
const environment = createEnvironment();

environment.runtime; // 'worker'
environment.supports('indexedDB'); // 取决于当前 Worker 环境
environment.supports('cacheStorage'); // 取决于当前 Worker 环境
environment.supports('localStorage'); // false

职责边界

Environment 不负责:

  • 权限查询和权限申请
  • 页面可见性、online/offline 或前后台监听
  • app version、device id 和用户标识
  • 屏幕尺寸和安全区域
  • 浏览器品牌及精确版本

动态状态由业务自己的事件监听和状态管理负责;需要更新环境判断时重新调用 createEnvironment()。业务和客户端信息通过业务自己的 context 或 adapter 管理。

让基础能力保持简单,让业务开发更加专注。