0
# Utility Processing
1
2
String replacement and content manipulation utilities for preprocessing markup and script content.
3
4
## Capabilities
5
6
### Replace Processing
7
8
String replacement processor for find-and-replace operations on markup content, supporting both string and regex patterns.
9
10
```typescript { .api }
11
/**
12
* Creates replace preprocessor for markup blocks
13
* @param options - Array of replacement patterns
14
* @returns PreprocessorGroup with markup preprocessing
15
*/
16
function replace(options: Options.Replace): PreprocessorGroup;
17
18
namespace Options {
19
type Replace = Array<
20
| [string | RegExp, string]
21
| [RegExp, (substring: string, ...args: any[]) => string]
22
>;
23
}
24
```
25
26
**Usage Examples:**
27
28
```typescript
29
import { replace } from "svelte-preprocess";
30
31
// Basic string replacements
32
const preprocess = {
33
markup: replace([
34
// Simple string replacement
35
['__VERSION__', '1.0.0'],
36
['__BUILD_DATE__', new Date().toISOString()],
37
38
// Environment variables
39
['process.env.NODE_ENV', JSON.stringify(process.env.NODE_ENV)],
40
['process.env.API_URL', JSON.stringify(process.env.API_URL || 'http://localhost:3000')]
41
])
42
};
43
44
// Regex replacements
45
const preprocess = {
46
markup: replace([
47
// Remove debug comments
48
[/<!--\s*DEBUG:.*?-->/g, ''],
49
50
// Replace placeholder URLs
51
[/https?:\/\/placeholder\.com/g, 'https://api.example.com'],
52
53
// Transform custom syntax
54
[/\{\{(\w+)\}\}/g, '{$1}'] // Convert {{variable}} to {variable}
55
])
56
};
57
58
// Function-based replacements
59
const preprocess = {
60
markup: replace([
61
// Dynamic replacements with custom logic
62
[/\{\{DATE:([^}]+)\}\}/g, (match, format) => {
63
return new Intl.DateTimeFormat('en-US', {
64
dateStyle: format
65
}).format(new Date());
66
}],
67
68
// Template processing
69
[/\{\{INCLUDE:([^}]+)\}\}/g, (match, filename) => {
70
return require('fs').readFileSync(filename, 'utf-8');
71
}]
72
])
73
};
74
```
75
76
## Integration with Auto Preprocessor
77
78
The replace processor integrates with the auto preprocessor and is applied early in the processing pipeline:
79
80
```typescript
81
import { sveltePreprocess } from "svelte-preprocess";
82
83
const preprocess = sveltePreprocess({
84
// Replace processing happens first, before other markup processing
85
replace: [
86
['__VERSION__', process.env.npm_package_version],
87
['__API_URL__', process.env.API_URL],
88
[/\{\{(\w+)\}\}/g, '{$1}'] // Template syntax conversion
89
],
90
91
// Then other processors
92
pug: true,
93
typescript: true,
94
scss: true
95
});
96
```
97
98
Processing order in auto preprocessor:
99
1. **Replace processing** (applied to markup)
100
2. Markup processing (Pug, etc.)
101
3. Script and style processing
102
103
## Common Use Cases
104
105
### Environment Variable Injection
106
107
```typescript
108
const preprocess = sveltePreprocess({
109
replace: [
110
// Build-time constants
111
['__VERSION__', JSON.stringify(process.env.npm_package_version)],
112
['__BUILD_TIMESTAMP__', JSON.stringify(Date.now())],
113
114
// Environment configuration
115
['__API_BASE_URL__', JSON.stringify(process.env.API_BASE_URL)],
116
['__DEBUG_MODE__', JSON.stringify(process.env.NODE_ENV === 'development')],
117
118
// Feature flags
119
['__FEATURE_NEW_UI__', JSON.stringify(process.env.FEATURE_NEW_UI === 'true')]
120
]
121
});
122
```
123
124
Then use in components:
125
126
```svelte
127
<script>
128
const apiUrl = __API_BASE_URL__;
129
const version = __VERSION__;
130
const debugMode = __DEBUG_MODE__;
131
</script>
132
133
<div class="app-info">
134
<p>Version: {version}</p>
135
{#if debugMode}
136
<p>API URL: {apiUrl}</p>
137
{/if}
138
</div>
139
```
140
141
### Template Syntax Conversion
142
143
```typescript
144
// Convert from other template syntaxes to Svelte
145
const preprocess = sveltePreprocess({
146
replace: [
147
// Vue-style template syntax to Svelte
148
[/v-if="([^"]+)"/g, '{#if $1}'],
149
[/v-for="(\w+) in (\w+)"/g, '{#each $2 as $1}'],
150
[/\{\{([^}]+)\}\}/g, '{$1}'],
151
152
// Angular-style to Svelte
153
[/\*ngIf="([^"]+)"/g, '{#if $1}'],
154
[/\*ngFor="let (\w+) of (\w+)"/g, '{#each $2 as $1}'],
155
156
// React-style class binding
157
[/className=\{([^}]+)\}/g, 'class={$1}']
158
]
159
});
160
```
161
162
### Content Generation
163
164
```typescript
165
const fs = require('fs');
166
const path = require('path');
167
168
const preprocess = sveltePreprocess({
169
replace: [
170
// Include external content
171
[/\{\{INCLUDE:([^}]+)\}\}/g, (match, filename) => {
172
try {
173
return fs.readFileSync(path.resolve(filename), 'utf-8');
174
} catch (err) {
175
console.warn(`Could not include file: ${filename}`);
176
return '';
177
}
178
}],
179
180
// Generate component imports
181
[/\{\{AUTO_IMPORTS:([^}]+)\}\}/g, (match, directory) => {
182
const files = fs.readdirSync(directory)
183
.filter(file => file.endsWith('.svelte'))
184
.map(file => {
185
const name = path.basename(file, '.svelte');
186
return `import ${name} from './${directory}/${file}';`;
187
});
188
return files.join('\n');
189
}],
190
191
// Generate type definitions
192
[/\{\{TYPE_EXPORTS\}\}/g, () => {
193
const types = ['User', 'Product', 'Order']; // from some source
194
return types.map(type => `export type { ${type} };`).join('\n');
195
}]
196
]
197
});
198
```
199
200
### Conditional Compilation
201
202
```typescript
203
const preprocess = sveltePreprocess({
204
replace: [
205
// Development-only code blocks
206
[/\/\* DEV_START \*\/[\s\S]*?\/\* DEV_END \*\//g,
207
process.env.NODE_ENV === 'development' ? '$&' : ''
208
],
209
210
// Production-only code blocks
211
[/\/\* PROD_START \*\/([\s\S]*?)\/\* PROD_END \*\//g,
212
process.env.NODE_ENV === 'production' ? '$1' : ''
213
],
214
215
// Feature flag blocks
216
[/\/\* FEATURE:(\w+)_START \*\/([\s\S]*?)\/\* FEATURE:\1_END \*\//g,
217
(match, featureName, content) => {
218
return process.env[`FEATURE_${featureName.toUpperCase()}`] === 'true' ? content : '';
219
}
220
]
221
]
222
});
223
```
224
225
Then use in templates:
226
227
```svelte
228
<!-- This block only appears in development -->
229
/* DEV_START */
230
<div class="debug-panel">
231
<h3>Debug Information</h3>
232
<pre>{JSON.stringify($page, null, 2)}</pre>
233
</div>
234
/* DEV_END */
235
236
<!-- This block only appears in production -->
237
/* PROD_START */
238
<script async src="https://analytics.example.com/script.js"></script>
239
/* PROD_END */
240
241
<!-- Feature flag controlled content -->
242
/* FEATURE:NEW_HEADER_START */
243
<header class="new-header">
244
<h1>New Design</h1>
245
</header>
246
/* FEATURE:NEW_HEADER_END */
247
```
248
249
### CSS Custom Property Injection
250
251
```typescript
252
const preprocess = sveltePreprocess({
253
replace: [
254
// Inject CSS custom properties
255
['/* CSS_VARS */', () => {
256
const theme = require('./theme.json');
257
return Object.entries(theme)
258
.map(([key, value]) => `--${key}: ${value};`)
259
.join('\n ');
260
}]
261
]
262
});
263
```
264
265
```svelte
266
<style>
267
:root {
268
/* CSS_VARS */
269
}
270
</style>
271
```
272
273
## Advanced Patterns
274
275
### Multi-step Processing
276
277
```typescript
278
const preprocess = sveltePreprocess({
279
replace: [
280
// Step 1: Process includes
281
[/\{\{INCLUDE:([^}]+)\}\}/g, (match, file) => fs.readFileSync(file, 'utf-8')],
282
283
// Step 2: Process variables (after includes)
284
[/__(\w+)__/g, (match, varName) => process.env[varName] || match],
285
286
// Step 3: Clean up markers
287
[/\/\* MARKER:.*?\*\//g, '']
288
]
289
});
290
```
291
292
### Internationalization
293
294
```typescript
295
const translations = require('./i18n/en.json');
296
297
const preprocess = sveltePreprocess({
298
replace: [
299
// Replace translation keys
300
[/\{\{t:([^}]+)\}\}/g, (match, key) => {
301
return translations[key] || key;
302
}],
303
304
// Replace pluralization
305
[/\{\{plural:(\w+):(\d+)\}\}/g, (match, key, count) => {
306
const pluralKey = count === '1' ? key : `${key}_plural`;
307
return translations[pluralKey] || key;
308
}]
309
]
310
});
311
```
312
313
### Build Optimization
314
315
```typescript
316
const preprocess = sveltePreprocess({
317
replace: [
318
// Remove console.log in production
319
process.env.NODE_ENV === 'production' && [/console\.log\([^)]*\);?/g, ''],
320
321
// Remove comments in production
322
process.env.NODE_ENV === 'production' && [/\/\*[\s\S]*?\*\//g, ''],
323
process.env.NODE_ENV === 'production' && [/\/\/.*$/gm, ''],
324
325
// Minify whitespace in production
326
process.env.NODE_ENV === 'production' && [/\s{2,}/g, ' ']
327
].filter(Boolean)
328
});
329
```
330
331
## Error Handling
332
333
```typescript
334
const preprocess = sveltePreprocess({
335
replace: [
336
// Safe file inclusion with error handling
337
[/\{\{SAFE_INCLUDE:([^}]+)\}\}/g, (match, filename) => {
338
try {
339
return fs.readFileSync(filename, 'utf-8');
340
} catch (error) {
341
console.warn(`Warning: Could not include ${filename}: ${error.message}`);
342
return `<!-- Could not include ${filename} -->`;
343
}
344
}],
345
346
// Environment variable with fallback
347
[/__ENV:(\w+)(?::([^_]+))?__/g, (match, varName, fallback = '') => {
348
const value = process.env[varName];
349
if (value === undefined) {
350
console.warn(`Warning: Environment variable ${varName} is not defined`);
351
return fallback;
352
}
353
return value;
354
}]
355
]
356
});
357
```
358
359
## Types
360
361
```typescript { .api }
362
type Replace = Array<
363
| [string | RegExp, string]
364
| [RegExp, (substring: string, ...args: any[]) => string]
365
>;
366
367
interface ReplacementPattern {
368
/** String or RegExp to match */
369
0: string | RegExp;
370
371
/** Replacement string or function */
372
1: string | ((substring: string, ...args: any[]) => string);
373
}
374
```