How to save Gulp bundle in the source directory?

I am following the Fast browserify builds with watchify recipe and get it working, but would like my bundles to be written to the original source folder.

For example, I have the following code (taken directly from the recipe, but modified slightly)

// add custom browserify options here
var customOpts = {
    entries: glob.sync("./dev/www/**/*-root.js"),
    debug: true
};
var opts = _.assign({}, watchify.args, customOpts);
var b = watchify(browserify(opts)); 



gulp.task('js', bundle); // so you can run `gulp js` to build the file
b.on('update', bundle); // on any dep update, runs the bundler
b.on('log', gutil.log); // output build logs to terminal


function bundle() {
    return b.bundle()
    // log errors if they happen
        .on('error', gutil.log.bind(gutil, 'Browserify Error'))
        .pipe(source('bundle.js'))
    // optional, remove if you don't need to buffer file contents
        .pipe(buffer())
    // optional, remove if you dont want sourcemaps
        .pipe(sourcemaps.init({ loadMaps: true })) // loads map from browserify file
    // Add transformation tasks to the pipeline here.
        .pipe(sourcemaps.write('./')) // writes .map file
        .pipe(gulp.dest((file) => {return file.base;}));
        //.pipe(gulp.dest('./dist'));
}

as you can see in the entries: glob.sync("./dev/www/**/*-root.js"), line, I am scanning for multiple files to be bundled.

The problem I am encountering is the .pipe(gulp.dest((_file: any) => {return file.base;})); line, which returns the root project folder's path, not the original source folder's path.

How can I obtain the source folder path for writing to?

Edit

I found http://fettblog.eu/gulp-browserify-multiple-bundles/ which describes how to create multiple bundles, but it doesn't use watchify. it looks like this issue might be a limitation of vinyl-source-stream?


It took a lot of effort, but I figured out a solution.

Generally I followed the pattern found at http://fettblog.eu/gulp-browserify-multiple-bundles/ but added caching of each browserify object created (one per page) plus added watchify to it.

Other things added in the following code:

  • livereload
  • dev server launch
  • typescript (tsx) compile (including chained sourcemaps)
  • full solution (typescript code):

    import gulp = require("gulp");
    import browserify = require("browserify");
    var watchify = require("watchify");
    
    import source = require("vinyl-source-stream");
    
    import buffer = require("vinyl-buffer");
    
    
    import gutil = require("gulp-util");
    import sourcemaps = require("gulp-sourcemaps");
    var sourcemapsApply = require("vinyl-sourcemaps-apply");
    
    import _ = require("lodash");
    
    
    import glob = require("glob");
    import vinyl = require("vinyl");
    
    
    import rename = require("gulp-rename");
    
    var minifyify = require("minifyify");
    
    import path = require("path");
    
    var tsify = require("tsify");
    
    
    var livereload = require("gulp-livereload");
    var notify = require("gulp-notify");
    
    var closureCompiler = require("gulp-closure-compiler");
    
    import uglify = require("gulp-uglify");
    import http = require("http");
    var st = require("st");  //module for serving static files.  used to create dev server.   https://www.npmjs.com/package/st
    
    var eventStream = require("event-stream"); //module for merging multiple vinyl streams to return one when finishing task.   see http://fettblog.eu/gulp-browserify-multiple-bundles/
    
    var rootPath = __dirname;
    
    gulp.task("default", () => {
        gulp.start("tsxDevWatch");
    });
    
    
    gulp.task("devServer", (done) => {
    
        var rootPath = __dirname;
        //start server
        http.createServer(st({
            path: rootPath,
            index: true, //"index.html",
            cache: false,
        })).listen(8080,"localhost", done);
    
    });
    
    gulp.task("tsxDevWatch",["devServer"], () => {
    
    
    
        livereload.listen();
    
        //browserify+watchify of *-main.js files and compiles into *-main.bundle.js files IN SAME FOLDER
    
        //created mostly following the pattern described here: http://fettblog.eu/gulp-browserify-multiple-bundles/
        //but adds stupid source-filepath workaround for use with "source" (vinyl-source-stream needed for watchify)
    
        /** the files we are going to browserify bundle*/
        var entries = glob.sync("./dev/www/**/*-main.tsx", {
            realpath: true, //so paths are absolute.  This is required so our "bMaps" mappings stay intact, because watchify.on("update") always provides full filepath, 
        });
        /** we create one browserify instance for each file we are bundling.  this caches the browserify instance so it can be reused on watchify updates (decreasing compile time by A LOT) */
        var bMaps: { [key: string]: BrowserifyObject } = {};
    
        var tasks = entries.map((entry) => {    
            process.chdir(path.dirname(entry));
    
            var browserifyOptions = {
                entries: [entry],
                debug: true,
                plugin: [
                    watchify,
                    //tsify,
                ],
                cache: {}, packageCache: {}, fullPaths: true // Requirement of watchify
            };
            var b = browserify(browserifyOptions);
    
    
            b.plugin(tsify, { //options from here: http://json.schemastore.org/tsconfig
                jsx: "react",
                //inlineSourceMap: false,  //sourcemap options don't seem to matter, seems to be set by browserify or something.
                //sourceMap:true,
                module: "commonjs",
                target: "es5",
            });
    
            bMaps[entry] = b;
    
            b.on('update', (updatedFiles: string[]) => {
                console.log("!!!!!!!!!!!!!! n!!!!!!!!!!!!!!!!!!!n UPDATE CALLED FOR", JSON.stringify(updatedFiles));
    
                var rebuildAll = false;
                _.forEach(updatedFiles, (updatedFile) => {
                    if (bMaps[updatedFile] == null) {
                        //a dependency needs to be rebuilt, skip rebuilding anything that changed and do EVERYTHING
                        rebuildAll = true;
                        return false;
                    }
                });
    
                if (rebuildAll === false) {
                    _.forEach(updatedFiles, (updatedFile) => {
                        console.log(" ============= update()", updatedFile);
                        //find the b for this file
                        var _b = bMaps[updatedFile];
                        //do a bundle for it
                        _createTsXBundle(_b, updatedFile);
    
                    });
                } else {
                    //this is a dependency, rebuild EVERYTHING!!!
                    _.forEach(bMaps, (value_b, key_entry) => {
                        _createTsXBundle(value_b, key_entry);
                    });
                }
    
            }); // on any dep update, runs the bundler
            b.on('log', gutil.log); // output build logs to terminal
    
            return _createTsXBundle(b, entry);
        });
    
        return eventStream.merge.apply(null, tasks);
    });
    
    /** worker to create a tsx bundle.  used by a task  */
    function _createTsXBundle(b: BrowserifyObject, entry: string) {
        process.chdir(path.dirname(entry));
        console.log("================= doBundle()", entry);
    
        var bundledStream = b.bundle();
        bundledStream = <any>bundledStream.on('error', gutil.log.bind(gutil, 'Browserify Error'));
    
        var currentSource: vinyl;
    
        var targetName = path.basename(entry, ".tsx") + ".bundle.js";
        bundledStream
            .pipe(source(targetName))
            .pipe(buffer()) //need this to support chaining our vinyl source file
    
        ////////////////////////////////////////
        //// optional, remove if you dont want sourcemaps
        //  .pipe(sourcemaps.init({
        //      loadMaps: true,
        //      //debug: true
        //  })) // loads map from browserify file
    
        /////////////////////////  WORKS, BUT NEED TO ENABLE SOURCEMAPS plugin TO GET SOURCEMAPS
        //// uglify
        //.pipe(uglify({
        //  //preserveComments: "all",              
        //  output:<any> {
        //      max_line_len: 300,
        //      //screw_ie8: false,
        //      //beautify: true,
        //      //comments: true,
        //      //bracketize: true,
        //      //quote_keys: true,
        //      //width: 120,
        //      //semicolons:true,
        //  },
        //  compress: {
        //      unsafe:true,
        //  },
        //}))
    
        //// Add transformation tasks to the pipeline here.
        //  .pipe(sourcemaps.write())
    
            .pipe(gulp.dest((file: vinyl) => {
                //console.log("GULP.DEST(file)n base=", file.base, "n cwd=", file.cwd, "n path=", file.path, "n relative=", file.relative);
                return file.base;
            }))
            .pipe(livereload())
    
        ;
    
        return bundledStream;
    }
    
    链接地址: http://www.djcxy.com/p/32958.html

    上一篇: 在一个流中合并多个浏览器包

    下一篇: 如何将Gulp包保存在源目录中?