How to bundle typescript files for the browser use

2019-02-27 17:56发布

问题:

I'm kinda new to front end development, being a long time backend C# and Java developer, and I'm trying to come to grips with how to build front end applications. I would like to build an application using typescript and use gulp for my build pipeline to transpile, bundle and minify my code to a single JavaScript file.

For this purpose, I have been looking at the node module tsproject which, as far as I can understand, is supposed to do exactly what I want. Except, I can't get it to do what I want :-(.

This is the relevant parts my gulpfile.js:

var gulp = require('gulp');
var clean = require('gulp-clean');
var tsproject = require('tsproject');

gulp.task('default', [ 'min-js' ]);

gulp.task('clean', function () {
    return gulp
        .src('./dist/', { read: false })
        .pipe(clean());
});

gulp.task('min-js', [ 'clean' ], function () {
    return tsproject
        .src('./tsconfig.json')
        .pipe(gulp.dest('./dist/js'))
});

And my tsconfig.json:

{
    "compilerOptions": {
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react",
        "outDir": "./"
    },
    "files": [
        "./src/**/*.tsx",
        "./src/**/*.ts"
    ],
    "bundles": {
        "myApp": {
            "files": [
                "./src/App.tsx"
            ],
            "config": {
                "minify": true,
                "sourcemap": true
            }
        }
    }
}

I had expected this to output a single js-file containing transpiled, bundled and minified JavaScript code but what I get is a bundled (not transpiled nor minified) Typescript file (./dist/js/myApp.min.ts).

Am I doing something wrong or have I completely misunderstood the purpose and intent of tsproject?

回答1:

Well, I'm not sure if this is the best way to go about it but I finally got things working with a gulpfile like this:

var gulp = require('gulp');
var browserify = require('gulp-browserify');
var clean = require('gulp-clean');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var ts = require('gulp-typescript');
var uglify = require('gulp-uglify');

gulp.task('default', [ 'min-js' ]);

gulp.task('clean', function () {
    return gulp
        .src([
            './tmp/',
            './dist/'
        ], { read: false })
        .pipe(clean());
});

gulp.task('transpile-ts', ['clean'], function () {
    var tsproject = ts.createProject('./src/tsconfig.json');
    return tsproject
        .src()
        .pipe(sourcemaps.init())
        .pipe(tsproject()).js
        .pipe(sourcemaps.write('./sourcemaps'))
        .pipe(gulp.dest('./tmp/js'));
});

gulp.task('min-js', [ 'transpile-ts' ], function () {
    return gulp
        .src('./tmp/js/App.js')
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(browserify())
        .pipe(uglify())
        .pipe(concat('App.min.js'))
        .pipe(sourcemaps.write('./sourcemaps'))
        .pipe(gulp.dest('./dist/js'))
});

Basically I transpile all TypeScript files to Javascript with CommonJS imports to a temporary directory. Then I use Browserify to bundle (i.e. resolve the CommonJS imports) the JavaScript files into a single file. Finally I minify the resulting JavaScript file. Voila!

For some reason I had to first write the transpiled files to a temporary directory and then bundle and minify those files. Instead of just keep on pipeing the result of pipe(tsproject()) to browserify()...