Yii Framework Forum: Bootstrap - Sass - Gulp - Toolchain - Yii Framework Forum

Jump to content

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

Bootstrap - Sass - Gulp - Toolchain The ultimate toolchain for JS and CSS Rate Topic: -----

#1 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 28 November 2015 - 02:59 PM

/*******************************************
The following discussion leads to a complete Gulp, Sass and Yii asset workflow
with the result that only one JS and one CSS is produced.
The code that is referenced throughout the discussion is the source code
for yiiframework.com.
It can be found here: https://github.com/y...iiframework.com

******************************************/

/*******************************************
Yii application templates based on Gulp and Sass available:

BOOTSTRAP:

Basic: yii2-app-basic-gulp-sass

Advanced: yii2-app-advanced-gulp-sass

FOUNDATION:

Basic: yii2-app-basic-zurbified

Advanced: yii2-app-advanced-zurbified

******************************************/


Hi,

I've been trying all day trying to figure this one out but I am at a loss.

I have moved a copy of the @vendor/bower/bootstrap folder into /frontend/assets and overridden the bootstrap bundles configuration in the frontend config to reflect this.

I am looking to customise the bootstrap files in order to 1) remove unneeded CSS and 2) change the remaining CSS to reflect the desired styling of my frontend.

What I just don't seem to be able to figure out is how to do this either intrinsically with yii, through a Yii extension or via a solution external to the Yii application.

I previously had recompiling working on a previous project when using a plugin for PHPStorm but this does not seem to work anymore.

Is there a way to recompile Bootstrap in Yii using the .less files?

As always, any and all advice greatly appreciated :)

This post has been edited by jacmoe: 29 March 2016 - 04:11 AM
Reason for edit: Added app templates

1

#2 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 28 November 2015 - 03:43 PM

Bootstrap 4 will be out any day now, and it is now based on Sass.

So, my advice is to grab the Sass package for Bootstrap 3.x - you can get it from the Bootstrap site.

And set up a tool-chain separate from Yii.
Using PHP for this is in my opinion a very bad idea.
We are using Node.js and Gulp for our build script at https://github.com/y...iiframework.com

You can easily find tutorials on how to set up Gulp and Sass together.

Then you need to define an asset bundle where you reference the generated css.
Check the guide.

And you probably need to disable the 'official' Yii Bootstrap assets.
Here's instructions: http://www.yiiframew...g-asset-bundles

Note that you can also go the route of configuring the asset manager to call the third-party tool-chain for you, but I haven't really bothered.
Instructions here: http://www.yiiframew...sset-conversion

Personally, I just run a 'gulp build' or 'gulp watch' and then code..
"Less noise - more signal"
1

#3 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 28 November 2015 - 04:46 PM

Thank you very much for a quick as informative response.

I was actually looking at the Bootstrap framework download today when I was running out of ideas and noticed it was sass only. I had also installed node.js for this purpose and had played around with grunt.

So essentially you recommend ditching lessc preprocessing in favour of sass as Bootstrap 4 will be sass-only anyway and ignoring any intrinsic compilers etc in favour of a Node/Gulp setup, set up file watchers in Gulp and make the appropriate configurations in AssetManager so that it publishes only the compiled file from Gulp instead of the core Bootstrap extension (which I had disabled anyway)?
0

#4 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 28 November 2015 - 04:49 PM

Exactly :)

That way you can use best of breed tool-sets all the way.

I think that you will find Gulp to be much more flexible and cleaner than Grunt, by the way.
But, that is a matter of preference.
However, if you don't have preferences, choose Gulp.

Here's a good article on SitePoint about Gulp for Sass: http://www.sitepoint...-workflow-sass/
"Less noise - more signal"
1

#5 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 28 November 2015 - 09:14 PM

I've downloaded the yiiframework.com files and had a look at the set up you have.

Regarding the gulp, gulp-sass etc modules... are these installed locally to the project root or globally as node modules? I don't see them in the project directory but this could obviously be due to .gitignore. If it's possible, I would prefer to have these installed globally for 1) reuse and 2) less clutter in the project directory. Going by the require() statements in Gulpfile.js they need to be included locally (it seems obvious this could be done globally but it's going to involve a considerable folder path).

Thanks again for the help! I've spent many a year doing various things in Yii, PHP etc but this work I am doing now is for a large project so I am hoping it will not only produce a lean and secure application but will also help me to really polish off the skills I have been learning over the years.
0

#6 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 November 2015 - 08:52 AM

It would now be a good idea to read the readme :)

It is a bad idea to save the Gulp modules globally because - heck: why not store everything globally, then? Including all composer packages, like Yii?

The Gulp client is installed globally, though. And the Browser-sync tool.

The rest of project dependent, and you can treat 'node_modules' just as you treat the 'vendor' directory: something that is project specific.

Read the readme, and if anything is unclear, tell us :)
"Less noise - more signal"
1

#7 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 09:19 AM

I've been playing around with this last night and most of today and I still cant seem to get it to work.

I had installed node globally and the packages locally, so my root directory looks like this: -

/backend
/common
/console
/development
/environments
/frontend
/node_modules
	/.bin
	/browser-synch
	/del
	/es6-promise
	/gulp
	/gulp-autoprefixer
	/gulp-cache
	/gulp-concat
	/gulp-imaginemin
	/gulp-jshint
	/gulp-minify-css
	/gulp-notify
	/gulp-rename
	/gulp-sass
	/gulp-sourcemaps
	/gulp-uglify
	/jshint
/scss
	/1-common
	/2-vendors
	/3-global
	/4-components
	/5-pages
	/6-elements
	all.css
/tests
/vendor
/web
	/css
gulpfile.js
package.json


I've stripped down gulpfile.js to a minimum to test the compiler prior to setting a watch or adding other functionality: -

// Load plugins
var gulp = require('gulp');
var sass = require('gulp-sass');

var sassOptions = {
    errLogToConsole: true,
    outputStyle: 'expanded'
};

// Styles
gulp.task('styles', function() {
    return gulp
        .src('scss/all.scss')
        .pipe(sass(sassOptions).on('error', sass.logError))
        .pipe(autoprefixer(autoprefixerOptions))
        .pipe(gulp.dest('web/css'))
        .pipe(notify({ message: 'Styles task complete' }));
});


So I have now tried running the console command but I get neither anything in the web/css folder nor any error messages.

node gulpfile styles


I have read through the README.md document and I cant see where I am going wrong here at all.

Again, all your help is greatly appreciated!
0

#8 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 09:22 AM

BTW I have the gulp client installed locally - I tried having just a global installation but it I was getting a cannot find module error.
0

#9 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 November 2015 - 09:56 AM

# install gulp globally if you haven't done so before
npm install -g gulp

# install browsersync globally if you haven't done so before
npm install -g browser-sync

# install dependent NPM modules
npm install


Gulp is both global and local, btw.

Browser-sync, on the other hand, is global only.

How does your package.json look like?
"Less noise - more signal"
1

#10 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 10:02 AM

The package.json file was the default copied over from the yiiframework.com github package: -

{
  "name": "yiiframework.com",
  "version": "2.0.0",
  "description": "yiiframework.com Website ========================",
  "main": "Gulpfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/qiangxue/yiiframework.com.git"
  },
  "author": "Qiang Xue",
  "homepage": "http://www.yiiframework.com",
  "devDependencies": {
    "del": "^2.1.0",
    "gulp": "^3.9.0",
    "es6-promise": "*",
    "gulp-autoprefixer": "^3.1.0",
    "gulp-cache": "^0.4.0",
    "gulp-concat": "^2.6.0",
    "gulp-imagemin": "^2.4.0",
    "gulp-jshint": "^2.0.0",
    "gulp-minify-css": "^1.2.1",
    "gulp-notify": "^2.2.0",
    "gulp-rename": "^1.2.2",
    "gulp-sass": "^2.1.0",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-uglify": "^1.5.1",
    "jshint": "^2.8.0"
  }
}


0

#11 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 10:03 AM

FYI I changed gulpfile.js to Gulpfile.js just to make sure it matched perfectly with the package.json but it didn't help.
0

#12 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 November 2015 - 10:41 AM

You should not have to do anything extra besides following the instructions in our readme :)

I assume that you have a recent Node.js installed?

Also, what errors exactly are you getting?
"Less noise - more signal"
0

#13 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 12:30 PM

Yeah, I have node.js installed. The odd thing is that I am not getting any errors. This is really frustrating.
0

#14 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 November 2015 - 01:07 PM

Wait: are you running node gulpfile build ?

You should just run:

gulp

gulp build

gulp whatever


That is: gulp is a global command.

It invokes node.js, not the other way around.
"Less noise - more signal"
1

#15 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 01:21 PM

Boom! You were right on the money. I was sure I have tried that variant before but perhaps not (I'm quite brain-fried from trying to get Bootstrap to compile, including going from 10AM yesterday pretty much straight through til 2AM today).

Anyway, I am now getting messages that it is attempting to compile but there are a few errors I need to look at. Honestly, I don't think I have ever been so happy to see error messages in my life.

Thanks again, Sir. It's been a struggle to get the compile functionality but it's rare that something worthwhile is easy and that's a major task in the development of this application almost sorted, which is a relief.

Thanks again!
1

#16 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 November 2015 - 01:40 PM

Awesome! :)

Stick with it because the knowledge that you are starting to pick up is applicable to much larger area of web development than just Yii projects.
"Less noise - more signal"
0

#17 User is offline   jacmoe 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 3,655
  • Joined: 10-October 10
  • Location:Denmark

Posted 29 November 2015 - 01:44 PM

I have modified the Gulpfile to handle the advanced project layout:

// fix problems with undefined Promise class
// http://stackoverflow.com/questions/32490328/gulp-autoprefixer-throwing-referenceerror-promise-is-not-defined
require('es6-promise').polyfill();

// Load plugins
var gulp = require('gulp'),
	sass = require('gulp-sass'),
	autoprefixer = require('gulp-autoprefixer'),
	minifycss = require('gulp-minify-css'),
	jshint = require('gulp-jshint'),
	uglify = require('gulp-uglify'),
	imagemin = require('gulp-imagemin'),
	rename = require('gulp-rename'),
	concat = require('gulp-concat'),
	notify = require('gulp-notify'),
	cache = require('gulp-cache'),
	browsersync = require('browser-sync'),
	sourcemaps = require('gulp-sourcemaps'),
	del = require('del');

	var sassOptions = {
  	errLogToConsole: true,
  	outputStyle: 'expanded'
	};

	var autoprefixerOptions = {
  	browsers: ['last 2 versions', '> 5%', 'Firefox ESR']
	};


// Styles
gulp.task('styles', function() {
  return gulp
	.src('scss/all.scss')
	.pipe(sourcemaps.init())
	.pipe(sass(sassOptions).on('error', sass.logError))
	.pipe(autoprefixer(autoprefixerOptions))
	.pipe(gulp.dest('frontend/web/css'))
	.pipe(gulp.dest('backend/web/css'))
	.pipe(rename({ suffix: '.min' }))
	.pipe(minifycss())
	.pipe(sourcemaps.write('../css/',{includeContent: false, sourceRoot: '../scss/'}))
	.pipe(gulp.dest('frontend/web/css'))
	.pipe(gulp.dest('backend/web/css'))
	.pipe(notify({ message: 'Styles task complete' }));
});

// Scripts
gulp.task('scripts', function() {
  return gulp.src(require('./js/all.json'))
	//.pipe(jshint('.jshintrc'))
	//.pipe(jshint.reporter('default'))
	.pipe(sourcemaps.init())
	.pipe(concat('all.js'))
	.pipe(gulp.dest('frontend/web/js'))
	.pipe(gulp.dest('backend/web/js'))
	.pipe(rename({ suffix: '.min' }))
	.pipe(uglify())
	.pipe(sourcemaps.write())
	.pipe(gulp.dest('frontend/web/js'))
	.pipe(gulp.dest('backend/web/js'))
	.pipe(notify({ message: 'Scripts task complete' }));
});

// Images
gulp.task('images', function() {
  return gulp.src('img/**/*')
	.pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
	.pipe(gulp.dest('web/img'))
	.pipe(notify({ message: 'Images task complete' }));
});

// Copy fonts
gulp.task('fonts', function() {
  gulp.src(['vendor/bower/bootstrap/fonts/*','scss/2-vendors/fontawesome/fonts/*', 'scss/2-vendors/fonts/josefine-sans/*'])
  .pipe(gulp.dest('./web/fonts'));
});

// Clean
gulp.task('clean', function(cb) {
	del(['frontend/web/css', 'frontend/web/js'], cb)
	del(['backend/web/css', 'backend/web/js'], cb)
});

// Build the "web" folder by running all of the above tasks
gulp.task('build', ['clean', 'styles', 'scripts'], function() {});

// Watch
gulp.task('watch', function() {

  // Initialize Browsersync
  browsersync.init({
	proxy: "http://bugitor.dev"
  });

  // Watch .scss files
  gulp.watch('scss/**/*.scss', ['styles']);

  // Watch .js files
  gulp.watch('js/**/*.js', ['scripts']);

  // Watch image files
  //gulp.watch('img/**/*', ['images']);

  // Watch any view files in 'views', reload on change
  gulp.watch(['common/views/**/*.php']).on('change', browsersync.reload);
  gulp.watch(['frontend/views/**/*.php']).on('change', browsersync.reload);
  gulp.watch(['backend/views/**/*.php']).on('change', browsersync.reload);

  // Watch any files in 'web', reload on change
  gulp.watch(['frontend/web/js/*']).on('change', browsersync.reload);
  gulp.watch(['backend/web/js/*']).on('change', browsersync.reload);
  gulp.watch(['frontend/web/css/*']).on('change', browsersync.reload);
  gulp.watch(['backend/web/css/*']).on('change', browsersync.reload);
});

gulp.task('default', ['build', 'watch'], function() {});

"Less noise - more signal"
0

#18 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 01:45 PM

Yep, that's the beauty of true application development - simplifying the manifold and then applying that simplification to a manifold of situations :)
0

#19 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 01:49 PM

View Postjacmoe, on 29 November 2015 - 01:44 PM, said:

I have modified the Gulpfile to handle the advanced project layout:

// fix problems with undefined Promise class
// http://stackoverflow.com/questions/32490328/gulp-autoprefixer-throwing-referenceerror-promise-is-not-defined
require('es6-promise').polyfill();

// Load plugins
var gulp = require('gulp'),
	sass = require('gulp-sass'),
	autoprefixer = require('gulp-autoprefixer'),
	minifycss = require('gulp-minify-css'),
	jshint = require('gulp-jshint'),
	uglify = require('gulp-uglify'),
	imagemin = require('gulp-imagemin'),
	rename = require('gulp-rename'),
	concat = require('gulp-concat'),
	notify = require('gulp-notify'),
	cache = require('gulp-cache'),
	browsersync = require('browser-sync'),
	sourcemaps = require('gulp-sourcemaps'),
	del = require('del');

	var sassOptions = {
  	errLogToConsole: true,
  	outputStyle: 'expanded'
	};

	var autoprefixerOptions = {
  	browsers: ['last 2 versions', '> 5%', 'Firefox ESR']
	};


// Styles
gulp.task('styles', function() {
  return gulp
	.src('scss/all.scss')
	.pipe(sourcemaps.init())
	.pipe(sass(sassOptions).on('error', sass.logError))
	.pipe(autoprefixer(autoprefixerOptions))
	.pipe(gulp.dest('frontend/web/css'))
	.pipe(gulp.dest('backend/web/css'))
	.pipe(rename({ suffix: '.min' }))
	.pipe(minifycss())
	.pipe(sourcemaps.write('../css/',{includeContent: false, sourceRoot: '../scss/'}))
	.pipe(gulp.dest('frontend/web/css'))
	.pipe(gulp.dest('backend/web/css'))
	.pipe(notify({ message: 'Styles task complete' }));
});

// Scripts
gulp.task('scripts', function() {
  return gulp.src(require('./js/all.json'))
	//.pipe(jshint('.jshintrc'))
	//.pipe(jshint.reporter('default'))
	.pipe(sourcemaps.init())
	.pipe(concat('all.js'))
	.pipe(gulp.dest('frontend/web/js'))
	.pipe(gulp.dest('backend/web/js'))
	.pipe(rename({ suffix: '.min' }))
	.pipe(uglify())
	.pipe(sourcemaps.write())
	.pipe(gulp.dest('frontend/web/js'))
	.pipe(gulp.dest('backend/web/js'))
	.pipe(notify({ message: 'Scripts task complete' }));
});

// Images
gulp.task('images', function() {
  return gulp.src('img/**/*')
	.pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
	.pipe(gulp.dest('web/img'))
	.pipe(notify({ message: 'Images task complete' }));
});

// Copy fonts
gulp.task('fonts', function() {
  gulp.src(['vendor/bower/bootstrap/fonts/*','scss/2-vendors/fontawesome/fonts/*', 'scss/2-vendors/fonts/josefine-sans/*'])
  .pipe(gulp.dest('./web/fonts'));
});

// Clean
gulp.task('clean', function(cb) {
	del(['frontend/web/css', 'frontend/web/js'], cb)
	del(['backend/web/css', 'backend/web/js'], cb)
});

// Build the "web" folder by running all of the above tasks
gulp.task('build', ['clean', 'styles', 'scripts'], function() {});

// Watch
gulp.task('watch', function() {

  // Initialize Browsersync
  browsersync.init({
	proxy: "http://bugitor.dev"
  });

  // Watch .scss files
  gulp.watch('scss/**/*.scss', ['styles']);

  // Watch .js files
  gulp.watch('js/**/*.js', ['scripts']);

  // Watch image files
  //gulp.watch('img/**/*', ['images']);

  // Watch any view files in 'views', reload on change
  gulp.watch(['common/views/**/*.php']).on('change', browsersync.reload);
  gulp.watch(['frontend/views/**/*.php']).on('change', browsersync.reload);
  gulp.watch(['backend/views/**/*.php']).on('change', browsersync.reload);

  // Watch any files in 'web', reload on change
  gulp.watch(['frontend/web/js/*']).on('change', browsersync.reload);
  gulp.watch(['backend/web/js/*']).on('change', browsersync.reload);
  gulp.watch(['frontend/web/css/*']).on('change', browsersync.reload);
  gulp.watch(['backend/web/css/*']).on('change', browsersync.reload);
});

gulp.task('default', ['build', 'watch'], function() {});



Thank you!

I will definitely look to apply this very soon but that will have to be after I have looked through it, understood the functionality of all the modules etc rather than just blindly plugging it in.

Right now, I am going to get those errors sorted out and do a test compile. Then I will probably look to strip out unwanted style/scripts for Bootstrap elements my project is not going to use (or at least not in the initial version) to keep things as lean and simple as I possibly can.
0

#20 User is offline   U4EA 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 300
  • Joined: 04-November 12

Posted 29 November 2015 - 04:10 PM

That's it successfully compiling from the source files for Bootstrap 3.3.6 now. Thanks!
1

Share this topic:


  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »
  • You cannot start a new topic
  • You cannot reply to this topic

2 User(s) are reading this topic
0 members, 2 guests, 0 anonymous users