我正在关注Fast browserify builds with watchify recipe并让它正常运行,但希望将我的捆绑包写入原始源文件夹。
例如,我有以下代码(直接从配方中获取,但略有修改)
// 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'));
}
正如您在entries: glob.sync("./dev/www/**/*-root.js"),
行中看到的那样,我正在扫描要捆绑的多个文件。
我遇到的问题是.pipe(gulp.dest((_file: any) => {return file.base;}));
行,它返回根项目文件夹的路径,而不是原始源文件夹的路径。
如何获取写入的源文件夹路径?
我发现http://fettblog.eu/gulp-browserify-multiple-bundles/描述了如何创建多个捆绑包,但它并没有使用watchify。看起来这个问题可能是乙烯基源流的限制?
答案 0 :(得分:1)
花了很多功夫,但我想出了一个解决方案。
一般情况下,我遵循http://fettblog.eu/gulp-browserify-multiple-bundles/处找到的模式,但添加了每个创建的browserify对象的缓存(每页一个),并添加了watchify。
以下代码中添加了其他内容:
完整解决方案(打字稿代码):
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;
}