2

I'm aware this has probably been asked before, but I can't seem to be able to ask Google the right questions to find what I need. So I'm possibly thinking about this in the wrong way.

Basically, I need to know if there is a way to use Gulp with Bower so that all css files in subdirectories under bower_components are combined into one styles.css, all js files in subdirectories under bower_components are combined into one scripts.js. Kind of how assetic works in symfony2 to combine assets into single files. Does each 'built' file in each bower_componets subdirectory have to be linked to manually (in the Gulp config file), or is it more common to loop through them programatically?

Thanks

timhc22
  • 7,213
  • 8
  • 48
  • 66
  • You could use `gulp-concat` for both the CSS and JS, if you define them as separate tasks. For listing the bower components you need, it's wise to do this manually, this way you know exactly what you're using. – Tony Barnes Mar 24 '15 at 16:40
  • It's a bad idea to automate this. It takes 20seconds to run a `bower install ____ --save` command and manually add the js and css path to your build process. Look at bootstrap for example, there is duplication between bootstrap.js, bootstrap.min.js, and the individual component files. Including them all would be confusing and a waste of bandwidth. You could try something like [gulp-useref](https://www.npmjs.com/package/gulp-useref) to make the concatenation process simpler. Manually specify the order and path of files to be included for assets. Automating this will only invite problems – deefour Mar 25 '15 at 01:51
  • what I mean is condensing bootstrap's js and tinymce's js and ... etc into one minified file to be included (as oppose to all individual component files within bootstrap) – timhc22 Apr 02 '15 at 13:31
  • useref looks like it may be helpful. I have found myself using npm instead of bower though (I know that is a different argument altogether) but with browserify I can just say which libraries I want to be included with my project and it handles including and condensing automatically – timhc22 Apr 02 '15 at 13:35

4 Answers4

1

Would something like the below help? It loops through all css files in my 'src' directory and spits out one css file in the 'dist' folder. It does the same for my js files:

// Config
var requireJsRuntimeConfig = vm.runInNewContext(fs.readFileSync('src/app/require.config.js') + '; require;');
    requireJsOptimizerConfig = merge(requireJsRuntimeConfig, {
        out: 'scripts.js',
        baseUrl: './src',
        name: 'app/startup',
        paths: {
            requireLib: 'bower_modules/requirejs/require'
        },
        include: [
            'requireLib',
            'components/nav-bar/nav-bar',
            'components/home-page/home',
            'text!components/about-page/about.html'
        ],
        insertRequire: ['app/startup'],
        bundles: {
            // If you want parts of the site to load on demand, remove them from the 'include' list
            // above, and group them into bundles here.
            // 'bundle-name': [ 'some/module', 'another/module' ],
            // 'another-bundle-name': [ 'yet-another-module' ]
        }
    });

    // Discovers all AMD dependencies, concatenates together all required .js files, minifies them
    gulp.task('js', function () {
        return rjs(requireJsOptimizerConfig)
            .pipe(uglify({ preserveComments: 'some' }))
            .pipe(gulp.dest('./dist/'));
    });

    // Concatenates CSS files, rewrites relative paths to Bootstrap fonts, copies Bootstrap fonts
    gulp.task('css', function () {
        var bowerCss = gulp.src('src/bower_modules/components-bootstrap/css/bootstrap.min.css')
                .pipe(replace(/url\((')?\.\.\/fonts\//g, 'url($1fonts/')),
            appCss = gulp.src('src/css/*.css'),
            combinedCss = es.concat(bowerCss, appCss).pipe(concat('css.css')),
            fontFiles = gulp.src('./src/bower_modules/components-bootstrap/fonts/*', { base: './src/bower_modules/components-bootstrap/' });
        return es.concat(combinedCss, fontFiles)
            .pipe(gulp.dest('./dist/'));
    });
Andre Gallo
  • 2,261
  • 5
  • 23
  • 46
1

there is a way and its honestly really simple. you can install "gulp-run" to your npm devDependencies and then use the run to execute bower install.

var gulp = require('gulp'),
    del = require('del'),
    run = require('gulp-run'),
    sass = require('gulp-sass'),
    cssmin = require('gulp-minify-css'),
    browserify = require('browserify'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    jshint = require('gulp-jshint'),
    browserSync = require('browser-sync'),
    source = require('vinyl-source-stream'),
    buffer = require('vinyl-buffer'),
    reactify = require('reactify'),
    package = require('./package.json'),
    reload = browserSync.reload;

/**
 * Running Bower
 */
gulp.task('bower', function() {
  run('bower install').exec();
})

/**
 * Cleaning lib/ folder
 */
.task('clean', function(cb) {
  del(['lib/**'], cb);
})

/**
 * Running livereload server
 */
.task('server', function() {
  browserSync({
    server: {
     baseDir: './' 
    }
  });
})

/**
 * sass compilation
 */
.task('sass', function() {
  return gulp.src(package.paths.sass)
  .pipe(sass())
  .pipe(concat(package.dest.style))
  .pipe(gulp.dest(package.dest.lib));
})
.task('sass:min', function() {
  return gulp.src(package.paths.sass)
  .pipe(sass())
  .pipe(concat(package.dest.style))
  .pipe(cssmin())
  .pipe(gulp.dest(package.dest.lib));
})

/**
 * JSLint/JSHint validation
 */
.task('lint', function() {
  return gulp.src(package.paths.js)
  .pipe(jshint())
  .pipe(jshint.reporter('default'));
})

/** JavaScript compilation */
.task('js', function() {
  return browserify(package.paths.app)
  .transform(reactify)
  .bundle()
  .pipe(source(package.dest.app))
  .pipe(gulp.dest(package.dest.lib));
})
.task('js:min', function() {
  return browserify(package.paths.app)
  .transform(reactify)
  .bundle()
  .pipe(source(package.dest.app))
  .pipe(buffer())
  .pipe(uglify())
  .pipe(gulp.dest(package.dest.lib));
})

/**
 * Compiling resources and serving application
 */
.task('serve', ['bower', 'clean', 'lint', 'sass', 'js', 'server'], function() {
  return gulp.watch([
    package.paths.js, package.paths.jsx, package.paths.html, package.paths.sass
  ], [
   'lint', 'sass', 'js', browserSync.reload
  ]);
})
.task('serve:minified', ['bower', 'clean', 'lint', 'sass:min', 'js:min', 'server'], function() {
  return gulp.watch([
    package.paths.js, package.paths.jsx, package.paths.html, package.paths.sass
  ], [
   'lint', 'sass:min', 'js:min', browserSync.reload
  ]);
});

what is really beautiful with this setup I just posted is this is making a custom gulp run called "serve" that will run your setup with a development server (with live reload and much better error intelligence) all you have to do is go to your directory and type "gulp serve" and it'll run bower install and build everything for you. obviously the folder structure is different so you will need to make some modifications, but hopefully this shows how you can run bower with gulp :)

John Ruddell
  • 25,283
  • 6
  • 57
  • 86
0

Something like the below was what I was looking for, except I don't like having to add the paths manually. This is why I prefer something like CommonJS for Javascript. I definitely remember seeing a way in which CSS files were picked up automatically from the bower_components folder, I believe it was in the Wordpress Roots project (based on the settings/overrides in bower.json).

gulp.task('css', function () {

    var files = [
        './public/bower_components/angular-loading-bar/build/loading-bar.css',
        './public/bower_components/fontawesome/css/font-awesome.css'
    ];

    return gulp.src(files, { 'base': 'public/bower_components' })
               .pipe(concat('lib.css'))
               .pipe(minifyCss())
               .pipe(gulp.dest('./public/build/css/')
    );
});

gulp.task('js-lib', function () {
    var files = [
        'public/bower_components/jquery/dist/jquery.js',
        'public/bower_components/bootstrap-sass/assets/javascripts/bootstrap.js'
    ];


    return gulp.src(files, { 'base': 'public/bower_components/' })
               .pipe(sourcemaps.init())
               .pipe(uglify({ mangle: false }))
               .pipe(concat('lib.js'))
               .pipe(sourcemaps.write('./'))
               .pipe(gulp.dest('./public/build/js/')
    );
});
Community
  • 1
  • 1
timhc22
  • 7,213
  • 8
  • 48
  • 66
-1

You can use gulp-main-bower-files library to add the main files of packages in .bower.json instead to declare them manually

dhilt
  • 18,707
  • 8
  • 70
  • 85