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:
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包保存在源目录中?