关于 acul-screen-generator
ACUL Screen Generator 是用于创建和修改 Auth0 ACUL 屏幕组件的引导式技能,可生成主题化界面。它支持 React 和 JavaScript 项目,并在 CLI 可用时使用脚手架;不支持的屏幕则参考 SDK 示例。
主要功能
- 01按九阶段工作流引导设置
- 02通过 CLI 搭建 ACUL 项目和屏幕
- 03生成模块化主题屏幕组件
- 04为 CLI 不支持的屏幕参考 SDK 示例
- 05验证构建并配置本地开发屏幕
适用场景
- 01创建包含指定屏幕的 ACUL 项目
- 02向现有项目添加屏幕
- 03修改现有屏幕的代码或样式
- 04排查构建和本地屏幕注册问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ auth0/ agent-skills --skill acul-screen-generator安装后在 Claude Code 中输入/acul-screen-generator确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/js-templates/login-id.jslogin-password.jsassets/react-templates/login-id.tsxlogin-password.tsxassets/theme-templates/globals.csstailwind.config.tstheme-provider.tstokens.cssreferences/acul-js-sdk.mdacul-react-sdk.mdcli-commands.mdscreen-catalog.mdsocial-providers.mdtheming-patterns.mdtests/evals.json详细介绍
ACUL Screen Generator
生成可用于生产环境、完全主题化的 Auth0 ACUL 屏幕组件。遵循严格的 9 阶段工作流(阶段 0–8):CLI 身份验证 → 意图检测 → 项目设置 → 屏幕需求 → 技术栈与设计 → 主题提取 → 结构化代码生成 → 构建验证与迭代修复 → 开发模式接线。
参考资料层级
始终按以下优先顺序为屏幕确定正确的参考资料。运行 CLI 前,检查 auth0-acul-samples 中是否存在该屏幕;如果不存在,CLI 将失败。
1. Check auth0-acul-samples availability first (gate for CLI usage)
→ Read `references/screen-catalog.md` for the Samples column
→ Verify the screen directory exists at:
React: https://github.com/auth0-samples/auth0-acul-samples/tree/main/react/src/screens/<screen-name>
React-JS: https://github.com/auth0-samples/auth0-acul-samples/tree/main/react-js/src/screens/<screen-name>
→ If the screen IS in samples → proceed to CLI (step 2)
→ If the screen is NOT in samples → skip CLI entirely, go to step 3
2. Auth0 CLI scaffolded code (only for screens confirmed in auth0-acul-samples)
→ Use `auth0 acul screen add` or `auth0 acul init` to generate screen code locally
→ The CLI produces the correct project structure, SDK imports, and hook patterns
→ If the CLI succeeds, use the scaffolded code as-is — do NOT fetch from GitHub
3. SDK examples (for screens NOT in auth0-acul-samples — do NOT attempt CLI for these)
→ Code snippets showing SDK imports, hooks, and action functions
→ React: https://github.com/auth0/universal-login/blob/master/packages/auth0-acul-react/examples/<screen-name>.md
→ JS: https://github.com/auth0/universal-login/blob/master/packages/auth0-acul-js/examples/<screen-name>.md
→ Determine if the example is React or JS, then adapt to match the project's framework
4. assets/react-templates/ or assets/js-templates/
→ Structural component pattern only — never use their hooks/actions for other screens
要查看 auth0-acul-samples 中包含哪些屏幕 → 阅读 references/screen-catalog.md。
auth0-acul-samples 架构
如果 auth0-acul-samples 中包含某个屏幕,请使用此模块化模式生成代码,而不是使用单体组件。
每个屏幕的目录结构:
<screen-name>/
├── index.tsx thin entry: wires manager hook + applies theme + renders layout
├── components/
│ ├── Header.tsx logo, title, subtitle from screen.texts
│ ├── <ScreenName>Form.tsx form fields, submit, captcha, passkey button
│ ├── Footer.tsx signup link, forgot password, back link
│ └── AlternativeLogins.tsx social login buttons (if screen has social)
├── hooks/
│ └── use<ScreenName>Manager.ts wraps SDK hooks, exposes clean handlers + feature flags
└── locales/
└── en.json fallback text strings
index.tsx 模式:
import { ULThemeCard, ULThemePageLayout } from '@/components'
import { applyAuth0Theme } from '@/utils/theme/themeEngine'
import Header from './components/Header'
import <ScreenName>Form from './components/<ScreenName>Form'
import Footer from './components/Footer'
import { use<ScreenName>Manager } from './hooks/use<ScreenName>Manager'
const <ScreenName>Screen = () => {
const { sdkInstance, texts, locales } = use<ScreenName>Manager()
applyAuth0Theme(sdkInstance)
document.title = texts?.pageTitle ?? locales.pageTitle
return (
<ULThemePageLayout>
<ULThemeCard>
<Header texts={texts} />
<AlternativeLogins alignment="top" /> {/* conditional */}
<<ScreenName>Form />
<Footer texts={texts} links={links} />
<AlternativeLogins alignment="bottom" /> {/* conditional */}
</ULThemeCard>
</ULThemePageLayout>
)
}
export default <ScreenName>Screen // REQUIRED: screenLoader registers via lazy(), which needs a default export
index.tsx必须包含export default。 项目的屏幕注册表(src/utils/screen/screenLoader.ts)会使用lazy(() => import('@/screens/<screen-name>'))加载每个屏幕,而React.lazy会解析模块的 默认 导出。仅使用命名导出(export const <ScreenName>Screen)虽然可以成功编译,但运行时会显示空白页面或“屏幕未实现”。请参阅阶段 6 中的“屏幕注册”。
hooks/use<ScreenName>Manager.ts 模式:
import { useLoginId, useScreen, useTransaction } from '@auth0/auth0-acul-react/<screen-name>'
import { executeSafely } from '@/utils/helpers/executeSafely'
import locales from '../locales/en.json'
export const use<ScreenName>Manager = () => {
const sdkInstance = useLoginId() // screen-specific SDK hook
const screen = useScreen()
const { alternateConnections } = useTransaction()
const handleSubmit = async (data) => executeSafely(() => login(data))
const handleFederatedLogin = async (conn) => executeSafely(() => federatedLogin({ connection: conn }))
return {
sdkInstance,
texts: screen.texts,
locales,
alternateConnections,
handleSubmit,
handleFederatedLogin,
isPasskeyEnabled: screen.isPasskeyEnabled,
isCaptchaAvailable: screen.isCaptchaAvailable,
}
}
如果 auth0-acul-samples 中不包含某个屏幕,且 CLI 不支持该屏幕,则回退到基于 SDK 示例的单文件组件。
前提条件
- 已安装 Auth0 CLI:
brew install auth0 - 已在 Auth0 租户上配置自定义域名(ACUL 的硬性要求)
- Node.js ≥ 22(Auth0 CLI 生成的 ACUL 项目需要此版本)
阶段 0:环境验证与 CLI 身份验证
步骤 1 — 检查 Node.js 版本
node --version 2>&1
解析输出并确认主版本号为 ≥ 22。如果未安装 Node.js,或版本低于 22:
- **未安装:**停止并告知客户安装 Node.js 22+(例如,运行
nvm install 22,或从 nodejs.org 下载)。 - **版本 < 22:**停止并告知客户升级。例如:
nvm install 22 && nvm use 22。Auth0 CLI 生成的 ACUL 项目需要 Node.js 22+,在较旧版本上将无法构建或运行。
在确认 Node.js ≥ 22 之前,请勿继续任何后续阶段。
步骤 2 — CLI 身份验证与租户检查
auth0 login
auth0 acul config list --rendering-mode advanced
如果 auth0 acul config list 返回有关自定义域名的错误,请停止并告知客户:必须先在租户上配置自定义域名,才能使用 ACUL。
CLI 标志完整参考 → 阅读 references/cli-commands.md。
阶段 1:意图检测
询问客户需要哪种模式:
- A) 从头构建 — 新建项目、选择屏幕并进行完整设置
- B) 添加屏幕 — 在现有项目中添加一个或多个新屏幕
- C) 修改屏幕 — 更改现有项目中某个屏幕的代码或样式
此选择决定后续进入阶段 2A、2B 或 2C。
阶段 2A:从头开始 — 初始化项目
收集:应用名称、框架(react 或 js)、初始屏幕列表。
auth0 acul init <app_name> -t react -s login-id,login-password,signup
auth0 acul config generate <screen-name> # repeat per screen
确认项目目录中已创建 acul_config.json。
CLI 脚手架生成的代码是首选信息来源。 阅读生成的屏幕文件,了解项目结构、SDK 导入、钩子模式和组件布局。请勿从 GitHub 获取内容——CLI 输出是规范的起点。仅根据客户的需求(品牌塑造、额外组件等)定制或扩展生成的代码。
继续进入阶段 3。
阶段 2B:添加屏幕 — 首先检查示例是否可用
-
确认项目目录中存在
acul_config.json。- 如果不存在 → 停止。告知客户先运行
auth0 acul init。
- 如果不存在 → 停止。告知客户先运行
-
尝试使用 CLI 前,先检查 auth0-acul-samples 中是否包含该屏幕。 阅读
references/screen-catalog.md,并查看请求的屏幕对应的Samples (React)或Samples (React-JS)列。然后获取 GitHub 目录列表,确认该屏幕确实存在于预期路径:React: https://github.com/auth0-samples/auth0-acul-samples/tree/main/react/src/screens/<screen-name> React-JS: https://github.com/auth0-samples/auth0-acul-samples/tree/main/react-js/src/screens/<screen-name>此检查用于确定 CLI 能否搭建该屏幕。如果 auth0-acul-samples 中不存在该屏幕,CLI
auth0 acul screen add命令将会失败——因此请完全跳过该命令,直接进入步骤 4。 -
屏幕存在于 auth0-acul-samples 中 → 尝试使用 CLI:
auth0 acul screen add <screen-name> -d <project-dir>- 如果 CLI 成功 → 直接使用搭建生成的代码。 阅读生成的文件,了解结构、SDK 导入方式和钩子模式。不要从 GitHub 获取代码。根据客户的需求(品牌风格、组件等)自定义 CLI 生成的代码。然后进入阶段 3。
- 如果屏幕在示例中,但 CLI 报错(例如,身份验证问题、版本不匹配)→ 将其作为恢复路径,继续执行步骤 4。
-
屏幕不存在于 auth0-acul-samples 中(或 CLI 失败)→ 跳过 CLI,直接获取参考代码。
由于 CLI 不支持此屏幕,请勿尝试执行
auth0 acul screen add——该命令会报错。请改为根据参考代码构建屏幕。步骤 4a — 获取项目结构(如果尚不清楚): 如果这是首次手动添加屏幕(即你还没有从之前 CLI 生成的屏幕中了解项目的目录布局、配置连接方式和构建设置),请创建一个虚拟页面:
auth0 acul screen add login-id -d <project-dir>- 阅读生成的虚拟屏幕文件,了解项目结构、目录布局、配置连接方式和构建设置
- 然后移除虚拟屏幕文件(删除
login-id/屏幕目录)
如果你已通过之前 CLI 生成或手动创建的屏幕了解项目结构,请跳过此步骤。
步骤 4b — 获取屏幕参考代码: 检查项目文件,确定现有项目的技术栈(React 或 JS/Vanilla)。然后获取参考代码:
- React 项目 → 检查 universal-login 仓库中的 SDK 示例:
- 获取:
https://github.com/auth0/universal-login/blob/master/packages/auth0-acul-react/examples/<screen-name>.md - 解析以下内容:准确的导入路径、钩子模式(模式 A 或 B)、操作函数名称和负载结构
- 获取:
- JS/Vanilla 项目 → 检查 JS SDK 示例:
- 获取:
https://github.com/auth0/universal-login/blob/master/packages/auth0-acul-js/examples/<screen-name>.md - 解析以下内容:管理器类名称、方法名称和负载结构
- 获取:
确定示例是 React(JSX/TSX、钩子)还是纯 JS(基于类的管理器),并使其与项目的框架匹配。如果项目使用 React,但只有 JS 示例(反之亦然),请使用相应的 SDK 参考(
references/acul-react-sdk.md或references/acul-js-sdk.md)适配这些模式。步骤 4c — 使用项目结构生成屏幕文件,并填入步骤 4b 中的 SDK 参考数据。这样可以确保目录布局、配置集成和构建兼容性正确。如果使用 React,请遵循“auth0-acul-samples Architecture”部分中的模块化架构模式;如果示例足够简单,则使用单文件组件。
步骤 4d — 注册屏幕,以便本地开发模式能够解析该屏幕(必需)。 CLI 会自动注册其搭建的屏幕,但手动生成的屏幕不会注册——因此,即使文件存在且构建成功,
auth0 acul dev(本地模式)仍会显示 "Screen '' is not implemented"。(连接模式会从租户读取屏幕,因此无需此步骤也能正常工作——这就是此问题只会在本地开发中出现的原因。)屏幕通过src/utils/screen/screenLoader.ts中的SCREEN_COMPONENTS映射解析。首先确定项目如何维护该映射——不要假设它是手动编辑的:
- 检查
screenLoader.ts是否为自动生成文件。打开该文件,查找类似// Auto-generated file的标记,并检查package.json脚本中是否有生成器(例如generate:screenLoader)以及scripts/generate-screen-loader.js。- **如果存在生成器(CLI 脚手架项目中较常见):**加载器会通过扫描
src/screens/*/index.tsx,并与允许列表(例如src/constants/validScreens.js)进行比对后重新生成。**不要手动编辑screenLoader.ts,否则更改会被覆盖。**请改为:- 确认允许列表(
VALID_SCREENS)中包含<screen-name>。如果没有,请添加。 - 运行生成器:
npm run generate:screenLoader(使用package.json中的实际脚本名称)。 - 确认新条目现在已出现在
screenLoader.ts中。
- 确认允许列表(
- **如果不存在生成器:**直接手动编辑
SCREEN_COMPONENTS映射:"<screen-name>": lazy(() => import("@/screens/<screen-name>")),
- **如果存在生成器(CLI 脚手架项目中较常见):**加载器会通过扫描
- 无论哪种情况,都要确认屏幕的
index.tsx有一个默认导出(export default <ScreenName>Screen)——lazy()会解析默认导出。只有具名导出虽然能通过编译,但加载后会显示空白或“未实现”。
所有屏幕名称及其可用情况 → 请阅读
references/screen-catalog.md。
阶段 2C:修改屏幕 — 获取当前状态
-
确认
acul_config.json存在。 -
获取当前渲染配置:
auth0 acul config get <screen-name> -f <screen-name>.json auth0 acul config list --rendering-mode advanced -
从客户的代码库中读取现有屏幕文件。**本地代码是你的首要参考。**进行任何更改前,先了解其当前结构、SDK 导入和钩子模式。
-
仅当本地代码缺少关键 SDK 模式(例如钩子模式错误、缺少操作函数),且无法从现有代码库中确定正确模式时,才从 GitHub 参考资料中获取信息。使用参考资料层级(样例可用性 → 支持时使用 CLI 脚手架代码 → SDK 示例)进行验证。
阶段 3:屏幕需求
向客户了解:
- 屏幕类型 — 完整的可用屏幕列表 → 请阅读
references/screen-catalog.md - 所需组件:
- 社交平台提供商:Google、GitHub、Apple、Microsoft、Facebook
- 表单字段:邮箱、用户名、电话、密码、确认密码
- MFA 类型(如适用):OTP、短信、推送、WebAuthn
- 可选附加项:验证码、通行密钥按钮、记住我、条款复选框
- **修改模式:**需要具体更改什么(布局、颜色、添加/移除组件)
阶段 4:技术栈检测
确认或检测:
- **框架:**React(
@auth0/auth0-acul-react)或 JS(@auth0/auth0-acul-js) - **样式库:**Tailwind CSS / CSS Modules / styled-components / 纯 CSS
- **是否已有主题文件?**检查
tailwind.config.ts、styles/tokens.css、theme/index.ts
加载相应的 SDK 参考资料:
- React → 请阅读
references/acul-react-sdk.md - JS → 请阅读
references/acul-js-sdk.md
社交按钮的实现方式 → 请阅读 references/social-providers.md。
阶段 5:提取主题并确定范围
设计输入 — 检测客户提供的内容:
选项 A — 图片或样稿(jpeg / png / 截图): 分析图片并提取:
- 主色、辅助色、强调色(十六进制值)
- 背景色和卡片/表面颜色
- 字体系列和字重
- 边框圆角样式(锐利 / 微圆角 / 圆角 / 药丸形)
- 间距节奏(紧凑 / 常规 / 宽松)
- 布局类型:居中卡片 / 全幅铺满 / 分栏面板 / 浮动卡片
选项 B — 仅提供品牌颜色(无图片): 根据提供的十六进制值推导完整的令牌集:
primary → button bg, links, focus ring
primary-hover → primary darkened ~10%
primary-text → white if primary is dark, else #111827
background → page background
surface → card/panel background
text-primary → headings (#111827 light / #F1F5F9 dark)
text-secondary → labels, placeholders
border → input borders
error → #EF4444 (unless specified)
success → #22C55E (unless specified)
主题范围 — 询问客户:
- 单个屏幕: 将令牌内联应用于此组件的样式
- 所有屏幕: 先生成共享主题文件,然后将其一致地应用到每个屏幕
有关各样式库的主题文件模式 → 阅读 references/theming-patterns.md。
按样式库生成的主题文件(所有屏幕范围):
| 样式库 | 使用的模板 | 输出文件 |
|---|---|---|
| Tailwind | assets/theme-templates/tailwind.config.ts | tailwind.config.ts |
| CSS Modules | assets/theme-templates/tokens.css | styles/tokens.css |
| styled-components | assets/theme-templates/theme-provider.ts | theme/index.ts |
| Plain CSS | assets/theme-templates/globals.css | styles/globals.css |
将所有 {{TOKEN}} 占位符替换为提取的令牌值。
第 6 阶段:结构化代码生成
生成方式取决于屏幕代码的来源。
路径 A — CLI 搭建的屏幕(首选)
当 CLI 成功生成屏幕(通过 auth0 acul init 或 auth0 acul screen add)时,以 CLI 输出为基础。读取生成的文件,并根据客户需求进行定制:
- 将第 5 阶段的设计令牌应用于生成组件的样式
- 按照指定添加/移除组件(社交按钮、验证码、通行密钥等)
- 根据客户提供的设计输入调整布局和结构
- 保留 CLI 的 SDK 导入、钩子模式和操作函数 — 它们都是正确的
切勿丢弃 CLI 生成的代码,改为从 GitHub 参考重新生成。
路径 B — 来自 auth0-acul-samples 的屏幕(仅当 CLI 不支持该屏幕时)
使用 CLI 虚拟页面策略(第 2B 阶段,第 4a 步)中记录的项目结构作为基础。使用 samples 模式生成屏幕目录(参见上文“auth0-acul-samples 架构”),并匹配虚拟页面的目录布局和配置接线:
<screen-name>/
├── index.tsx
├── components/
│ ├── Header.tsx
│ ├── <ScreenName>Form.tsx
│ ├── Footer.tsx
│ └── AlternativeLogins.tsx (only if screen has social login)
├── hooks/
│ └── use<ScreenName>Manager.ts
└── locales/
└── en.json
index.tsx— 精简:调用use<ScreenName>Manager(),调用applyAuth0Theme(),渲染ULThemePageLayout→ULThemeCard→ 子组件use<ScreenName>Manager.ts— 封装 samples 参考中的 SDK 钩子,公开带类型的处理器和功能标志- 表单组件 — 使用 react-hook-form,从管理器钩子读取数据,不直接调用 SDK
- Header/Footer — 无状态,通过属性接收文本
en.json— 提供备用字符串,与screen.texts.*中使用的键匹配
将第 5 阶段的设计令牌应用于布局组件和表单组件样式。
路径 C — 屏幕不在 auth0-acul-samples 中(单文件组件)
使用 assets/react-templates/ 或 assets/js-templates/ 中的结构作为模式,生成单个 <screen-name>.tsx(React)或 <screen-name>.js(JS);钩子和操作完全取自第 2 阶段获取的 SDK 示例。
JSX 结构顺序:
Outer layout wrapper → Card/panel → Logo slot → Title (screen.texts) →
Error banner (conditional) → Form fields → Captcha (conditional) →
Submit button → Passkey button (conditional) → Social divider + buttons
(conditional on alternateConnections) → Footer links
屏幕注册(仅适用于 Path B 和 Path C)
CLI 会自动注册其生成的任何屏幕(Path A)。手动生成的屏幕(Path B、Path C)必须注册,否则本地运行 auth0 acul dev 时会显示 "Screen '' is not implemented",即使文件已存在且构建成功。(连接模式会从租户解析屏幕,因此无需此步骤也能正常运行——这也是该问题只会在本地开发时出现的原因。)屏幕通过 src/utils/screen/screenLoader.ts 中的 SCREEN_COMPONENTS 映射进行解析。
对于每个手动生成的屏幕:
- 先确认
screenLoader.ts的维护方式,不要假设它是手动编辑的。 如果文件带有// Auto-generated file标记,或package.json中有生成器脚本(例如由scripts/generate-screen-loader.js支持的generate:screenLoader),则它会通过扫描src/screens/*/index.tsx并与允许列表匹配来重新生成:- 确保
<screen-name>在允许列表中(例如src/constants/validScreens.js),然后运行npm run generate:screenLoader。不要手动编辑生成的文件——否则更改会被覆盖。 - 仅当不存在生成器时,才手动添加条目:
"<screen-name>": lazy(() => import("@/screens/<screen-name>")),
- 确保
- 确保屏幕的
index.tsx(或单文件组件)包含export default——React.lazy解析的是默认导出,而非命名导出。
输出任何代码前的验证
- SDK 导入路径与屏幕名称完全一致(例如,
@auth0/auth0-acul-react/mfa-otp-challenge) - Hook 模式(通用
useScreen()还是屏幕专用 Hook)应取自 CLI 生成的代码或参考资料,不要凭空假设 - Action 函数名称和负载结构应取自 CLI 生成的代码或参考资料
- 错误状态使用 SDK 源(
hasErrors/getErrors())——绝不能仅使用本地错误状态 - 不要硬编码 UI 字符串——使用
screen.texts.*并提供区域设置回退 - 使用模块化架构(Path A、Path B)时,在 index.tsx 中调用
applyAuth0Theme() - 手动生成的屏幕(Path B、Path C)必须在
src/utils/screen/screenLoader.ts中注册,并提供匹配的export default——这是本地运行auth0 acul dev的必要条件
所有屏幕范围: 对项目中的每个屏幕重复执行适用的 Path A、B 或 C,并确保所有屏幕都从共享主题文件导入。每条路径内的组件结构应保持一致。
第 7 阶段:构建验证与迭代修复
生成或修改屏幕代码后,务必先验证输出,再继续后续步骤。生成的代码可能包含错误的导入路径、错误的导入方式(默认导入还是命名导入)、无效的组件属性,或对不存在的导出的引用。本阶段会自动发现并修复这些问题。
步骤 1 — 安装新依赖(如有)
如果生成或修改的代码在 package.json 中引入了新依赖(即 dependencies / devDependencies 下的条目尚未安装在 node_modules 中),请先在项目根目录运行 npm install,再执行 lint 或构建。如果没有新增软件包,则跳过此步骤。
# Run from the project root
npm install
如果安装失败(依赖冲突、注册表错误、版本不匹配),请将错误告知客户并停止操作——问题解决前不要继续执行 lint 或构建。
步骤 2 — 运行 lint
运行项目的 linter,以发现导入错误、类型不匹配和无效属性:
# Detect the lint command from package.json scripts
npm run lint 2>&1 || npx eslint src/screens/<screen-name>/ --ext .ts,.tsx,.js,.jsx 2>&1
如果项目使用 TypeScript,还要运行类型检查器:
npx tsc --noEmit 2>&1
步骤 3 — 运行构建
npm run build 2>&1
步骤 4 — 解析错误并迭代修复
如果 lint 或构建产生错误,请解析每条错误并应用适当的修复:
| 错误模式 | 根本原因 | 修复方法 |
|---|---|---|
does not have a default export | 对命名导出使用了 import X | 改为 import { X } |
has no exported member | 导入的符号在模块中不存在 | 阅读源模块,找到正确的导出名称 |
Module not found / Cannot find module | 导入路径错误 | 从 node_modules 或项目自身的源代码树中确认正确路径 |
Property 'X' does not exist on type | 传递给组件的属性无效 | 阅读组件的类型定义或源代码,找到有效属性 |
is not assignable to type | 属性类型不匹配 | 转换类型或转换值,使其符合预期类型 |
JSX element type 'X' does not have any construct or call signatures | 组件导入错误或组件不存在 | 确认组件存在,并已从其模块正确导出 |
修复工作流:
- 阅读错误输出——找出文件、行号和错误代码。
- 阅读错误位置处的源文件,了解上下文。
- 如果错误涉及导入——阅读目标模块(来自
node_modules或项目源代码),找到正确的导出名称和路径。 - 应用修复。
- 重新运行
npm run build 2>&1。 - 从步骤 1 开始重复,直到构建成功。
迭代上限: 严格限制为 5 次迭代。如果错误陷入停滞(连续 2 次迭代出现相同错误数量或相同错误),请立即停止,不要继续迭代。达到上限后若仍有错误,请将剩余错误告知客户并征求指导,不要继续修改代码。
此阶段会发现的常见问题
- 文件使用
export const Component(命名导出)时,却写成import Component from './Component'——修复:改为import { Component } from './Component' - 使用
import { useLoginId } from '@auth0/auth0-acul-react',而不是特定屏幕的路径@auth0/auth0-acul-react/login-id——修复:使用正确的子路径导入 - 使用
<ULThemeCard title={...}>,但ULThemeCard不接受title属性——修复:移除无效属性,改用<Header>子组件 - 从项目中不存在的路径导入主题工具——修复:确认项目目录树中的实际路径
- 将
applyAuth0Theme作为命名导入使用,但它实际上是默认导出(或反之)——修复:匹配模块的实际导出方式
构建无法捕获的运行时检查:未注册的屏幕
npm run build 成功并不能保证手动添加的屏幕能在本地开发环境中渲染。构建会通过,但当出现以下情况时,auth0 acul dev 会显示 "Screen '' is not implemented":
src/utils/screen/screenLoader.ts中的SCREEN_COMPONENTS映射表缺少该屏幕,或- 屏幕的
index.tsx没有export default(因此lazy()无法解析组件)。
对于通过路径 B 或路径 C 生成的每个屏幕,请在结束前验证以上两项。这是运行时/注册环节的遗漏,并非编译错误——lint 和 tsc 不会报告此问题。如果项目会自动生成 screenLoader.ts,请通过其生成器(npm run generate:screenLoader)完成注册,不要手动编辑。(参见阶段 6 中的“屏幕注册”。)
验证成功
构建以 退出代码 0 完成且没有 lint 错误,并且每个手动添加的屏幕都已在 screenLoader.ts 中注册且带有 export default 后,继续执行阶段 8。
阶段 8:开发模式接线
向客户提供可直接运行的命令:
# Local preview — no tenant connection needed
auth0 acul dev -p 3000 -d <project-dir>
# Connected mode — syncs assets to tenant (stage/dev only)
auth0 acul dev --connected -s <screen-name> -d <project-dir>
⚠️ 建议使用连接模式时,务必附上以下警告:
连接模式会实时更新你的 Auth0 租户。仅在暂存或开发租户上使用此模式,切勿用于生产环境。
参考文件
| 文件 | 加载时机 |
|---|---|
references/acul-react-sdk.md | 框架为 React |
references/acul-js-sdk.md | 框架为 JS / Vanilla |
references/screen-catalog.md | 选择屏幕类型或触发 CLI 回退时 |
references/social-providers.md | 需要社交登录按钮时 |
references/theming-patterns.md | 生成或应用共享主题文件时 |
references/cli-commands.md | 需要完整的 CLI 标志详情时 |
资源模板
| 文件 | 使用时机 |
|---|---|
assets/theme-templates/tailwind.config.ts | Tailwind,所有屏幕范围 |
assets/theme-templates/tokens.css | CSS Modules,所有屏幕范围 |
assets/theme-templates/theme-provider.ts | styled-components |
assets/theme-templates/globals.css | 纯 CSS,所有屏幕范围 |
assets/react-templates/<screen>.tsx | React 组件样板基础 |
assets/js-templates/<screen>.js | JS 组件样板基础 |