9

我正在使用带有 browserify 和 factor-bundle 的 gulp。我有以下代码:

b = browserify({
        entries: [ 'a.js', 'b.js'],
        plugin: [ [ 'factor-bundle', { outputs: [ 'build/a.js', 'build/b.js' ] } ] ]
    })
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(buffer())
    .pipe(gulp.dest('/build/common'));

我想在 parial 包('build/a.js' 和 'build/b.js')上传递一些操作(如 uglify、bundle-collapser 或其他作业)。我尝试使用因子捆绑页面上描述的方法:

b.plugin('factor-bundle', { outputs: [ write('x'), write('y') ] });
function write (name) {
    return concat(function (body) {
        console.log('// ----- ' + name + ' -----');
        console.log(body.toString('utf8'));
    });
}

但是我不了解 write() 方法,也不知道如何执行 uglification 以及如何 gulp.dest 结果。
任何想法?解释?

4

2 回答 2

11

write()方法返回一个可写流,允许您通过进一步的下游转换来管道化由 factor-bundle 插件生成的包。

例如,您的write()方法可能如下所示:

var path = require('path');
var file = require('gulp-file');
var sourcemaps = require('gulp-sourcemaps');

function write (filepath) {    
    return concat(function (content) {        
        // create new vinyl file from content and use the basename of the
        // filepath in scope as its basename.
        return file(path.basename(filepath), content, { src: true })
        // uglify content
        .pipe(uglify())
        // write content to build directory
        .pipe(gulp.dest('./build/scripts'))        
    });
}

你会像这样使用它:

browserify({
    entries: [ 'a.js', 'b.js'],
    plugin: [ [ 'factor-bundle', { outputs: [ write('a.js'), write('b.js') ] } ] ]
})
.bundle()
.pipe(write('common.js'))
// Could have use these instead, but it wouldn't be as DRY.
// .pipe(source('common.js'))
// .pipe(uglify())
// .pipe(gulp.dest('./build/scripts'))

使用factor-bundle插件会影响 browserify .bundle()调用后的输出。通常,它会生成捆绑包作为映射到每个入口文件的可读流,然后您就可以对它们应用进一步的转换。

相反,您将获得一个单一的可读流,其中包含一个包含来自提供的条目文件的共享公共模块的包,我 common.js在上面的示例中调用了它。然后,您需要分别处理映射到每个条目文件的可读流的转换。

在上面的示例中,我将可写流添加到输出数组中,排列顺序与我的入口文件相同,它们将各自的包作为可读流接收并对其应用进一步的转换

您还可以利用该factor.pipeline 事件

var b = browserify({ ... });

b.on('factor.pipeline', function (id, pipeline) {
    pipeline.get('wrap').push(write(id));
});

b.plugin(factor);

return b.bundle().pipe(write('common.js'));

我认为值得注意的是,将进一步的下游工作应用于输出完全脱离了管道。因此,如果您使用 gulp 并从 browserify 返回流,则该任务将提前完成,因为它仍在对入口文件执行操作。我还没有遇到这个问题。

希望这可以帮助。

于 2015-02-18T04:22:08.507 回答
0

这有点旧,但它可能对其他人有用。@Christian 上面的回答帮助了我,但我必须解决任务完成的问题。我通过为打开的流添加一个计数器来做到这一点,并在它们全部关闭后调用任务回调。

gulp.task('build:js:compile', function(cb) {

const apps  = getAllJavascriptFilesPaths(); // this returns an array of full path to the js files i want to bundle
const dist  = 'dist'; // the output path

const files = [];
const streams = [];
let openedStreams = 0;

// We use browserify factor-bundle to get the shared code in a separated js file, and not in all apps files
// The write function here handles the post processing of each browserified app by returning a writable stream
// We check the number of opened streams, and call the callback once they are all closed, to be sure the task is
// complete
function write(filepath) {
    openedStreams++;
    return concat(function (content) {
        // create new vinyl file from content and use the basename of the
        // filepath in scope as its basename.
        return file(path.basename(filepath), content, { src: true })
            .pipe(uglify())
            .pipe(gulp.dest(dist))
            .on('finish', function () {
                openedStreams--;
                if (openedStreams == 0) {
                    cb();
                }
            });
    });
}

apps.forEach(function (file) {
    files.push(file);
    streams.push(write(file)));
});

browserify(files)
    .plugin(factor, { outputs: streams })
    .transform("babelify", {presets: 'babel-preset-env'})
    .bundle()
    .pipe(write('common.js'));
});
于 2019-07-13T20:57:49.870 回答