Replace strings in files while bundling them with Rollup
npx @tessl/cli install tessl/npm-rollup-plugin-replace@1.2.00
# Rollup Plugin Replace
1
2
Rollup Plugin Replace is a Rollup plugin that performs string replacement during the bundling process. It allows developers to replace specific strings or patterns in their code at build time, making it ideal for environment variable injection, build-time configuration, and conditional compilation scenarios.
3
4
## Package Information
5
6
- **Package Name**: rollup-plugin-replace
7
- **Package Type**: npm
8
- **Language**: JavaScript (ES modules)
9
- **Installation**: `npm install --save-dev rollup-plugin-replace`
10
11
## Core Imports
12
13
```javascript
14
import replace from 'rollup-plugin-replace';
15
```
16
17
For CommonJS:
18
19
```javascript
20
const replace = require('rollup-plugin-replace');
21
```
22
23
## Basic Usage
24
25
```javascript
26
// rollup.config.js
27
import replace from 'rollup-plugin-replace';
28
29
export default {
30
input: 'src/main.js',
31
output: {
32
file: 'dist/bundle.js',
33
format: 'iife'
34
},
35
plugins: [
36
replace({
37
ENVIRONMENT: JSON.stringify('production'),
38
VERSION: JSON.stringify('1.0.0')
39
})
40
]
41
};
42
```
43
44
**Important**: The replace plugin should be placed before other plugins (like rollup-plugin-commonjs) in your plugins array to allow those plugins to apply optimizations such as dead code removal.
45
46
## Architecture
47
48
The plugin operates through a simple but effective architecture:
49
50
- **Filter System**: Uses rollup-pluginutils to create include/exclude filters for file processing
51
- **Pattern Matching**: Builds optimized regex patterns from replacement keys, sorted by length for longest-first matching
52
- **Magic String Integration**: Leverages magic-string library for precise source transformations with source map support
53
- **Lazy Evaluation**: Converts all replacement values to functions for consistent handling and dynamic evaluation
54
- **Transform Pipeline**: Processes files during Rollup's transform phase, returning null for unchanged files to optimize performance
55
56
The plugin's core algorithm escapes special characters in both delimiters and replacement keys, ensuring reliable pattern matching even with complex replacement scenarios.
57
58
## Capabilities
59
60
### Plugin Factory Function
61
62
Creates a Rollup plugin instance configured for string replacement.
63
64
```javascript { .api }
65
/**
66
* Creates a Rollup plugin for string replacement during bundling
67
* @param options - Configuration object for replacement settings
68
* @returns Rollup plugin object with name and transform methods
69
*/
70
function replace(options = {}): RollupPlugin;
71
72
interface RollupPlugin {
73
/** Plugin identifier */
74
name: string;
75
/** Transform function that processes file contents */
76
transform(code: string, id: string): TransformResult | null;
77
}
78
79
interface TransformResult {
80
/** Transformed code */
81
code: string;
82
/** Source map (if sourceMap option is not false) */
83
map?: object;
84
}
85
```
86
87
### Configuration Options
88
89
The options object supports the following properties:
90
91
```javascript { .api }
92
interface ReplaceOptions {
93
/** Minimatch pattern or array of patterns for files to include */
94
include?: string | string[];
95
/** Minimatch pattern or array of patterns for files to exclude */
96
exclude?: string | string[];
97
/** Custom delimiters for replacement patterns [prefix, suffix] */
98
delimiters?: [string, string];
99
/** Whether to generate source maps (default: true) */
100
sourceMap?: boolean;
101
/** Object containing replacement key-value pairs */
102
values?: { [key: string]: string | ReplacementFunction };
103
/** Direct replacement properties (when values is not specified) */
104
[key: string]: string | ReplacementFunction | any;
105
}
106
107
type ReplacementFunction = (id: string) => string;
108
```
109
110
**Usage Examples:**
111
112
```javascript
113
// Basic string replacements
114
replace({
115
ENVIRONMENT: JSON.stringify('production'),
116
API_URL: JSON.stringify('https://api.example.com')
117
})
118
119
// File filtering
120
replace({
121
include: 'src/**/*.js',
122
exclude: 'node_modules/**',
123
DEBUG: 'false'
124
})
125
126
// Custom delimiters
127
replace({
128
delimiters: ['<@', '@>'],
129
VERSION: '1.0.0'
130
// Replaces <@VERSION@> instead of VERSION
131
})
132
133
// Function-based replacements
134
replace({
135
__dirname: (id) => `'${path.dirname(id)}'`,
136
__filename: (id) => `'${id}'`
137
})
138
139
// Using values object
140
replace({
141
include: '**/*.js',
142
sourceMap: false,
143
values: {
144
ENVIRONMENT: JSON.stringify('development'),
145
DEBUG: 'true'
146
}
147
})
148
149
// Special characters in replacement keys
150
replace({
151
"require('config')": "require('./config-prod')",
152
"process.env.NODE_ENV": JSON.stringify('production')
153
})
154
```
155
156
### File Filtering
157
158
Control which files are processed using include/exclude patterns:
159
160
```javascript { .api }
161
interface FileFilterOptions {
162
/** Include files matching these minimatch patterns */
163
include?: string | string[];
164
/** Exclude files matching these minimatch patterns */
165
exclude?: string | string[];
166
}
167
```
168
169
- Uses minimatch patterns for file matching
170
- If `include` is omitted, all files are processed by default
171
- `exclude` patterns take precedence over `include` patterns
172
- Patterns are relative to the project root
173
174
### Replacement Delimiters
175
176
Customize the delimiters used for pattern matching:
177
178
```javascript { .api }
179
interface DelimiterOptions {
180
/** Custom delimiters as [prefix, suffix] array */
181
delimiters?: [string, string];
182
}
183
```
184
185
- Default delimiters: `['', '']` (matches exact strings)
186
- Custom delimiters wrap replacement keys: `delimiters: ['<@', '@>']`
187
- Useful for avoiding conflicts with existing code patterns
188
- Delimiters are escaped for regex usage
189
190
### Replacement Values
191
192
Define what strings should be replaced and their replacement values:
193
194
```javascript { .api }
195
type ReplacementValue = string | ReplacementFunction;
196
type ReplacementFunction = (id: string) => string;
197
198
interface ReplacementConfig {
199
/** Organized replacement values */
200
values?: { [key: string]: ReplacementValue };
201
/** Direct replacement properties (merged with options) */
202
[key: string]: ReplacementValue | any;
203
}
204
```
205
206
**Replacement Types:**
207
208
1. **Static strings**: Direct string replacement
209
```javascript
210
{ API_URL: JSON.stringify('https://api.prod.com') }
211
```
212
213
2. **Function replacements**: Dynamic replacement based on file ID
214
```javascript
215
{ __dirname: (id) => `'${path.dirname(id)}'` }
216
```
217
218
3. **Special characters**: Keys can contain regex special characters
219
```javascript
220
{ "require('dev-config')": "require('prod-config')" }
221
```
222
223
### Source Map Generation
224
225
Control source map generation for replaced content:
226
227
```javascript { .api }
228
interface SourceMapOptions {
229
/** Whether to generate source maps (default: true) */
230
sourceMap?: boolean;
231
}
232
```
233
234
- Source maps are generated by default using magic-string
235
- Set `sourceMap: false` to disable source map generation
236
- Source maps preserve original line/column information for debugging
237
238
## Advanced Usage Patterns
239
240
### Environment-Based Configuration
241
242
```javascript
243
replace({
244
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
245
'process.env.API_URL': JSON.stringify(
246
process.env.NODE_ENV === 'production'
247
? 'https://api.prod.com'
248
: 'https://api.dev.com'
249
)
250
})
251
```
252
253
### Conditional Compilation
254
255
```javascript
256
replace({
257
'__DEV__': process.env.NODE_ENV !== 'production',
258
'__PROD__': process.env.NODE_ENV === 'production'
259
})
260
```
261
262
### Dynamic Path Replacement
263
264
```javascript
265
replace({
266
'__filename': (id) => `'${path.relative(process.cwd(), id)}'`,
267
'__dirname': (id) => `'${path.relative(process.cwd(), path.dirname(id))}'`
268
})
269
```
270
271
### Build Information Injection
272
273
```javascript
274
replace({
275
BUILD_VERSION: JSON.stringify(require('./package.json').version),
276
BUILD_DATE: JSON.stringify(new Date().toISOString()),
277
COMMIT_HASH: JSON.stringify(process.env.GIT_COMMIT || 'unknown')
278
})
279
```
280
281
## Types
282
283
```javascript { .api }
284
interface RollupPlugin {
285
/** Plugin identifier, always 'replace' */
286
name: string;
287
/**
288
* Transform function that processes file contents
289
* @param code - Source code of the file
290
* @param id - File path/identifier
291
* @returns Transform result or null if no changes
292
*/
293
transform(code: string, id: string): TransformResult | null;
294
}
295
296
interface TransformResult {
297
/** Transformed source code */
298
code: string;
299
/** Source map object (if sourceMap is not false) */
300
map?: object;
301
}
302
303
interface ReplaceOptions {
304
/** File inclusion patterns */
305
include?: string | string[];
306
/** File exclusion patterns */
307
exclude?: string | string[];
308
/** Custom replacement delimiters */
309
delimiters?: [string, string];
310
/** Source map generation flag */
311
sourceMap?: boolean;
312
/** Replacement values object */
313
values?: { [key: string]: string | ReplacementFunction };
314
/** Direct replacement properties */
315
[key: string]: any;
316
}
317
318
type ReplacementFunction = (id: string) => string;
319
```