@buoy-gg/angular

中文文档
7.0.87发布于 2026/11/07TypeScriptES Module近 30 天下载 3593

Run Buoy in an Angular app.

原始使用文档
文档目录10 节
  1. Install and sign in
  2. What ng add writes
  3. QA builds
  4. NgRx Store
  5. NGXS
  6. Router, Query, and Highlight
  7. Angular 19 and custom builders
  8. Other stores and phone apps
  9. App options
  10. Manual setup

Buoy for Angular

Let your coding agent install Buoy. Copy the Angular install prompt. Its guide is install-angular.md. Watch the trailer on the Angular page.

Buoy runs in Angular as a beta. It starts after the first view, outside Angular's zone. It stops with the app and skips the server. Your app keeps its Angular views and state. Buoy uses React for its own UI.

Install and sign in

Run these from your app folder:

ng add @buoy-gg/angular
npx --package=@buoy-gg/core buoy login
ng serve

Pick the tools you want in the prompt. Network, Console, Storage, Events, and Env start checked. The prompt also checks tools that fit the app:

  • Routes if the app has Angular Router.
  • Query if it has Angular Query.
  • Redux if it has NgRx or NGXS.
  • Highlight on Angular 20 or newer.

React, React DOM, and RN Web come with Buoy. Use the same version for all Buoy packages. To add a tool later, install its Buoy package. Restart ng serve to load the new list. The server prints a restart note when that list changes. A second ng add run leaves your files alone.

For more than one app, choose it by name:

ng add @buoy-gg/angular --project my-app
npx --package=@buoy-gg/core buoy login --project my-app

Login writes src/environments/buoy.ts under the app's source root. The builder reads its BUOY_KEY for you. Login also writes an env file for local Buoy tools. It adds both files to .gitignore. Do not commit them. Dev tokens and free keys keep a dev guard in the key file. Each person signs in with their own account.

What ng add writes

In angular.json, it changes two builder names:

{
  "build": {
    "builder": "@buoy-gg/angular:application"
  },
  "serve": {
    "builder": "@buoy-gg/angular:dev-server"
  }
}

Keep each target's other fields and build configs. ng add keeps those fields when it makes the change. It adds this call last in app.config.ts:

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideBuoy } from '@buoy-gg/angular';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    // Keep the app's other providers here.
    provideBuoy(),
  ],
};

For NgModule apps, it puts the call last in @NgModule.providers. The builder adds the light hook before the app starts. That lets Network see calls from the first app initializer. It loads all installed tools. You need no buoy.ts list. You need no Buoy guard or prod condition here.

Prod swaps Buoy for a small, empty provider. The host, tools, React DOM, and RN Web stay out. NgRx DevTools needs its own dev guard, shown below. SSR and prerender builds keep Buoy out of server code. Watch builds use the same rules.

QA builds

To keep Buoy in a QA build, set this build option:

{
  "buoy": { "release": true }
}

Put it in the QA config under build.configurations. It keeps the browser tools and turns on the early hook. The server bundle still uses the empty provider. For release access, your team signs in with Buoy. Add your site at buoy.gg/dashboard/sites. Then pass provideBuoy({ signIn: true }). A paid key works too, as a backup. Your app's access rules and plan still apply. Dev tokens and free keys from login stay out of prod code. NgRx, NGXS, and Highlight still need Angular dev mode.

NgRx Store

Keep your normal store and effects setup. Add @ngrx/store-devtools and select the Redux tool. Keep NgRx DevTools in a dev guard. Put provideBuoy() last in the provider list:

import { provideStoreDevtools } from '@ngrx/store-devtools';
import { provideBuoy } from '@buoy-gg/angular';

declare const ngDevMode: boolean | undefined;

// At the end of the app's providers:
(typeof ngDevMode === 'undefined' || ngDevMode)
  ? provideStoreDevtools({ maxAge: 50 })
  : [],
provideBuoy(),

No extra NgRx bridge call is needed with the builder. Buoy provides REDUX_DEVTOOLS_EXTENSION through DI. It never claims window.__REDUX_DEVTOOLS_EXTENSION__. If another provider wins, dev builds print this warning:

[Buoy] NgRx has no Buoy link. Move provideBuoy() last in providers.

The tool shows actions, state, and diffs. Replay adds a new row. Jump restores the chosen state. A state jump may take one second. The guard keeps NgRx DevTools out of prod. logOnly alone still ships that code. Old setups can keep provideBuoyNgRx() after provideStoreDevtools().

NGXS

Select the Redux tool and keep the app's NGXS store. NGXS still needs its own adapter call:

import { provideBuoy } from '@buoy-gg/angular';
import { provideBuoyNgxs } from '@buoy-gg/angular/ngxs';

declare const ngDevMode: boolean | undefined;

// At the end of the app's providers:
(typeof ngDevMode === 'undefined' || ngDevMode)
  ? provideBuoyNgxs()
  : [],
provideBuoy(),

This uses NGXS_PLUGINS through DI. It needs no browser global or @ngxs/devtools-plugin. We tested NGXS 22 with RxJS 7.8. Use one adapter. Do not mix NgRx and NGXS bridges. Jump calls Store.reset. Replay calls Store.dispatch. Async actions show when they end. Errors still reach NGXS. Canceled actions with no result add no row.

Router, Query, and Highlight

With the builder, provideBuoy() links these tools through DI. Routes reads the app's Router and route list. Go asks for id in a path like /pokemon/:id. Lazy child routes show once the app loads them.

Query uses the app's Angular Query client. Keep your normal provideTanStackQuery(queryClient) call. When you choose Query, ng add adds @tanstack/react-query. Buoy's UI needs that peer next to @buoy-gg/react-query. Match its version to @tanstack/angular-query-experimental. Both must resolve the same @tanstack/query-core version and copy. Check with pnpm why @tanstack/query-core or npm ls @tanstack/query-core. Split copies can break types or the offline switch. Keys, data, and refetch all use the app's client.

Highlight draws boxes and counts checks for each view. It needs Angular 20 or newer and the dev hook. Missing hooks show "Not in this app." Buoy leaves other hooks in place and stops its own. Counts are view checks, not paints or DOM writes. The list holds up to 200 views. It does not give React's cause or timing data. The hook is private API. Check it on Angular upgrades.

Angular 19 and custom builders

The Buoy builders work with CLI 19, 20, 21, and 22. Fresh app runs cover 19, 20, and 22. CLI 21 was checked from its types and schema. Highlight stays off on Angular 19.

CLI 19 has no conditions option. The Buoy builder does its own prod swap on that CLI. A fresh CLI 19 app may use @angular-devkit/build-angular. ng add keeps that builder and writes the manual setup.

The same rule applies to custom builders and Nx targets. ng add reads the targets in angular.json. It only swaps @angular/build builder names. For other builders, it prints why it kept them. It writes the hook, tool list, dev guard, and prod config. CLI 20+ gets the buoy-disabled condition. Check that your custom builder accepts conditions. If it does not, use entry file swaps instead. CLI 19 and webpack get entry file swaps instead. The tool list gets a prod file swap too. Keep manual app links for Router, Query, and state tools. For Nx layouts with no angular.json, use manual setup.

Other stores and phone apps

Vanilla Zustand stores need named store objects. Pass zustandStores: { ui: uiStore } in app options. Install the Zustand tool. The builder finds it. It shows state, changes, diffs, and edits.

SignalStore has no Buoy DI feature yet. Do not use the NgRx bridge for SignalStore. A Signals view is planned. It has not shipped. It would show signals used by the current page. It cannot list every signal in an app. Jotai needs an app with Jotai state.

Angular 22 uses fetch for HttpClient by default. Use provideHttpClient(withXhr()) if the app needs XHR. For Ionic Angular phones, see the Capacitor guide. Desktop links and phone boot hooks still need their own setup.

App options

Options add to the setup the builder finds. Keep the Buoy call last in the provider list. Pass an object, or a factory that calls inject():

provideBuoy({ zustandStores: { ui: uiStore } }),

// Or use a factory for app services:
provideBuoy(() => ({ queryClient: inject(QueryClient) })),

Choose one call. Do not use both. The factory runs once in the app's DI context. It can read the store with inject(Store) too. Router, Query, Highlight, and NgRx still get their links. The builder still loads each installed tool. Custom apps and a test broker work here too.

The merge rules are:

  • App keys replace auto keys. Your queryClient wins.
  • load() adds its keys last, after the app options.
  • Lists and nested objects replace the whole value. This includes apps, zustandStores, and externalSync.
  • links merges by tool id. Your link wins for that id. Each link runs after render and returns a stop function. Buoy calls each stop on teardown, plus your onDestroy.
  • An explicit modules map or loader turns auto off. It keeps the manual path below, with your own links.

To use your own Routes link, pass this in the options:

links: {
  'route-events': async () => {
    const { connectBuoyRouter } = await import('@buoy-gg/angular/router');
    return zone.runOutsideAngular(() =>
      connectBuoyRouter(router, fn => zone.run(fn)),
    );
  },
},

Get router and zone with inject() in the factory. This replaces just the Routes link. Highlight stays on. Use highlight-updates to replace that link too. For lazy app settings, let load() return mount options. Leave out modules to keep the builder's tool list. The loader and link callbacks run outside the zone. They run later, so call inject() in the factory.

Manual setup

Use this path when you pass your own tool list. Existing provideBuoy({ modules, ... }) calls still work. A factory, provideBuoy(() => options), can call inject(). load can return all mount settings at once. onDestroy stops app hooks; onMount gets the stop function. An explicit modules map or loader selects this path. With the builder, other options keep the auto links.

Put the light hook first in src/main.ts:

import '@buoy-gg/angular/register';

Do not use the React inspector hook from @buoy-gg/core/web/register. Make a tool list, then pass it behind a dev guard:

// src/buoy.ts
import { BUOY_KEY } from './environments/buoy';
export const buoyOptions = {
  licenseKey: BUOY_KEY,
  modules: async () => ({
    network: await import('@buoy-gg/network/web'),
  }),
};
// src/app/app.config.ts
import { provideBuoy } from '@buoy-gg/angular';
import { buoyOptions } from '../buoy';

declare const ngDevMode: boolean | undefined;

// Last in the app's providers:
(typeof ngDevMode === 'undefined' || ngDevMode)
  ? provideBuoy(buoyOptions)
  : [],

For CLI 20+ esbuild builders that accept conditions, use:

{
  "conditions": ["buoy-disabled", "module", "production"],
  "fileReplacements": [
    { "replace": "src/buoy.ts", "with": "src/buoy.prod.ts" }
  ]
}
// src/buoy.prod.ts
export const buoyOptions = {};

Keep both the guard and the file swap. A runtime isDevMode() check alone leaves tool chunks. For CLI 19 or webpack, let ng add write entry swaps. Or use prod entry and config files with no Buoy imports. Keep the app's own providers in those prod files.

In a manual loader, use these app links as needed:

ToolManual link
RoutesCall connectBuoyRouter(router, fn => zone.run(fn)) from @buoy-gg/angular/router. Stop it in onDestroy.
HighlightCall connectBuoyHighlights(module.HighlightUpdatesController, fn => zone.runOutsideAngular(fn)) from @buoy-gg/angular/highlights. Stop it in onDestroy.
NgRxPut provideBuoyNgRx() after NgRx DevTools, inside the same dev guard.
QueryPass the app's queryClient and the 'react-query' module.
ZustandPass zustandStores and the zustand module.

Manual QA builds also need enableInRelease: true. Keep their app guard true and omit the prod swaps. Start registerBrowserNetwork({ enableInRelease: true }) from the light hook entry. A Desktop link needs externalSync: { enableInRelease: true } too. Keep that flag in the settings returned by load. Remote phone checks may need these calls before tools open: bootLifecycle(), installLocationAdapters(), installPermissions(), and installCapacitorNotificationCapture({ enableInRelease: true }). Use only the modules installed in that app.

版本与发布记录

@buoy-gg/angular 共发布 25 个版本,首次发布于 2026/10/09;过去 12 个月发布了 25 个版本。

版本发布日期距今
7.0.87latest2026/11/071 天前
7.0.862026/11/062 天前
7.0.852026/11/053 天前
7.0.842026/11/035 天前
7.0.832026/11/035 天前
7.0.822026/11/036 天前

关于 @buoy-gg/angular 的常见问题

@buoy-gg/angular 是什么?

Run Buoy in an Angular app.

如何安装 @buoy-gg/angular?

在项目目录运行 npm install @buoy-gg/angular,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@angular/core(>=19 <23)、@angular/common(>=19 <23)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@buoy-gg/angular 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@buoy-gg/angular 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@buoy-gg/angular 可以商用吗?

@buoy-gg/angular 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@buoy-gg/angular 的下载量有多少?

根据 npm 官方下载统计,@buoy-gg/angular 在 2026/10/09 – 2026/11/07 这 30 天内被下载 3,593 次,日均约 120 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@buoy-gg/angular 还在维护吗?

最新版本 7.0.87 发布于 2026/11/07(1 天前);至今共发布 25 个版本,其中过去 12 个月发布了 25 个;首次发布于 2026/10/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。