fs.readdirでサブディレクトリを含む全てのファイルをBrowserfyに渡す

こちらで残課題となっていた、サブフォルダ以下の.jsファイルについてもBrowserifyするためgulpfile.jsを修正する。

fsで再帰的にファイルを読むには

こちらにも、同じような質問が挙げられている。
実は私の勘違いで、fs.readdirはちゃんとサブフォルダのファイルも処理してくれるのだが
非同期で行われる処理の中にreturn browserify()をしてしまっていたため
最初のコールバック実行中にgulp.task()が値を返して終了してしまっていたことが原因だった。

とはいえ、fs.readdir()ではなかなか直感的な書き方ができないので、以下の様に書き直した。

/// gulp browserify
gulp.task('browserify', [ 'transpile' ], function() {

    // https://stackoverflow.com/questions/5827612/node-js-fs-readdir-recursive-directory-search
    var walk = function(dir) {
        var files = [];
        var list = fs.readdirSync(dir);
        list.forEach(function(node) {
            var item = path.join(dir, node);
            var stat = fs.statSync(item);
            if(stat && stat.isDirectory()) {
                files = files.concat(walk(item));
            }
            else {
                files.push(item);
            }
        });
        return files;
    };

    var filesToBeBundled = [];
    var filesAll = walk(JS_SRC_DIR_PATH);
    var regexJS = new RegExp('.+\.js$');
    var regexes = [];
    INPUT_EXCEPTION_PATTERNS.forEach(function(pattern) {
        regexes.push(new RegExp(pattern));
    });

    filesAll.forEach(function(file) {
        var matched = false;
        if(regexJS.test(file)) {
            regexes.forEach(function(r) {
                matched |= r.test(file);
            });
            if(!matched) {
                filesToBeBundled.push(file);
            }
        }
    });

    return browserify({
            entries: filesToBeBundled,
            debug: true
        })
        .bundle()
        .pipe(vinylSourceStream(path.basename(OUTPUT_FILE_PATH)))
        .pipe(vinylBuffer())
        .pipe(gulpSourceMaps.init({ loadMaps: true }))
        .pipe(gulpSourceMaps.mapSources(function(pathSource, file) {
            if((new RegExp('^(\./)*node_modules/')).test(pathSource)) {
                return pathSource;
            }

            var pathMapSources = [];
            var map = JSON.parse(fs.readFileSync(path.join(file.cwd, (pathSource + '.map'))));
            map.sources.forEach(function(s) {
                var pathRelative = path.join(path.dirname(pathSource), path.join(map.sourceRoot, s));
                pathMapSources.push(pathRelative);
            });

            if(pathMapSources.length > 1) {
                throw (new Error());
            }
            return pathMapSources[0];
        }))
        .pipe(gulpSourceMaps.write('.', {
            includeContent: false,
            sourceRoot: function(file) {
                return path.relative(path.dirname(OUTPUT_FILE_PATH), '.');
            }
        }))
        .pipe(gulp.dest(path.dirname(OUTPUT_FILE_PATH)));
});

あまり推奨されてはいないがfs.readdirSync()を使って同期的に処理を行うようにしている。
高々3ファイルの現時点でもすでに問題になっているが、やはりビルドに時間がかかるので、今度はビルド時間を何とかしないと。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です