22
33[ ![ npm latest version] ( https://img.shields.io/npm/v/path-serializer?style=flat-square&color=98c379 )] ( https://www.npmjs.com/package/path-serializer )
44
5- 1 . stabilize pnpm dependencies path in snapshot
6- 2 . transform win32 path to posix path
7- 3 . escapeEOL \r\n -> \n
8- and more...
5+ A snapshot serializer that normalizes system-specific paths into stable, readable placeholders — designed for Vitest, Jest, and Rstest.
6+
7+ - Stabilize pnpm dependencies path in snapshot
8+ - Transform win32 path to posix path
9+ - Replace absolute paths with placeholders (` <ROOT> ` , ` <WORKSPACE> ` , ` <HOME> ` , ` <TEMP> ` )
10+ - Handle ` file:// ` protocol URLs
11+ - Escape EOL (` \r\n ` -> ` \n ` )
12+ - Normalize ANSI color codes
913
1014``` ts
1115// __snapshots__/index.test.ts.snap
12- // 😭 bad
16+
17+ // 😭 Without path-serializer — fragile, platform-specific, unreadable
1318{
1419 " loader" : " D:\\ user\\ rspack\\ node_modules\\ .pnpm\\ css-loader@6.11.0_@rspack+core@packages+rspack_webpack@5.94.0_@swc+core@1.4.0_@swc+helpers@0._jlcdgjlw2ezzhg43ml3d627wdu\\ node_modules\\ css-loader\\ utils.ts"
1520}
16- // 😎👍🏻 good
21+
22+ // 😎 With path-serializer — stable, cross-platform, clean
1723{
1824 " loader" : " <ROOT>/node_modules/<PNPM_INNER>/css-loader/utils.ts"
1925}
2026```
2127
28+ ## Installation
29+
30+ ``` bash
31+ # npm
32+ npm install path-serializer -D
33+
34+ # pnpm
35+ pnpm add path-serializer -D
36+ ```
37+
2238## Usage
2339
40+ ### Basic
41+
2442``` typescript
2543// vitest.setup.ts
44+ import path from ' node:path' ;
45+ import { expect } from ' vitest' ;
2646import { createSnapshotSerializer } from ' path-serializer' ;
2747
2848expect .addSnapshotSerializer (
@@ -32,12 +52,119 @@ expect.addSnapshotSerializer(
3252);
3353```
3454
35- More features can be found in [ ./src/types.ts] ( https://github.com/rspack-contrib/path-serializer/blob/main/src/types.ts )
55+ ### With Workspace (Monorepo)
56+
57+ ``` typescript
58+ expect .addSnapshotSerializer (
59+ createSnapshotSerializer ({
60+ root: path .join (__dirname , ' ../..' ),
61+ workspace: path .join (__dirname , ' ..' ),
62+ }),
63+ );
64+ ```
65+
66+ This replaces:
67+ - Workspace paths → ` <WORKSPACE>/... `
68+ - Root paths → ` <ROOT>/... `
69+
70+ ### Custom Replacements
71+
72+ Use ` replace ` and ` replacePost ` to add custom path matchers:
73+
74+ ``` typescript
75+ expect .addSnapshotSerializer (
76+ createSnapshotSerializer ({
77+ root: path .join (__dirname , ' ..' ),
78+ replace: [
79+ { match: / port\s\d + / , mark: ' PORT' },
80+ { match: ' /specific/path' , mark: ' CUSTOM' },
81+ ],
82+ }),
83+ );
84+ ```
85+
86+ ### Hooks
87+
88+ Use ` beforeSerialize ` and ` afterSerialize ` for custom pre/post processing:
89+
90+ ``` typescript
91+ expect .addSnapshotSerializer (
92+ createSnapshotSerializer ({
93+ root: path .join (__dirname , ' ..' ),
94+ beforeSerialize : (val ) => val .replace (/ hash:\w {8} / g , ' hash:<HASH>' ),
95+ afterSerialize : (val ) => val .trim (),
96+ }),
97+ );
98+ ```
99+
100+ ## Options
101+
102+ ### ` root `
103+
104+ - ** Type:** ` string `
105+ - ** Default:** ` process.cwd() `
106+
107+ Repository root path. Paths under this directory are replaced with ` <ROOT> ` .
108+
109+ ### ` workspace `
110+
111+ - ** Type:** ` string `
112+ - ** Default:** ` '' `
113+
114+ Workspace root path (for monorepos). Paths under this directory are replaced with ` <WORKSPACE> ` .
115+
116+ ### ` replace `
117+
118+ - ** Type:** ` PathMatcher[] `
119+
120+ Custom matchers applied ** before** built-in replacements.
121+
122+ ### ` replacePost `
123+
124+ - ** Type:** ` PathMatcher[] `
125+
126+ Custom matchers applied ** after** built-in replacements.
127+
128+ ### ` beforeSerialize `
129+
130+ - ** Type:** ` (val: string) => string `
131+
132+ Transform the raw string before any replacements.
133+
134+ ### ` afterSerialize `
135+
136+ - ** Type:** ` (val: string) => string `
137+
138+ Transform the final string after all replacements.
139+
140+ ### ` features `
141+
142+ Toggle individual features (all enabled by default):
143+
144+ | Feature | Default | Description |
145+ | ---| ---| ---|
146+ | ` replaceWorkspace ` | ` true ` | ` /foo/packages/core/src ` → ` <WORKSPACE>/src ` |
147+ | ` replaceRoot ` | ` true ` | ` /foo/node_modules/.pnpm ` → ` <ROOT>/node_modules/.pnpm ` |
148+ | ` replaceWorkspaceWithFileProtocol ` | ` true ` | ` file:///foo/packages/core/src ` → ` <WORKSPACE>/src ` |
149+ | ` replaceRootWithFileProtocol ` | ` true ` | ` file:///foo/node_modules/.pnpm ` → ` <ROOT>/node_modules/.pnpm ` |
150+ | ` replacePnpmInner ` | ` true ` | Collapse pnpm's long ` .pnpm/... ` paths to ` <PNPM_INNER> ` |
151+ | ` replaceTmpDir ` | ` true ` | ` os.tmpdir() ` paths → ` <TEMP> ` |
152+ | ` replaceHomeDir ` | ` true ` | ` os.homedir() ` paths → ` <HOME> ` |
153+ | ` transformWin32Path ` | ` true ` | Convert ` D:\\foo\\bar ` to ` /d/foo/bar ` |
154+ | ` transformCLR ` | ` true ` | Normalize ANSI color escape codes |
155+ | ` escapeDoubleQuotes ` | ` true ` | Escape ` " ` to ` \" ` |
156+ | ` escapeEOL ` | ` true ` | Normalize ` \r\n ` to ` \n ` |
157+ | ` addDoubleQuotes ` | ` true ` | Wrap output in double quotes |
158+
159+ More details can be found in [ ./src/types.ts] ( https://github.com/rspack-contrib/path-serializer/blob/main/src/types.ts ) .
36160
37161## Showcases
38162
39- [ Rslib] ( https://github.com/web-infra-dev/rslib/blob/3ff6859eb38171c731e447a1364afc021f8c501a/tests/setupVitestTests.ts )
163+ - [ Rslib] ( https://github.com/web-infra-dev/rslib/blob/3ff6859eb38171c731e447a1364afc021f8c501a/tests/setupVitestTests.ts )
164+ - [ Rsbuild] ( https://github.com/web-infra-dev/rsbuild/blob/a50eafa3519caaa66ecd6b0ccb2897a8194781ff/scripts/test-helper/vitest.setup.ts )
165+ - [ Rspack] ( https://github.com/web-infra-dev/rspack/blob/5a6162c/packages/rspack-test-tools/src/helper/expect/placeholder.ts )
166+ - [ Rspress] ( https://github.com/web-infra-dev/rspress/blob/8d620050cc2590954838e201d39c10744b6d1bac/scripts/test-helper/rstest.setup.ts )
40167
41- [ Rsbuild ] ( https://github.com/web-infra-dev/rsbuild/blob/a50eafa3519caaa66ecd6b0ccb2897a8194781ff/scripts/test-helper/vitest.setup.ts )
168+ ## License
42169
43- [ Rspack ] ( https://github.com/web-infra-dev/rspack/blob/5a6162c/packages/rspack-test-tools/src/helper/expect/placeholder.ts )
170+ [ MIT ] ( ./LICENSE )
0 commit comments