|
| 1 | +--- |
| 2 | +name: rstack-cli-best-practices |
| 3 | +description: Guidance on using Rstack CLI, including `rs` commands, the `rstack.config.ts` file, and import paths from the `rstack` package. Use for Rstack CLI-related tasks. |
| 4 | +--- |
| 5 | + |
| 6 | +# Rstack CLI Best Practices |
| 7 | + |
| 8 | +Rstack CLI is the `rstack` package, exposed through the `rs` binaries. It provides one CLI, one config file, and a consistent workflow for the Rstack JavaScript toolchain. |
| 9 | + |
| 10 | +It covers web app, library, docs, test, lint, and staged-file workflows. |
| 11 | + |
| 12 | +## Commands |
| 13 | + |
| 14 | +Use `rs -h` for top-level help, and `rs <command> -h` for command help where supported. |
| 15 | + |
| 16 | +| Command | Purpose | Underlying tool | Config | |
| 17 | +| ------------ | -------------------------------- | --------------- | --------------- | |
| 18 | +| `rs dev` | Run the app dev server | Rsbuild | `define.app` | |
| 19 | +| `rs build` | Build the app for production | Rsbuild | `define.app` | |
| 20 | +| `rs preview` | Preview the app production build | Rsbuild | `define.app` | |
| 21 | +| `rs lib` | Build a library | Rslib | `define.lib` | |
| 22 | +| `rs doc` | Serve or build docs | Rspress | `define.doc` | |
| 23 | +| `rs test` | Run tests | Rstest | `define.test` | |
| 24 | +| `rs lint` | Lint code | Rslint | `define.lint` | |
| 25 | +| `rs staged` | Run tasks on staged Git files | lint-staged | `define.staged` | |
| 26 | + |
| 27 | +Key behavior: |
| 28 | + |
| 29 | +- `rs test` extends `define.app` through `@rstest/adapter-rsbuild` and `define.lib` through `@rstest/adapter-rslib` unless `define.test` already sets `extends`. |
| 30 | +- `rs doc` requires the optional `@rspress/core` dependency. |
| 31 | + |
| 32 | +## rstack.config.ts |
| 33 | + |
| 34 | +Rstack CLI loads `rstack.config.{ts,js,mts,mjs}` by default. |
| 35 | + |
| 36 | +Register config with `define.*`: |
| 37 | + |
| 38 | +```ts |
| 39 | +import { define } from 'rstack'; |
| 40 | + |
| 41 | +define.app({ |
| 42 | + // Rsbuild config for `rs dev`, `rs build`, and `rs preview` |
| 43 | +}); |
| 44 | + |
| 45 | +define.test({ |
| 46 | + // Rstest config for `rs test` |
| 47 | +}); |
| 48 | +``` |
| 49 | + |
| 50 | +- `define.app(config)`: Rsbuild config for `rs dev`, `rs build`, and `rs preview`. Docs: https://rsbuild.rs/config/ |
| 51 | +- `define.lib(config)`: Rslib config for `rs lib`; Docs: https://rslib.rs/config/ |
| 52 | +- `define.doc(config)`: Rspress config for `rs doc`; Docs: https://rspress.rs/api/config/config-basic |
| 53 | +- `define.test(config)`: Rstest config for `rs test`; Docs: https://rstest.rs/config/ |
| 54 | +- `define.lint(config)`: Rslint config for `rs lint`; Docs: https://rslint.rs/config/ |
| 55 | +- `define.staged(config)`: lint-staged config for `rs staged`; accepts `Record<string, string | string[]>`. |
| 56 | + |
| 57 | +### Lazy Configuration |
| 58 | + |
| 59 | +Prefer async functions with dynamic imports for dependencies. Avoid top-level sync imports of heavy dependencies in `rstack.config.ts`. |
| 60 | + |
| 61 | +```ts |
| 62 | +import { define } from 'rstack'; |
| 63 | + |
| 64 | +define.app(async () => { |
| 65 | + const { pluginReact } = await import('@rsbuild/plugin-react'); |
| 66 | + return { |
| 67 | + plugins: [pluginReact()], |
| 68 | + }; |
| 69 | +}); |
| 70 | +``` |
| 71 | + |
| 72 | +## Import Paths |
| 73 | + |
| 74 | +Prefer Rstack-exported paths: |
| 75 | + |
| 76 | +| Instead of | Prefer | |
| 77 | +| ------------------------- | ------------------------ | |
| 78 | +| `@rstest/core` | `rstack/test` | |
| 79 | +| `@rslint/core` | `rstack/lint` | |
| 80 | +| `@rsbuild/core/types` | `rstack/types` | |
| 81 | +| `@rslib/core/types` | `rstack/types` | |
| 82 | +| `@rstest/core/globals` | `rstack/test/globals` | |
| 83 | +| `@rstest/core/importMeta` | `rstack/test/importMeta` | |
0 commit comments