Browserifyでbundleしたファイルをconcatする
Browserifyでrequire
じゃなくて単にconcatしたいときがある。UMD対応してないライブラリを読み込むときとか、必ず最初に実行したい処理(ポリフィルとか)がある場合だ。
Webpackだと、以下のようにentry
に配列を指定すればconcatできる。
module.exports = { entry: [ 'picturefill', 'src/js/index.js', ], output: { filename: 'bundle.js', path: './dist', }, }
とはいえBrowserifyを使いたい。以下のようにしたら、Gulpでストリームとしていい感じに捌けた。
const gulp = require('gulp') const gutil = require('gulp-util') const sourcemaps = require('gulp-sourcemaps') const concat = require('gulp-concat') const uglify = require('gulp-uglify') const mergeStream = require('merge-stream') const browserify = require('browserify') const source = require('vinyl-source-stream') const buffer = require('vinyl-buffer') export const js = () => { const ENTRY_FILES = [ 'node_modules/picturefill/dist/picturefill.js', ] const bundler = browserify('src/js/index.js', { debug: true, }) const bundle = () => mergeStream( gulp.src(ENTRY_FILES), bundler .bundle() .on('error', err => gutil.log('Browserify Error', err)) .pipe(source('index.js')) .pipe(buffer()), ) .pipe(sourcemaps.init({loadMaps: true})) .pipe(concat('app.js')) .pipe(uglify({preserveComments: 'license'})) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('dist/js')) return bundle() }
追記:上記のやり方だとStreamの解決順にconcatされてしまうので絶対に安全では無い。Browserifyでbundleするよりもgulp.src
に時間がかかることはまずないけど、不安になるコードだった。gulp-headerとかでやったら良さそう。
const fs = require('fs') const gulp = require('gulp') const gutil = require('gulp-util') const sourcemaps = require('gulp-sourcemaps') const header = require('gulp-header') const uglify = require('gulp-uglify') const browserify = require('browserify') const source = require('vinyl-source-stream') const buffer = require('vinyl-buffer') export const js = () => { const ENTRY_FILES = [ 'node_modules/picturefill/dist/picturefill.js', ] const concatedScripts = ENTRY_FILES.map(file => fs.readFileSync(file, 'utf8')) .concat('') .join('\n') const bundler = browserify('src/js/index.js', { debug: true, }) const bundle = () => bundler .bundle() .on('error', err => gutil.log('Browserify Error', err)) .pipe(source('app.js')) .pipe(buffer()) .pipe(sourcemaps.init({loadMaps: true})) .pipe(header(concatedScripts)) .pipe(uglify({preserveComments: 'license'})) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('dist/js')) return bundle() }
これだと、ENTRY_FILES
のログがソースマップでうまいことできないけど、たぶんこっちのほうがよさげ。