npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

nb-web-cli

v0.0.21

Published

基于 Next.js 16的前端脚手架 nb-web-cli

Readme

nb-web-cli

基于 Next.js 16 App Router 的前端脚手架。通过命令行一键创建项目模板并安装依赖。

前置准备

  • Node.js >= 20.9
  • npm 镜像源:需配置为公司私有源
npm config set registry https://registry.npmjs.org

使用方式

# 全局安装(或 npx 直接运行)
npm install -g nb-web-cli

# 创建新项目(在当前空目录,自定义项目名称为 my-project)
nb-web-cli my-project

# 创建新项目(在当前空目录,项目名称取当前目录名称)
nb-web-cli

# 跳过依赖安装
nb-web-cli my-project --no-install

# 指定包管理器
nb-web-cli my-project --package-manager pnpm

创建完成后,项目中所有 nb-web-demo 占位符(包名、basePath 路由前缀等)会被替换为指定的项目名称。

本地开发(维护脚手架)

# 1. 安装 CLI 依赖(根目录)
npm install

# 2. 安装模板依赖并启动(packages/ 必须单独 install)
cd packages && npm install && npm run dev

# 或在 packages/ 已 install 的前提下,根目录执行:
npm run dev

# 3. 本地联调 CLI
npm link
mkdir /tmp/test && cd /tmp/test
nb-web-cli

详细文档

下文为完整的脚手架使用指南。


nb-web-cli 脚手架使用指南

本文档参照 Next.js 官方文档 的 App Router 学习路径,结合模板样例(默认 basePath 为 /nb-web-demo),说明脚手架的整体设计与日常开发方式。


目录

  1. CLI 初始化项目
  2. 快速开始
  3. 项目结构
  4. 路由(Routing)
  5. 布局与页面(Layouts & Pages)
  6. 服务端与客户端组件
  7. 数据获取
  8. 特殊文件:Loading / Error / Not Found
  9. Proxy 与开发代理
  10. 环境变量
  11. 全局状态(Zustand)
  12. 用户鉴权
  13. 构建与部署
  14. 样例页面走读
  15. 新建业务模块 Checklist

0. CLI 初始化项目

命令说明

| 命令 | 场景 | 项目名来源 | 文件写入位置 | |------|------|-----------|-------------| | nb-web-cli | 已 cd 进入空目录 | 当前文件夹名 | 当前目录 | | nb-web-cli my-app | 已 cd 进入空目录 | 参数 my-app | 当前目录 | | nb-web-cli my-app --no-install | 同上,跳过依赖安装 | 参数 my-app | 当前目录 | | nb-web-cli my-app -p pnpm | 指定 pnpm 安装依赖 | 参数 my-app | 当前目录 |

注意: 两种模式都是在当前空目录内初始化,不会在父目录下额外创建子文件夹。目录名本身需符合 npm 包名规范(小写、无空格等)。

初始化流程

  1. 进入空目录
  2. 执行 nb-web-cli
  3. 复制 packages/ 模板到当前目录
  4. 替换 nb-web-demo 占位符(basePath、包名、Proxy 匹配等)
  5. npm install(可用 --no-install 跳过)
  6. npm run dev

占位符替换范围

初始化时,所有 nb-web-demo 会被替换为指定项目名,包括但不限于:

| 类型 | 示例 | |------|------| | 包名 | package.json → "name": "my-app" | | 路由前缀 | _constants/urls.ts → basePath = '/my-app' | | Next.js basePath | next.config.ts → basePath: '/my-app' | | Proxy 匹配 | proxy.ts → matcher: ['/my-app/:path*'] | | 构建产物 | build/my-app.tar.gz | | 部署配置 | Jenkinsfile 中的 name 字段 |

典型用法

# 方式一:目录名即项目名
mkdir my-project && cd my-project
nb-web-cli
npm run dev

# 方式二:自定义项目名(目录名可以不同)
mkdir workspace && cd workspace
nb-web-cli my-app
npm run dev

1. 快速开始

对应官方文档:Installation

Next.js 16.2.4

环境要求

  • Node.js >= 20.9
  • npm / pnpm / yarn

安装与启动

终端用户(已通过 CLI 创建的项目):

# 若初始化时使用了 --no-install,需先安装依赖
npm install

# 本地开发(默认 dev 环境)
npm run dev

脚手架维护者(本仓库):

# 根目录:安装 CLI 依赖
npm install

# packages/:安装模板依赖并启动
cd packages && npm install && npm run dev

# 或在根目录(需 packages/ 已 npm install)
npm run dev

启动后访问 https://localhost:3000/nb-web-demo(初始化后则为 https://localhost:3000/<你的项目名>)。模板通过 Next.js basePath 配置路由前缀,无需额外的根路径重定向。

开发端口与 HTTPS

默认情况下,npm run dev 使用 HTTPS(自签名证书,浏览器首次访问需信任)、监听 3000 端口,对应 package.json 中的脚本为:

"dev": "cross-env RUNTIME_ENV=dev next dev --experimental-https"

如需自定义,修改 package.json 的 scripts.dev 即可。

指定端口

通过环境变量 PORT 或 Next.js 的 -p 参数:

"dev": "cross-env RUNTIME_ENV=dev PORT=4000 next dev --experimental-https"
"dev": "cross-env RUNTIME_ENV=dev next dev -p 4000 --experimental-https"

启动后访问 https://localhost:4000/nb-web-demo。

改用 HTTP

去掉 --experimental-https 即可:

"dev": "cross-env RUNTIME_ENV=dev next dev"

启动后访问 http://localhost:3000/nb-web-demo。

常用脚本

| 命令 | 说明 | |------|------| | npm run dev | 开发模式,RUNTIME_ENV=dev,启用 API 代理 | | npm run build | SPA 静态导出(qa + prd 双环境),打包为 build/*.tar.gz | | npm run build:spa | 同 npm run build | | npm run build:ssr | SSR 生产构建,产物在 .next/ | | npm run start | 启动 SSR 生产服务(需先执行 build:ssr) | | npm run clean | 清理 .next / dist / build / .spa-staging | | npm run deploy | 同 npm run build,供 CI / pack_frontend.sh 调用 | | npm run gen:nginx -- <port> | 根据模板生成 QA / PRD 两套 nginx 配置到 nginx/ | | npm run lint | ESLint 检查 |


2. 项目结构

对应官方文档:Project Structure

脚手架仓库结构

维护模板时,代码位于 packages/ 目录:

nb-web-cli/                       # 脚手架仓库(CLI 包)
├── bin/index.mjs                 # CLI 入口
├── scripts/constants.mjs         # 占位符与复制规则
├── package.json                  # name: nb-web-cli
└── packages/                     # Next.js 模板(维护入口)
    ├── app/
    │   ├── layout.tsx            # 根布局
    │   ├── error.tsx             # 全局 Error 边界
    │   ├── not-found.tsx         # 全局 404 页
    │   ├── _api/                 # 不以 _ 开头的目录才会成为路由
    │   ├── _assets/              # 静态资源(如图标)
    │   ├── _components/
    │   ├── _constants/
    │   ├── _stores/
    │   ├── _utils/
    │   ├── (protected)/          # 需登录业务页(Route Group)
    │   └── (public)/login/       # 公开页(登录,含 loading.tsx)
    ├── config/
    │   ├── env/                  # .env.dev / .env.qa / .env.prd
    │   └── rewrite-rules.ts      # 开发环境 API 代理规则
    ├── scripts/
    │   ├── runtime-env.mjs       # 环境变量加载
    │   ├── build-spa.mjs         # SPA 多环境构建脚本
    │   ├── gen-nginx.mjs         # nginx 配置生成
    │   └── nginx.conf.template   # nginx 配置模板
    ├── Jenkinsfile               # CI 部署配置(占位符会被替换)
    ├── pack_frontend.sh          # 前端打包脚本(调用 npm run deploy)
    ├── proxy.ts
    ├── next.config.ts            # basePath: '/nb-web-demo'
    ├── tsconfig.json
    └── package.json              # name: nb-web-demo

初始化后的业务项目结构

执行 nb-web-cli 后,用户得到的项目结构与 packages/ 一致(不含 CLI 相关文件):

my-project/                       # 用户项目
├── app/
│   ├── layout.tsx
│   ├── error.tsx
│   ├── not-found.tsx
│   ├── _api/
│   ├── _assets/
│   ├── _components/
│   ├── _constants/
│   ├── _stores/
│   ├── _utils/
│   ├── (protected)/              # 业务首页等受保护页面
│   └── (public)/login/
├── config/
├── scripts/
├── Jenkinsfile
├── pack_frontend.sh
├── proxy.ts
├── next.config.ts                # basePath: '/my-project'
├── tsconfig.json
└── package.json                  # name: my-project

架构总览

  • 浏览器:页面组件、'use client' 客户端组件、Zustand Store
  • Next.js Server:根布局、受保护布局、serverFetch 服务端请求、proxy.ts 请求拦截
  • 后端 / BFF:/node/api/*、/gw-nb/*、/sharedWorker-nb/* 等(开发环境通过 rewrites 代理)

客户端组件通过 @sumslack/request-pro 请求 BFF;服务端组件通过 serverFetch 请求同源 BFF;开发环境下 proxy.ts 注入请求头,rewrite-rules.ts 转发 API 请求。

与官方约定的对应关系

| 官方概念 | 本脚手架实现 | |----------|-------------| | app/ 目录 | ✅ 使用 App Router | | layout.tsx | 根布局 + 业务布局(鉴权) | | page.tsx | 各路由页面 | | loading.tsx / error.tsx / not-found.tsx | 根级 error.tsx / not-found.tsx;登录页 (public)/login/loading.tsx | | Route Groups (folder) | (protected) / (public) 分组 | | basePath | next.config.ts 统一配置路由前缀,业务页面直接放在 app/ 下 | | proxy.ts(Next 16) | 注入请求来源路径,配合登录回跳 | | 环境变量 NEXT_PUBLIC_* | config/env/.env.{dev,qa,prd} |

路径别名

tsconfig.json 中配置了 @_* 别名,避免深层相对路径:

"@_api": ["./app/_api"],
"@_stores": ["./app/_stores"],
"@_components": ["./app/_components"],
"@_constants": ["./app/_constants"],
"@_utils": ["./app/_utils"]

以 _ 开头的目录(如 _api、_components)不会被 Next.js 当作路由,可安全放在 app/ 下。


3. 路由(Routing)

对应官方文档:Routing

文件系统路由

模板通过 next.config.ts 的 basePath 统一配置路由前缀。Route Group 目录 (protected) / (public) 不会出现在 URL 中:

app/(protected)/page.tsx      →  /nb-web-demo
app/(public)/login/page.tsx   →  /nb-web-demo/login

初始化后 basePath 替换为项目名,例如 app/(protected)/page.tsx → /my-app。

Route Groups(路由组)

括号文件夹 (protected) / (public) 不会出现在 URL 中,仅用于组织代码和共享布局:

| 路由组 | 文件 | 实际 URL | |--------|------|----------| | (protected) | (protected)/page.tsx | /nb-web-demo | | (public) | (public)/login/page.tsx | /nb-web-demo/login |

| 路由组 | 用途 | 布局行为 | |--------|------|----------| | (protected) | 需登录的业务页面 | 包裹 UserProvider + UserGuard | | (public) | 登录等公开页面 | 无鉴权守卫 |

路由常量

统一在 app/_constants/urls.ts 维护,避免硬编码:

export const userUrl = '/node/api/user';
export const sharedWorkerUrl = '/sharedWorker-nb/SharedWork.v4.0.0.min.js';
export const k8sPrefix = '/node/api/k8s';
export const baseUrl = `${k8sPrefix}/demo`;

export const basePath = '/nb-web-demo';   // Next.js basePath,初始化后替换
export const loginPath = '/login';        // 相对 basePath 的路径,完整 URL 为 /nb-web-demo/login

4. 布局与页面(Layouts & Pages)

对应官方文档:Layouts and Pages

布局嵌套关系

app/layout.tsx                  根布局:HTML、全局样式、GlobalProviders
  └── (protected)/layout.tsx    UserProvider + UserGuard
        └── page.tsx            业务页面
              └── components/test.tsx   客户端组件

根布局 app/layout.tsx

职责:

  • 设置 <html> / <body> 和 metadata
  • 引入全局 SCSS
  • 挂载 GlobalProviders(模块顶层初始化 initRequestPro,挂载后恢复持久化 Store)

业务布局 (protected)/layout.tsx

职责:

  • 用 UserProvider 提供用户上下文
  • 用 UserGuard 校验登录态,未登录则跳转登录页

页面 page.tsx

默认是 Server Component。本样例中页面本身较薄,主要组合子组件:

// app/(protected)/page.tsx
import Test from './components/test';
import Test2 from './components/test2';

export default function NbWebDemo() {
  return (
    <div className='nb-web-demo'>
      <div className='mb-16'>this is a nb-web-demo</div>
      <Test text='this is a test component' />
      <Test2 />
    </div>
  );
}

5. 服务端与客户端组件

对应官方文档:Server and Client Components

如何选择

  1. 需要 useState / useEffect / 事件处理 → 使用 'use client' 客户端组件
  2. 需要直接读 cookies / headers / 服务端 fetch → 使用默认的 Server Component
  3. 其余情况 → 优先 Server Component

| 类型 | 标识 | 本仓库样例 | |------|------|-----------| | Server Component | 默认,无需声明 | (protected)/layout.tsx、page.tsx | | Client Component | 文件顶部 'use client' | test.tsx、UserGuard.tsx、login/page.tsx |

边界原则

  • Server → Client:可以把 Client 组件当子组件引入 Server 组件 ✅
  • Client → Server:不能把 Server 组件直接 import 进 Client 组件 ❌
  • 交互逻辑、浏览器 API、Zustand、ahooks 等放在 Client 组件中

server-only / client-only

app/_utils/server/ 使用 server-only,app/_utils/client/ 使用 client-only,防止在错误的环境中引用:

_utils/
├── server/     # serverFetch、jumpLogin(redirect)
└── client/     # jumpLogin(location)、checkUserInQb

6. 数据获取

对应官方文档:Fetching Data

本脚手架区分 客户端请求 和 服务端请求 两套方式:

  • 客户端:@sumslack/request-pro 的 requestPro → app/_api/
  • 服务端:serverFetch → app/_api/server/
  • 两者均请求 /node/api/* 等同源 BFF(样例 testApi 走 /node/api/k8s/*)

客户端请求 — @sumslack/request-pro

在 GlobalProviders.tsx 模块顶层通过 initRequestPro 初始化后,Client Component 中使用:

// app/_api/user.ts
import {requestPro} from '@sumslack/request-pro';

export const login = ({username, password}): Promise<IUser> => {
  return requestPro({
    url: `${userUrl}/login`,
    method: 'post',
    data: {username, password, gatewayToken: true},
  }).then((res) => res.data.content || {});
};

export const getUser = (): Promise<IUser> => {
  return requestPro({ url: userUrl, method: 'get' })
    .then((res) => res.data.content || {});
};

@sumslack/request-pro 基于 axios,业务数据在 res.data 中;响应拦截器在 res.data.status === 401 时会自动 jumpLogin。

// app/_api/index.ts
export const testApi = (): Promise<any[]> => {
  return requestPro({
    url: `${k8sPrefix}/bond-market-calendar-v2/api/v1/query-issue`,
    method: 'get',
  }).then((res) => res.data.text || []);
};

test.tsx 中通过 ahooks 的 useRequest 调用 testApi 拉取数据。

服务端请求 — serverFetch

在 Server Component / Server Action 中请求同源 BFF,自动转发 Cookie:

// app/_api/server/user.ts
export const getServerUser = cache(async (): Promise<IUser | null> => {
  const res = await serverFetch(userUrl);
  if (!res?.ok) return null;
  const {status, content} = await res.json();
  return status === 401 || isEmpty(content) ? null : content;
});

cache() 保证同一请求周期内去重,符合 React 推荐模式。


7. 特殊文件:Loading / Error / Not Found

对应官方文档:

| 文件 | 触发时机 | 样例位置 | |------|----------|----------| | loading.tsx | 路由段加载中(Suspense 边界) | (public)/login/loading.tsx | | error.tsx | 子树抛出未捕获错误 | app/error.tsx(根级,覆盖全部路由) | | not-found.tsx | 调用 notFound() 或路由不存在 | app/not-found.tsx(根级) |

Error 边界试用

test.tsx 中提供了「点击崩溃」按钮,将 count 设为 undefined 后访问 count.length 会触发错误,由 error.tsx 捕获并展示重试按钮。


8. Proxy 与开发代理

对应官方文档:Proxy(Next.js 16)

proxy.ts — 请求拦截

在匹配路径的请求头中注入来源路径,供服务端 jumpLogin 做登录后回跳:

// proxy.ts
export function proxy(request: NextRequest) {
  requestHeaders.set(REQUEST_FROM_PATH_KEY, `${pathname}${search}`);
  return NextResponse.next({ request: { headers: requestHeaders } });
}

export const config = {
  matcher: ['/nb-web-demo/:path*'],
};

config/rewrite-rules.ts — 开发环境 API 转发

仅在 RUNTIME_ENV=dev 时通过 next.config.ts 的 rewrites 生效:

// config/rewrite-rules.ts
export const rewriteRules = [
  { source: '/gw-nb/:path*', destination: 'https://s.sumslack.com/gw-nb/:path*' },
  { source: '/node/api/:path*', destination: 'http://s.sumslack.com/api/:path*' },
  { source: '/sharedWorker-nb/:path*', destination: 'https://s.sumslack.com/sharedWorker-nb/:path*' },
];

开发环境下,浏览器请求 /node/api/*、/gw-nb/*、/sharedWorker-nb/* 等路径时,Next.js Dev Server 通过 rewrites 代理转发到 QA 后端。


9. 环境变量

对应官方文档:Environment Variables

加载机制

scripts/runtime-env.mjs 中的 loadRuntimeEnv() 根据 RUNTIME_ENV(dev / qa / prd)加载 config/env/.env.{dev,qa,prd}:

# config/env/.env.dev
NEXT_PUBLIC_RUNTIME_ENV=dev          # 客户端可访问
NEXT_PUBLIC_WS_BASE_URL=dev-ws
# INTERNAL_API_BASE_URL=...          # 仅服务端

| 规则 | 说明 | |------|------| | NEXT_PUBLIC_* | 会打入客户端 bundle,可在组件中通过 process.env.NEXT_PUBLIC_* 访问 | | 无此前缀 | 仅服务端可用 |

test.tsx 中展示了运行时环境变量的读取:

<div>runtime env: {process.env.NEXT_PUBLIC_RUNTIME_ENV}</div>
<div>ws base url: {process.env.NEXT_PUBLIC_WS_BASE_URL}</div>

10. 全局状态(Zustand)

本脚手架基于 Zustand 封装了两种 Store 创建方式:

| Store | 创建方式 | 持久化 | 样例 | |-------|----------|--------|------| | useTestStore | createPlainStore | ❌ | isLoading 开关 | | useTestPersistStore | createPersistStore | ✅ localStorage | aConfig 配置 |

  • createPlainStore:内存态,如 useTestStore
  • createPersistStore:持久化到 localStorage,如 useTestPersistStore
  • GlobalProviders 挂载后调用 rehydratePersistStores() 恢复持久化数据

持久化 Hydration

持久化 Store 设置了 skipHydration: true,在 GlobalProviders 挂载后统一调用 rehydratePersistStores(),避免 SSR 与客户端状态不一致。

跨组件共享演示

  • test.tsx:修改 isLoading 和 aConfig
  • test2.tsx:只读展示同一 Store 的值

11. 用户鉴权

鉴权流程

  1. 用户访问受保护页面
  2. UserGuard 调用 getUser() 写入 UserProvider 上下文
  3. 有 userId:执行 checkUserInQb 校验 QB 客户端一致性,通过后写入 requestPro 默认 userId 请求头并渲染子页面
  4. 无 userId:jumpLogin 跳转登录页,携带 from 参数
  5. requestPro 响应拦截器在接口返回 401 时也会自动 jumpLogin

核心组件

| 组件 / 工具 | 职责 | |-------------|------| | UserProvider | React Context,持有 user / setUser | | UserGuard | 拉取用户信息、校验 QB 客户端一致性、写入请求头、未登录跳转 | | jumpLogin(client) | 跳转 ${basePath}${loginPath}?from=...,携带完整来源路径 | | jumpLogin(server) | redirect() 跳转,from 来自 proxy.ts 注入的请求头 | | login/page.tsx | 登录表单,调用 _api/login(密码 MD5 后提交);成功后 router.replace(tarJumpPath)(自动剥离 basePath 前缀) |

登录回跳流程

  1. 用户访问 /nb-web-demo/foo?bar=1
  2. proxy.ts 将路径写入请求头 x-from-path
  3. 未登录时跳转 /nb-web-demo/login?from=%2Fnb-web-demo%2Ffoo%3Fbar%3D1
  4. 登录成功后 router.replace('/foo?bar=1'),Next.js 自动加上 basePath 回到原页面

12. 构建与部署

对应官方文档:Deploying

Jenkins 部署注意: 部署到 Jenkins 的分支名必须以 rel_ 为前缀,否则部署无法生效。

SPA 静态导出(默认)

npm run build
npm run build:spa

scripts/build-spa.mjs 会依次构建 qa、prd 两个环境,最终产物结构如下:

dist/
├── qa/          # QA 环境静态文件
└── prd/         # PRD 环境静态文件
build/
└── nb-web-demo.tar.gz   # 打包后的部署产物(初始化后为 <项目名>.tar.gz)

构建时 SPA_EXPORT=true,next.config.ts 启用:

  • output: 'export'
  • distDir: 'dist'
  • trailingSlash: true
  • basePath: '/nb-web-demo'(初始化后替换为项目名)

SSR 模式

需要 Node 服务运行时使用:

npm run build:ssr   # 清理后构建,产物在 .next/
npm run start       # 启动 SSR 生产服务

生成 nginx 配置

SPA 静态资源部署到 nginx 时,可根据模板生成 QA / PRD 两套配置文件:

npm run gen:nginx -- 8080

用法说明:

  • 必须传入端口号(正整数),例如 8080
  • 脚本会读取 package.json 的 name,并校验 next.config.ts 中的 basePath 是否为 /<项目名>,两者需保持一致
  • 每次执行会先清空 nginx/ 目录,再基于 scripts/nginx.conf.template 生成:
    • nginx/<项目名>.qa.conf
    • nginx/<项目名>.prd.conf
  • 生成目录已写入 .gitignore,不会提交到仓库

典型流程:

npm run build                          # 构建 SPA 静态产物
npm run gen:nginx -- 8080              # 生成 nginx 配置
# 将 dist/ 与 nginx/*.conf 按部署规范上传到服务器

13. 样例页面走读

访问 /nb-web-demo(需登录),页面由以下部分组成:

test.tsx — 综合演示组件

| 功能 | 涉及技术 | |------|----------| | 展示环境变量 | NEXT_PUBLIC_* | | 请求接口数据 | useRequest + testApi | | 读取用户信息 | useUserContext | | 本地 state | useState | | 全局状态 | useTestStore / useTestPersistStore | | UI 组件 | @sumslack/shadcn-pro 的 ProButton | | 错误边界 | 「点击崩溃」按钮 |

test2.tsx — 跨组件状态订阅

只读订阅 useTestStore 和 useTestPersistStore,验证 Store 在兄弟组件间共享。

页面渲染链路

用户请求 /nb-web-demo
  → proxy.ts 注入 x-from-path
  → app/layout.tsx(GlobalProviders 初始化)
  → (protected)/layout.tsx(UserGuard 校验)
  → page.tsx(Server Component 组装)
  → test.tsx + test2.tsx(Client Component 交互)

14. 新建业务模块 Checklist

通过 CLI 创建全新项目

  • [ ] 创建空目录并进入,nb-web-cli 或 nb-web-cli <项目名> 初始化
  • [ ] 确认 package.json 的 name、urls.ts 与 next.config.ts 中的 basePath 均已替换

在已有项目中新增业务模块

路由直接放在 app/ 下,按 Route Group 或路径段组织:

  • [ ] 在 app/ 下新增路由目录,如 app/(protected)/settings/ 或 app/dashboard/
  • [ ] 需鉴权的页面放在 (protected) 路由组内
  • [ ] 公开页面放在 (public) 路由组或独立路径段
  • [ ] 在 _constants/urls.ts 补充业务路径常量
  • [ ] 更新 proxy.ts 的 matcher(若新增需拦截的路径段)
  • [ ] 在 config/rewrite-rules.ts 补充开发环境代理(如需要)
  • [ ] 在 config/env/ 各环境文件中添加 NEXT_PUBLIC_* 变量
  • [ ] 业务 API 放入 _api/,服务端专用放 _api/server/
  • [ ] 需全局状态的逻辑放入 _stores/,通过 createPlainStore 或 createPersistStore 创建
  • [ ] Client 组件顶部加 'use client',服务端工具放 _utils/server/

SPA 部署

  • [ ] npm run build 生成 dist/qa、dist/prd 与 build/<项目名>.tar.gz
  • [ ] npm run gen:nginx -- <port> 生成 nginx 配置(basePath 需与 package.json 的 name 一致)

维护脚手架模板

修改 packages/ 下的代码即可,保存后重新执行 nb-web-cli 验证初始化结果。无需额外同步步骤。


参考链接