|
| 1 | +# Formatting |
| 2 | + |
| 3 | +import { PackageManagerTabs } from '@rspress/core/theme'; |
| 4 | + |
| 5 | +Rstack CLI includes a formatter built on [Prettier](https://prettier.io/). Compared with running Prettier directly, `rs fmt` offers better performance in two ways: |
| 6 | + |
| 7 | +- **Parallel formatting**: `rs fmt` formats files concurrently in a worker pool. |
| 8 | +- **Yuku parser**: `rs fmt` uses the high-performance [Yuku](https://yuku.fyi/) parser by default for JavaScript, JSX, and TypeScript files. |
| 9 | + |
| 10 | +`rs fmt` supports Prettier options and plugins and adds built-in capabilities such as [sorting package.json fields](#sort-package-json). |
| 11 | + |
| 12 | +## Basic usage |
| 13 | + |
| 14 | +Run `rs fmt` without file arguments to format files in the current directory and save the changes: |
| 15 | + |
| 16 | +```bash |
| 17 | +rs fmt |
| 18 | +``` |
| 19 | + |
| 20 | +Use `--check` to verify formatting without changing files: |
| 21 | + |
| 22 | +```bash |
| 23 | +rs fmt --check |
| 24 | +``` |
| 25 | + |
| 26 | +See the [`rs fmt` CLI reference](./cli/fmt) for more command-line options. |
| 27 | + |
| 28 | +## Configuration |
| 29 | + |
| 30 | +Use [`define.fmt()`](./configuration#define-fmt) in `rstack.config.ts` to set formatting rules. It supports all [Prettier options](https://prettier.io/docs/options): |
| 31 | + |
| 32 | +```ts title="rstack.config.ts" |
| 33 | +import { define } from 'rstack'; |
| 34 | + |
| 35 | +define.fmt({ |
| 36 | + printWidth: 100, |
| 37 | + singleQuote: true, |
| 38 | +}); |
| 39 | +``` |
| 40 | + |
| 41 | +In addition to Prettier options and `overrides`, Rstack provides two options: |
| 42 | + |
| 43 | +- [`ignorePatterns`](#ignore-files): exclude files with Gitignore-compatible patterns. |
| 44 | +- [`sortPackageJson`](#sort-package-json): sort fields in `package.json` files. The default value is `false`. |
| 45 | + |
| 46 | +:::warning Prettier configuration files |
| 47 | + |
| 48 | +`rs fmt` does not read Prettier configuration files, `.prettierignore`, or `.editorconfig`. Keep formatting options and additional ignore rules in `define.fmt()`. |
| 49 | + |
| 50 | +::: |
| 51 | + |
| 52 | +## Formatting scope |
| 53 | + |
| 54 | +`rs fmt` determines the formatting scope from the paths passed on the command line. You can combine the following inputs: |
| 55 | + |
| 56 | +- **Files**: format only the specified files. |
| 57 | +- **Directories**: scan directories recursively and format supported files. |
| 58 | +- **Glob patterns**: match multiple paths, and prefix a pattern with `!` to exclude matches. |
| 59 | + |
| 60 | +When no paths are provided, `rs fmt` formats the current directory. All glob patterns are resolved from the current working directory. Quote them so that `rs fmt`, rather than the shell, expands them: |
| 61 | + |
| 62 | +```bash |
| 63 | +# Format a directory and a file |
| 64 | +rs fmt src package.json |
| 65 | + |
| 66 | +# Format JavaScript and TypeScript files, excluding generated files |
| 67 | +rs fmt "src/**/*.{js,ts}" "!src/generated/**" |
| 68 | +``` |
| 69 | + |
| 70 | +When scanning directories or globs, `rs fmt` follows `.gitignore` rules, skips binary files, and does not traverse version-control directories or `node_modules`. It also skips files for which Prettier cannot infer a parser. |
| 71 | + |
| 72 | +`.gitignore` applies only when scanning directories and globs. It does not exclude files passed explicitly on the command line. To always exclude a file, use [`ignorePatterns`](#ignore-files). |
| 73 | + |
| 74 | +## Ignore files |
| 75 | + |
| 76 | +Use `ignorePatterns` to exclude files from formatting: |
| 77 | + |
| 78 | +```ts title="rstack.config.ts" |
| 79 | +import { define } from 'rstack'; |
| 80 | + |
| 81 | +define.fmt({ |
| 82 | + ignorePatterns: ['dist/**', 'coverage/**', '**/generated/**'], |
| 83 | +}); |
| 84 | +``` |
| 85 | + |
| 86 | +Patterns follow Gitignore syntax and are resolved relative to the directory containing the Rstack configuration file. Because they are applied after the files are selected, they also exclude files passed explicitly on the command line. |
| 87 | + |
| 88 | +## Sort package.json fields \{#sort-package-json} |
| 89 | + |
| 90 | +Enable `sortPackageJson` to sort fields in each selected `package.json` with [`sort-package-json`](https://github.com/keithamus/sort-package-json): |
| 91 | + |
| 92 | +```ts title="rstack.config.ts" |
| 93 | +import { define } from 'rstack'; |
| 94 | + |
| 95 | +define.fmt({ |
| 96 | + sortPackageJson: true, |
| 97 | +}); |
| 98 | +``` |
| 99 | + |
| 100 | +## Overrides |
| 101 | + |
| 102 | +Use the `overrides` field to set options for specific files. Each override supports these fields: |
| 103 | + |
| 104 | +- `files`: files or glob patterns to match. |
| 105 | +- `options`: formatting options applied to matching files. |
| 106 | +- `excludeFiles`: optional files or glob patterns to exclude. |
| 107 | + |
| 108 | +```ts title="rstack.config.ts" |
| 109 | +import { define } from 'rstack'; |
| 110 | + |
| 111 | +define.fmt({ |
| 112 | + overrides: [ |
| 113 | + { |
| 114 | + files: 'docs/**/*.md', |
| 115 | + excludeFiles: 'docs/generated/**', |
| 116 | + options: { |
| 117 | + proseWrap: 'always', |
| 118 | + }, |
| 119 | + }, |
| 120 | + ], |
| 121 | +}); |
| 122 | +``` |
| 123 | + |
| 124 | +### Pattern matching |
| 125 | + |
| 126 | +The `files` and `excludeFiles` patterns are resolved relative to the directory containing `rstack.config.ts`. |
| 127 | + |
| 128 | +In `files`, a pattern without `/` matches file names at any depth, while a pattern containing `/` matches relative paths. In this example, `*.md` matches Markdown files in any directory, while `scripts/**/*.js` matches paths relative to the configuration directory: |
| 129 | + |
| 130 | +```ts |
| 131 | +define.fmt({ |
| 132 | + overrides: [ |
| 133 | + { files: '*.md', options: { proseWrap: 'always' } }, |
| 134 | + { files: 'scripts/**/*.js', options: { singleQuote: true } }, |
| 135 | + ], |
| 136 | +}); |
| 137 | +``` |
| 138 | + |
| 139 | +### Merge order |
| 140 | + |
| 141 | +When multiple overrides match, they are applied in declaration order, so later values take precedence. Here, `README.md` matches both overrides, so the final `printWidth` is `80`: |
| 142 | + |
| 143 | +```ts |
| 144 | +define.fmt({ |
| 145 | + overrides: [ |
| 146 | + { files: '*.md', options: { printWidth: 100 } }, |
| 147 | + { files: 'README.md', options: { printWidth: 80 } }, |
| 148 | + ], |
| 149 | +}); |
| 150 | +``` |
| 151 | + |
| 152 | +## Prettier plugins |
| 153 | + |
| 154 | +To add formatting capabilities that are not built into Rstack, install the corresponding [Prettier plugin](https://prettier.io/docs/plugins) and add it to `plugins`. Plugins can be referenced by package name, file path, or URL. Package names and relative paths are resolved from the directory containing the Rstack configuration file. |
| 155 | + |
| 156 | +Because `rs fmt` loads plugins in workers, plugin objects cannot be passed directly. Reference each plugin by package name, path, or URL instead. For example, install and enable [`prettier-plugin-tailwindcss`](https://github.com/tailwindlabs/prettier-plugin-tailwindcss): |
| 157 | + |
| 158 | +<PackageManagerTabs command="install -D prettier-plugin-tailwindcss" /> |
| 159 | + |
| 160 | +```ts title="rstack.config.ts" |
| 161 | +import { define } from 'rstack'; |
| 162 | + |
| 163 | +define.fmt({ |
| 164 | + plugins: ['prettier-plugin-tailwindcss'], |
| 165 | +}); |
| 166 | +``` |
| 167 | + |
| 168 | +To enable a plugin only for specific files, add `plugins` to the `options` of an [`overrides`](#overrides) entry. |
0 commit comments