0
# Path Normalization
1
2
Cross-platform path normalization utilities for consistent file path handling across Windows and Unix systems. Provides robust path normalization that handles Windows network shares, UNC paths, and various path formats.
3
4
## Capabilities
5
6
### Normalize Path Function
7
8
Normalizes file paths for cross-platform compatibility with special handling for Windows paths.
9
10
```typescript { .api }
11
/**
12
* Normalizes file paths for cross-platform compatibility
13
* Handles Windows network shares, UNC paths, and mixed separators
14
* @param originalPath - Path string to normalize
15
* @returns Normalized path with forward slashes and proper network share handling
16
*/
17
function normalizePath(originalPath: string): string;
18
```
19
20
**Usage Examples:**
21
22
```typescript
23
import { normalizePath } from "@tailwindcss/node";
24
25
// Basic path normalization
26
console.log(normalizePath("src\\components\\Button.tsx"));
27
// Output: "src/components/Button.tsx"
28
29
console.log(normalizePath("src/components/Button.tsx"));
30
// Output: "src/components/Button.tsx" (already normalized)
31
32
// Mixed separators
33
console.log(normalizePath("src\\components/utils\\helpers.js"));
34
// Output: "src/components/utils/helpers.js"
35
36
// Trailing separators
37
console.log(normalizePath("dist\\"));
38
// Output: "dist"
39
40
console.log(normalizePath("dist/"));
41
// Output: "dist"
42
```
43
44
### Windows Network Share Handling
45
46
Special handling for Windows network shares and UNC paths:
47
48
```typescript
49
import { normalizePath } from "@tailwindcss/node";
50
51
// Windows network share paths
52
console.log(normalizePath("\\\\server\\share\\file.txt"));
53
// Output: "//server/share/file.txt"
54
55
console.log(normalizePath("\\\\?\\C:\\Program Files\\App\\file.txt"));
56
// Output: "//C:/Program Files/App/file.txt"
57
58
console.log(normalizePath("\\\\.\\C:\\file.txt"));
59
// Output: "//C:/file.txt"
60
61
// Ensures network shares maintain double leading slashes
62
console.log(normalizePath("\\\\network-drive\\folder"));
63
// Output: "//network-drive/folder" (not "/network-drive/folder")
64
```
65
66
### Edge Cases and Special Paths
67
68
Handles various edge cases and special path formats:
69
70
```typescript
71
import { normalizePath } from "@tailwindcss/node";
72
73
// Root paths
74
console.log(normalizePath("\\"));
75
// Output: "/"
76
77
console.log(normalizePath("/"));
78
// Output: "/"
79
80
// Single character paths
81
console.log(normalizePath("a"));
82
// Output: "a"
83
84
console.log(normalizePath("."));
85
// Output: "."
86
87
// Empty segments
88
console.log(normalizePath("src//components///Button.tsx"));
89
// Output: "src/components/Button.tsx"
90
91
// Windows drive letters
92
console.log(normalizePath("C:\\Users\\name\\Documents"));
93
// Output: "C:/Users/name/Documents"
94
```
95
96
### Build Tool Integration
97
98
Common usage patterns in build tools and development workflows:
99
100
```typescript
101
import { normalizePath } from "@tailwindcss/node";
102
import path from "path";
103
104
// Normalizing resolved paths
105
function resolveAndNormalize(relativePath: string, basePath: string): string {
106
const resolved = path.resolve(basePath, relativePath);
107
return normalizePath(resolved);
108
}
109
110
const normalizedPath = resolveAndNormalize("./src/components", process.cwd());
111
console.log(normalizedPath);
112
113
// File watching with normalized paths
114
const watchPaths = [
115
"src\\components\\**\\*.tsx",
116
"src/styles/**/*.css",
117
"config\\tailwind.config.js"
118
].map(normalizePath);
119
120
console.log(watchPaths);
121
// Output: [
122
// "src/components/**/*.tsx",
123
// "src/styles/**/*.css",
124
// "config/tailwind.config.js"
125
// ]
126
```
127
128
### Error Handling
129
130
The function includes proper error handling for invalid inputs:
131
132
```typescript
133
import { normalizePath } from "@tailwindcss/node";
134
135
// Type validation
136
try {
137
normalizePath(null as any);
138
} catch (error) {
139
console.error(error.message); // "expected path to be a string"
140
}
141
142
try {
143
normalizePath(123 as any);
144
} catch (error) {
145
console.error(error.message); // "expected path to be a string"
146
}
147
148
// Valid but unusual inputs
149
console.log(normalizePath(""));
150
// Output: "" (empty string is valid)
151
152
console.log(normalizePath(" "));
153
// Output: " " (whitespace is preserved)
154
```
155
156
### Cross-Platform Development
157
158
Essential for cross-platform development where paths may come from different sources:
159
160
```typescript
161
import { normalizePath } from "@tailwindcss/node";
162
163
// Configuration files might contain platform-specific paths
164
const config = {
165
contentPaths: [
166
"src\\components\\**\\*.tsx", // Windows developer
167
"src/pages/**/*.tsx", // Unix developer
168
"lib\\utils\\*.js" // Mixed environment
169
]
170
};
171
172
// Normalize all paths for consistent processing
173
const normalizedPaths = config.contentPaths.map(normalizePath);
174
console.log(normalizedPaths);
175
// Output: [
176
// "src/components/**/*.tsx",
177
// "src/pages/**/*.tsx",
178
// "lib/utils/*.js"
179
// ]
180
181
// Use in file system operations
182
import fs from "fs";
183
import glob from "glob";
184
185
normalizedPaths.forEach(pattern => {
186
const files = glob.sync(pattern);
187
files.forEach(file => {
188
// Process file...
189
console.log(`Processing: ${normalizePath(file)}`);
190
});
191
});
192
```
193
194
### Module Resolution Integration
195
196
Commonly used with module resolution systems:
197
198
```typescript
199
import { normalizePath } from "@tailwindcss/node";
200
201
// Custom resolver that normalizes paths
202
function customResolver(id: string, base: string): string | null {
203
if (id.startsWith("@/")) {
204
const resolved = path.resolve(base, "src", id.slice(2));
205
return normalizePath(resolved);
206
}
207
208
if (id.startsWith("~/")) {
209
const resolved = path.resolve(base, id.slice(2));
210
return normalizePath(resolved);
211
}
212
213
return null;
214
}
215
216
// Usage with compilation
217
import { compile } from "@tailwindcss/node";
218
219
const compiler = await compile(css, {
220
base: process.cwd(),
221
onDependency: (path) => console.log("Dependency:", normalizePath(path)),
222
customCssResolver: async (id, base) => {
223
const resolved = customResolver(id, base);
224
return resolved ? normalizePath(resolved) : undefined;
225
}
226
});
227
```
228
229
## Implementation Details
230
231
The normalization process:
232
233
1. **Type Validation**: Ensures input is a string
234
2. **Root Path Handling**: Special cases for "/" and "\"
235
3. **Short Path Optimization**: Returns paths of length ≤ 1 unchanged
236
4. **Windows Namespace Detection**: Identifies UNC and device paths
237
5. **Segment Splitting**: Splits on both "/" and "\" separators
238
6. **Empty Segment Removal**: Removes trailing empty segments
239
7. **Path Reconstruction**: Joins with "/" separators
240
8. **Network Share Correction**: Ensures proper "//" prefix for network paths
241
242
This ensures consistent, predictable path handling across all platforms and environments.