0
# Build Tool Integration
1
2
Integration patterns and examples for using tsify with popular build tools and Browserify extensions.
3
4
## Capabilities
5
6
### Watchify Integration
7
8
Incremental compilation support using watchify for fast development builds.
9
10
```javascript { .api }
11
/**
12
* Watchify integration provides:
13
* - Incremental TypeScript compilation
14
* - File change detection
15
* - Fast rebuild times
16
* - Development server compatibility
17
*/
18
```
19
20
**Basic Watchify Setup:**
21
```javascript
22
const watchify = require('watchify');
23
const browserify = require('browserify');
24
const tsify = require('tsify');
25
26
const b = browserify({
27
entries: ['src/main.ts'],
28
cache: {}, // Required for watchify
29
packageCache: {}, // Required for watchify
30
plugin: [watchify]
31
});
32
33
b.plugin(tsify, {
34
target: 'es5',
35
strict: true
36
});
37
38
b.on('update', bundle); // Rebuild on file changes
39
b.on('log', console.log); // Log rebuild messages
40
41
function bundle() {
42
return b.bundle()
43
.on('error', console.error)
44
.pipe(fs.createWriteStream('dist/bundle.js'));
45
}
46
47
bundle(); // Initial build
48
```
49
50
**Advanced Watchify with Error Recovery:**
51
```javascript
52
const fs = require('fs');
53
const path = require('path');
54
55
function createWatcher(entryFile, outputFile) {
56
const b = browserify({
57
entries: [entryFile],
58
cache: {},
59
packageCache: {},
60
plugin: [watchify],
61
debug: true // Enable source maps
62
});
63
64
b.plugin(tsify, {
65
project: './tsconfig.json'
66
});
67
68
let building = false;
69
70
b.on('update', function(files) {
71
console.log('Files changed:', files);
72
bundle();
73
});
74
75
b.on('log', function(msg) {
76
console.log('Watchify:', msg);
77
});
78
79
function bundle() {
80
if (building) return;
81
building = true;
82
83
const start = Date.now();
84
console.log('Building...');
85
86
const stream = b.bundle();
87
88
stream.on('error', function(error) {
89
console.error('Build failed:', error.message);
90
building = false;
91
});
92
93
stream.on('end', function() {
94
const time = Date.now() - start;
95
console.log(`Build completed in ${time}ms`);
96
building = false;
97
});
98
99
return stream.pipe(fs.createWriteStream(outputFile));
100
}
101
102
return { bundle, browserify: b };
103
}
104
105
// Usage
106
const watcher = createWatcher('src/main.ts', 'dist/bundle.js');
107
watcher.bundle();
108
```
109
110
### Gulp Integration
111
112
Integration with Gulp build system for complex build pipelines.
113
114
```javascript { .api }
115
/**
116
* Gulp integration provides:
117
* - Stream-based processing
118
* - Task orchestration
119
* - Multiple output formats
120
* - Development/production modes
121
*/
122
```
123
124
**Basic Gulp Task:**
125
```javascript
126
const gulp = require('gulp');
127
const browserify = require('browserify');
128
const tsify = require('tsify');
129
const source = require('vinyl-source-stream');
130
const buffer = require('vinyl-buffer');
131
const uglify = require('gulp-uglify');
132
const sourcemaps = require('gulp-sourcemaps');
133
134
gulp.task('typescript', function() {
135
return browserify({
136
entries: 'src/main.ts',
137
debug: true
138
})
139
.plugin(tsify, {
140
target: 'es5',
141
strict: true
142
})
143
.bundle()
144
.pipe(source('bundle.js'))
145
.pipe(buffer())
146
.pipe(sourcemaps.init({ loadMaps: true }))
147
.pipe(uglify())
148
.pipe(sourcemaps.write('./'))
149
.pipe(gulp.dest('dist'));
150
});
151
```
152
153
**Gulp with Multiple Entries:**
154
```javascript
155
const merge = require('merge2');
156
157
gulp.task('build-all', function() {
158
const entries = ['src/main.ts', 'src/worker.ts'];
159
160
const tasks = entries.map(function(entry) {
161
const filename = path.basename(entry, '.ts') + '.js';
162
163
return browserify({ entries: entry, debug: true })
164
.plugin(tsify)
165
.bundle()
166
.pipe(source(filename))
167
.pipe(buffer())
168
.pipe(gulp.dest('dist'));
169
});
170
171
return merge(tasks);
172
});
173
```
174
175
**Gulp Development Server:**
176
```javascript
177
const connect = require('gulp-connect');
178
179
gulp.task('serve', ['typescript'], function() {
180
connect.server({
181
root: 'dist',
182
livereload: true,
183
port: 8080
184
});
185
186
gulp.watch('src/**/*.ts', ['typescript']);
187
});
188
189
gulp.task('typescript', function() {
190
return browserify({
191
entries: 'src/main.ts',
192
debug: true
193
})
194
.plugin(tsify)
195
.bundle()
196
.on('error', function(error) {
197
console.error('TypeScript Error:', error.message);
198
this.emit('end');
199
})
200
.pipe(source('bundle.js'))
201
.pipe(gulp.dest('dist'))
202
.pipe(connect.reload());
203
});
204
```
205
206
### Grunt Integration
207
208
Integration with Grunt task runner using grunt-browserify.
209
210
```javascript { .api }
211
/**
212
* Grunt integration provides:
213
* - Task configuration
214
* - File watching
215
* - Multi-target builds
216
* - Plugin ecosystem compatibility
217
*/
218
```
219
220
**Gruntfile.js Configuration:**
221
```javascript
222
module.exports = function(grunt) {
223
grunt.initConfig({
224
browserify: {
225
dev: {
226
src: 'src/main.ts',
227
dest: 'dist/bundle.js',
228
options: {
229
plugin: [
230
['tsify', {
231
target: 'es5',
232
strict: true
233
}]
234
],
235
debug: true
236
}
237
},
238
prod: {
239
src: 'src/main.ts',
240
dest: 'dist/bundle.min.js',
241
options: {
242
plugin: [
243
['tsify', {
244
target: 'es5',
245
strict: true,
246
removeComments: true
247
}]
248
]
249
}
250
}
251
},
252
253
watch: {
254
typescript: {
255
files: ['src/**/*.ts'],
256
tasks: ['browserify:dev']
257
}
258
}
259
});
260
261
grunt.loadNpmTasks('grunt-browserify');
262
grunt.loadNpmTasks('grunt-contrib-watch');
263
264
grunt.registerTask('default', ['browserify:dev']);
265
grunt.registerTask('build', ['browserify:prod']);
266
grunt.registerTask('dev', ['browserify:dev', 'watch']);
267
};
268
```
269
270
### Webpack Migration
271
272
Guidance for projects migrating from webpack to Browserify + tsify.
273
274
**Webpack ts-loader equivalent:**
275
```javascript
276
// webpack.config.js (old)
277
module.exports = {
278
entry: './src/main.ts',
279
module: {
280
rules: [{
281
test: /\.tsx?$/,
282
use: 'ts-loader',
283
exclude: /node_modules/
284
}]
285
}
286
};
287
288
// Browserify equivalent
289
browserify('src/main.ts')
290
.plugin(tsify, {
291
exclude: ['node_modules/**']
292
})
293
.bundle();
294
```
295
296
### Babel Integration
297
298
Using tsify with Babelify for modern JavaScript features.
299
300
```javascript { .api }
301
/**
302
* Babel integration for:
303
* - ES6+ syntax transformation
304
* - JSX processing (alternative to TypeScript JSX)
305
* - Polyfill injection
306
* - Plugin ecosystem access
307
*/
308
```
309
310
**ES6 Output with Babel:**
311
```javascript
312
const babelify = require('babelify');
313
314
browserify('src/main.ts')
315
.plugin(tsify, {
316
target: 'es6', // Output ES6 from TypeScript
317
module: 'es6'
318
})
319
.transform(babelify, {
320
extensions: ['.tsx', '.ts'],
321
presets: ['@babel/preset-env'],
322
plugins: ['@babel/plugin-proposal-class-properties']
323
})
324
.bundle();
325
```
326
327
**React/JSX with Babel:**
328
```javascript
329
browserify('src/App.tsx')
330
.plugin(tsify, {
331
jsx: 'preserve', // Let Babel handle JSX
332
target: 'es6'
333
})
334
.transform(babelify, {
335
extensions: ['.tsx', '.ts'],
336
presets: [
337
'@babel/preset-env',
338
'@babel/preset-react'
339
]
340
})
341
.bundle();
342
```
343
344
### Testing Integration
345
346
Integration with testing frameworks and tools.
347
348
**Jest Configuration:**
349
```javascript
350
// jest.config.js
351
module.exports = {
352
preset: 'ts-jest',
353
testEnvironment: 'node',
354
setupFilesAfterEnv: ['<rootDir>/test/setup.js'],
355
collectCoverageFrom: [
356
'src/**/*.ts',
357
'!src/**/*.test.ts'
358
]
359
};
360
```
361
362
**Karma + Browserify:**
363
```javascript
364
// karma.conf.js
365
module.exports = function(config) {
366
config.set({
367
frameworks: ['browserify', 'mocha'],
368
files: [
369
'test/**/*.ts'
370
],
371
preprocessors: {
372
'test/**/*.ts': ['browserify']
373
},
374
browserify: {
375
plugin: [
376
['tsify', {
377
target: 'es5'
378
}]
379
],
380
debug: true
381
}
382
});
383
};
384
```
385
386
### Development Server Integration
387
388
Integration with development servers and hot reloading.
389
390
**Express Development Server:**
391
```javascript
392
const express = require('express');
393
const browserify = require('browserify');
394
const tsify = require('tsify');
395
396
const app = express();
397
398
app.get('/bundle.js', function(req, res) {
399
res.setHeader('Content-Type', 'application/javascript');
400
401
browserify('src/main.ts')
402
.plugin(tsify, { target: 'es5' })
403
.bundle()
404
.on('error', function(error) {
405
console.error('TypeScript Error:', error.message);
406
res.status(500).send(`console.error(${JSON.stringify(error.message)});`);
407
})
408
.pipe(res);
409
});
410
411
app.use(express.static('public'));
412
app.listen(3000);
413
```
414
415
## Types
416
417
```typescript { .api }
418
interface IntegrationOptions {
419
/** Watchify-specific options */
420
watchify?: {
421
ignoreWatch?: string[];
422
poll?: boolean | number;
423
};
424
425
/** Gulp stream options */
426
gulp?: {
427
sourcemaps?: boolean;
428
minify?: boolean;
429
livereload?: boolean;
430
};
431
432
/** Development server options */
433
devServer?: {
434
port?: number;
435
host?: string;
436
hot?: boolean;
437
};
438
}
439
440
interface BuildContext {
441
/** Build mode (development/production) */
442
mode: 'development' | 'production';
443
/** Source map generation */
444
sourceMap: boolean;
445
/** Output directory */
446
outputDir: string;
447
/** Entry points */
448
entries: string[];
449
}
450
```