jonkemp / gulp-useref

Parse build blocks in HTML files to replace references to non-optimized scripts or stylesheets.
MIT License
705 stars 93 forks source link

Couple of html files and how to get list of files which included to assets #140

Closed tsarapke closed 8 years ago

tsarapke commented 8 years ago

If I use gulp-useref with couple of html files, it process each time with same bundles.

  1. Is there a way to process first incoming bundle and just replace string in other files? For example, if you look to code below - gulp-useref create vendor.js twice (at second time it rewrite previous file). If you have a lot of files and you use minification of css and js then it can take much time depending on how many html files with the same bundles you use.
  2. How I can copy other files, which not included to bundles?

Structure:

html-file-1.html

<!-- build:js js/vendor.js -->
<script scr="js/script-1.js"></script>
<script scr="js/script-2.js"></script>
<!-- endbuild -->
<script scr="js/file-1-script.js"></script>

html-file-2.html

<!-- build:js js/vendor.js -->
<script scr="js/script-1.js"></script>
<script scr="js/script-2.js"></script>
<!-- endbuild -->
<script scr="js/file-2-script.js"></script>

The general idea of task:

var files = [],
    getExcludedFiles = function() {
       var temp = files;
       for(var i = 0; i < temp.length; i++) {
          temp[i] = "!" + temp[i]
       }

       return temp;
    };

gulp.task("useref", function() {
   var assets = useref.assets();

   return gulp.src(path_to_htmls)
              .pipe(assests)
              .pipe(some_function_to_store_bundle_files_in_some_var)
              .pipe(gulpif('*.js', uglify()))
              .pipe(assets.restore())
              .pipe(useref())
              .pipe(gulp.dest(dets_path))
});

gulp.task("js", ["useref"], function() {
   return gulp.src([path_to_JS, getExcludedFiles()])
              .pipe(gulp.dest(JS_dets_path))
});
tsarapke commented 8 years ago

Currently, I found way how to get access to files, which were concatenated. In gulp-useref/index.js I added additional argument in exports which called "callback" and then call him.

    module.exports = function (opts, callback) {
        return through.obj(function (file, enc, cb) {
            if (file.isNull()) {
                cb(null, file);
                return;
            }

            if (file.isStream()) {
                cb(new gutil.PluginError('gulp-useref', 'Streaming not supported'));
                return;
            }

            var output = useref(file.contents.toString(), opts);

            callback(output[1]);

"output" have following structure:

    [ 
       resultHtml, 
       { 
         css: { 
           'css/combined.css': { 
             'assets': [ 'css/one.css', 'css/two.css' ] 
           } 
         }, 
         js: { 
           'scripts/combined.js': { 
             'assets': [ 'scripts/one.js', 'scripts/two.js' ] 
           }, 
           'scripts/async.js': { 
              'assets': [ 'scripts/three.js', 'scripts/four.js' ] 
            } 
         } 
       } 
    ]

Example of my tasks

[
"build/src/js/**/*.js",
"!build/src/js/**/file-1.js",
"!build/src/js/**/file-2.js",
...
"!build/src/js/**/file-n.js"
]
    var bundleFiles = {
        js: [],
        css: []
    };

    function getAssets(output, type) {
        if(output[type] !== undefined) {
            for(var key in output[type]) {
                for(var i = 0; i < output[type][key].assets.length; i++) {
                    bundleFiles[type].push(path.basename(output[type][key].assets[i]));
                }
            }
        }
        bundleFiles[type] = uniq(bundleFiles[type]); // lodash uniq method
    }

    function getExcludion(type, src, src_folder) {
        var excludion = bundleFiles[type];
        for(var i = 0; i < excludion.length; i++) {
            excludion[i] = "!" + path.join(src_folder, excludion[i]);
        }
        excludion.unshift(src);
        return excludion;
    }

    gulp.task("distribution", function () {
        var assets = useref.assets();

        return gulp.src(path_to_html)
            .pipe(assets)
            .pipe(gulpif('*.js', uglify()))
            .pipe(assets.restore())
            .pipe(useref(null, function(output) {
                getAssets(output, "js");
                getAssets(output, "css");
            }))
            .pipe(gulp.dest(config.root.dist));
    });

    gulp.task("js-dist", ["distribution"], function () {
        return gulp.src(getExcludion("js", path_to_all_js, path_to_js_folder))
            .pipe(gulp.dest(path_setup.dest));
    });

So, can you add possibility to get access to files, which participate in concatenation and resolve problem with couple of html files which contain same bundles?

jonkemp commented 8 years ago

Maybe https://github.com/contra/gulp-cached would work for you?

ryanwangtian commented 8 years ago

@tsarapke Hi, I have the same problem. Do you have a solution now?

tsarapke commented 8 years ago

@ryanwangtian Hi, I wrote about it in my second post here. It's not a good solution, or rather it is not even a solution. It is a crutch. But it works for me (it regard to list of used files).

jcristovao commented 8 years ago

I had a similar problem, just found this thread, but for me gulp-cached was quite enough: @jonkemp , thanks for the tip

jonkemp commented 8 years ago

There are other solutions as well for incremental builds:

https://github.com/gulpjs/gulp#incremental-builds