im working on a wordpress theme with less and gulp. Since i need to adjust some default paths and values for bootstrap + fontaweseome i have a less file with my custom vars (overwrite.less). but it doesnt affect the variables at all.
Less files get injected via mainBowerFiles, the docs say less vars support lazy load. (http://lesscss.org/features/#variables-feature-lazy-loading)
files get cached to speed up the build ( < 10 ms) but even without - no effect.
gulpfile.js:
'use strict';
var gulp = require('gulp');
var less = require('gulp-less');
var browserSync = require('browser-sync').create();
var util = require('gulp-util');
var sourceMaps = require('gulp-sourcemaps');
var del = require('del');
var cache = require('gulp-cached');
var remember = require('gulp-remember');
var concat = require('gulp-concat');
var minifyCss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var mainBowerFiles = require('main-bower-files');
var paths = {
target: '../vagrant/www/wordpress/wp-content/themes/themename',
bowerJs: mainBowerFiles('**/*.js'),
bowerLess: mainBowerFiles('**/*.less'),
lessFiles: ['overwrite.less','less/**.less'],
jsFiles: ['js/**.js']
};
var allLess = paths.bowerLess.concat(paths.lessFiles);
var allJs = paths.bowerJs.concat(paths.jsFiles);
function compileLess() {
var s = gulp.src(allLess);
s = s.pipe(sourceMaps.init());
s = s.pipe(cache('less'));
s = s.pipe(less());
s = s.pipe(remember('less'));
s = s.pipe(minifyCss());
s = s.pipe(concat('style.css'));
s = s.pipe(sourceMaps.write('maps/'));
return s.pipe(gulp.dest(paths.target));
}
function compileJs() {
var s = gulp.src(allJs);
s = s.pipe(sourceMaps.init());
s = s.pipe(cache('js'));
s = s.pipe(uglify());
s = s.pipe(remember('js'));
s = s.pipe(concat('app.js'));
s = s.pipe(sourceMaps.write('maps/'));
return s.pipe(gulp.dest(paths.target));
}
gulp.task('move', function() {
var filesToMove = ['./*.php', './assets/**', 'bower_components/**', './partial/**'];
gulp.src(filesToMove, { base: './' })
.pipe(gulp.dest('../vagrant/www/wordpress/wp-content/themes/codecampus')).once('end', function () {
browserSync.reload();
});
});
gulp.task('browser-sync', function() {
browserSync.init([], {
proxy: "http://vccw.dev/"
});
});
gulp.task('watch', function () {
gulp.watch('less/**/*.less', ['less']);
gulp.watch('js/**/*.js', ['js']);
gulp.watch(['./*.php', './assets/**', './partial/**'], ['move'])
});
gulp.task('less', function () {
util.log('Compile less ...');
browserSync.reload();
return compileLess();
});
gulp.task('js', function () {
util.log('Compile js ...');
browserSync.reload();
return compileJs();
});
gulp.task('clean', function (cb) {
util.log('Delete old less ...');
del([paths.target + '**/*'], {force: true}, cb);
});
//define tasks
gulp.task('default', [ 'clean', 'less', 'js' , 'move', 'watch', 'browser-sync'], function () {
return util.log('Gulp is running!');
});
Solution 1:
Splitting up the bower-less-files plus overwrite and your custom styles. so that you have 2 less tasks.
Solution 2:
Keep anything in one Task and inject modifyVars into your less task
s = s.pipe(less({
modifyVars: {
"fa-font-path" : '"../custom/path/"',
...
}
}));
Related
In my gulfile.js, I'm using watch to compile scss files to css files. It runs without error and when I run gulp in powershell, it says that it is watching, but whenever I define a style in my scss file, it doesn't affect the css file which is created and I have to stop gulp and run it again. Actually, it's not watching carefully !
Here is my code.
Thanks for any help.
"use strict";
var gulp = require("gulp");
var sass = require("gulp-sass");
var minifyCSS = require("gulp-clean-css");
var uglify = require("gulp-uglify");
var rename = require("gulp-rename");
var changed = require("gulp-changed");
var { task, series } = require("gulp");
var SCSS_SRC = "./src/Assets/scss/**/*.scss";
var SCSS_DEST = "./src/Assets/css";
task("compile_scss", function() {
gulp
.src(SCSS_SRC)
.pipe(sass().on("error", sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: ".min" }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
});
task("watch_scss", function() {
gulp.watch(SCSS_SRC, series(["compile_scss"]));
});
task("default", series("watch_scss"));
You missed a return. The gulp doesn't know the task has completed. In your case you have to return the stream. Here is how your code should be:
"use strict";
var gulp = require("gulp");
var sass = require("gulp-sass");
var minifyCSS = require("gulp-clean-css");
var uglify = require("gulp-uglify");
var rename = require("gulp-rename");
var changed = require("gulp-changed");
var { task, series } = require("gulp");
var SCSS_SRC = "./src/Assets/scss/**/*.scss";
var SCSS_DEST = "./src/Assets/css";
function compile_scss() {
return gulp
.src(SCSS_SRC)
.pipe(sass().on("error", sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: ".min" }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
}
function watch_scss() {
gulp.watch(SCSS_SRC, series(compile_scss));
}
exports.default = series(watch_scss);
I also took the liberty of removing the "task()"s since
Reminder: This API isn't the recommended pattern anymore - export your tasks.
as said here.
For the problem be solved, as #Gabriel mentioned and according this link, I changed my code to this and the problem solved. But when I ran npm start, the watch stopped working; Therefore, I installed "concurrently" through npm and changed my start in package.json as mentioned here:
npm install concurrently
"start": "concurrently \"react-scripts start \" \"gulp \"",
"use strict";
var gulp = require("gulp");
var sass = require("gulp-sass");
var minifyCSS = require("gulp-clean-css");
var uglify = require("gulp-uglify");
var rename = require("gulp-rename");
var changed = require("gulp-changed");
var { task, series } = require("gulp");
var SCSS_SRC = "./src/Assets/scss/**/*.scss";
var SCSS_DEST = "./src/Assets/css";
function compile_scss() {
return gulp
.src(SCSS_SRC)
.pipe(sass().on("error", sass.logError))
.pipe(minifyCSS())
.pipe(rename({ suffix: ".min" }))
.pipe(changed(SCSS_DEST))
.pipe(gulp.dest(SCSS_DEST));
}
function watch_scss() {
gulp.watch(SCSS_SRC, series(compile_scss));
}
exports.default = series(watch_scss);
I have a gulp 'default' task where I want to clean a folder before gulp continues to build my minified CSS and JS. This 'clean' task needs to run only once per default task. But I am having issues trying to get default task to reference the real build tasks.
So here is my gulpfile:
var gulp = require('gulp');
// including our plugins
var clean = require('gulp-clean');
var less = require('gulp-less');
var util = require('gulp-util');
var lsourcemaps = require('gulp-sourcemaps');
var rename = require('gulp-rename');
var filesize = require('gulp-filesize');
var ugly = require('gulp-uglify');
var path = require('path');
var plumber = require('gulp-plumber');
var minifyCSS = require('gulp-minify-css');
var concat = require('gulp-concat');
// DEFAULT TASK
gulp.task('default', ['clean'], function() {
.pipe(gulp.task('vendor'))
.pipe(gulp.task('css'))
});
// strips public folder for a build operation nice and clean ** obliterates! **
gulp.task('clean', function() {
return gulp.src('public/**', {read: false})
.pipe(clean());
});
// javascript vendor builds
gulp.task('vendor', function() {
return gulp.src(['bower_comps/angular/angular.js', 'bower_comps/angular-bootstrap/ui-bootstrap.js', 'bower_comps/angular-bootstrap/ui-bootstrap-tpls.js'])
//.pipe(filesize())
.pipe(ugly())
.pipe(concat('vendor.min.js'))
.pipe(gulp.dest('public/js'))
});
// builds CSS
gulp.task('css', function() {
return gulp.src('bower_comps/bootstrap-less/less/bootstrap.less')
.pipe(lsourcemaps.init())
.pipe(plumber({
errorHandler: function(err) {
console.log(err);
this.emit('end')
}
}))
.pipe(less({
paths: [path.join(__dirname, 'less', 'includes')]
}))
.pipe(minifyCSS())
.pipe(rename('site.min.css'))
.pipe(lsourcemaps.write('./maps'))
.pipe(gulp.dest('public/css/'))
.pipe(filesize())
});
So how am I going about this wrong?? Each of the individual tasks will run on their own just fine "gulp css", "gulp vendor". Its just when I put them into a default task (master task) with a 'pre-requisite' task of my clean that I run into problems.
Tony
Try these for your tasks:
gulp.task('clean', function() {
// Insert cleaning code here
});
gulp.task('vendor', ['clean'], function() {
// Insert your 'vendor' code here
});
gulp.task(‘css’, ['clean'], function() {
// insert your 'css' code here
});
gulp.task('build', [‘vendor’, ‘css’]);
gulp.task('default', ['build']);
'vendor' and 'css' will run concurrently only after 'clean' has finished. 'clean' will only run once despite being a prerequisite for both 'vendor' and 'css'.
The Problem ist when you call the default task, gulp randomly chooses the order of the task:
gulp.task('default', ['clean', 'move', 'scripts', 'css']);
To solve this problem each task should have dependencies. For example the move task should be performed after the clean task. So the move taks should look like this:
gulp.task('move', ['clean'], function () { //your code }
for more explanation: https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulptaskname-deps-fn
sorry for my bad english :-)
I want to create yoeman generator for html template project
when i try to launch grunt i ha this error Task 'default not found
grunt build give grunt is not defined
$> grunt
Loading "Gruntfile.js" tasks...ERROR
>> ReferenceError: grunt is not defined
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
Here is my code
var fs = require('fs');
var path = require('path');
var showdown = require('showdown');
var EJS = require('ejs');
var TemplateRender = function(file, destination, source, template) {
this.file = file;
this.destination = destination;
this.source = source;
this.template = template;
this.grunt = grunt;
};
TemplateRender.prototype = {
render: function() {
var file = this._read();
var html = this._convert(file);
var content = this._template(html);
this._write(content);
},
_read: function() {
var filepath = path.join(this.source,this.file);
grunt.file.read(filepath);
},
_convert: function(file) {
return new showdown.convertor().makeHtml(file);
},
_template: function(html) {
var template = this.grunt.file.read(this.template);
return EJS.render(template,{content:html});
},
_write: function() {
this.grunt.file.write(
path.join(this.destination, this.file),
page
);
}
};
'use strict';
module.exports = function(grunt) {
grunt.registerTask('build', function() {
var template = "app/index.ejs",
destination = path.join(process.cwd(),"dist"),
source = path.join(process.cwd(),"posts"),
files = fs.readdirSync(source);
files.forEach(function(file) {
new TemplateRender(file, destination, source, template, grunt).render();
read();
convert();
template();
write();
});
});
};
I need to know how to detect error in grunt and yeoman
At the top of your code, in the TemplateRender function, you have this line: this.grunt = grunt; But you don't actually have an argument by that name. Try this:
// ... (everything the same above here)
// *** Notice the new argument to this constructor function
var TemplateRender = function(file, destination, source, template, grunt) {
this.file = file;
this.destination = destination;
this.source = source;
this.template = template;
this.grunt = grunt;
};
TemplateRender.prototype = {
// ...
_read: function() {
var filepath = path.join(this.source,this.file);
// *** probably needs to be `this.grunt` ?
this.grunt.file.read(filepath);
},
// ...
};
module.exports = function(grunt) {
grunt.registerTask('build', function() {
// ... (mostly the same)
files.forEach(function(file) {
new TemplateRender(file, destination, source, template, grunt).render();
// *** where are these defined? Should they be: this._read(), etc?
this._read();
this._convert();
this._template();
this._write();
});
});
};
I wonder if this is the correct solution to update the state with two dictionares
var PopulationCityView = React.createClass({
getInitialState: function() {
return {
prod_diff : {'wheat':0,'meat':0,'fish':0,'bread':0,'fruit':0,'wine':0,'beer':0,'wool':0,'cloth':0,'leather':0,'paper':0,'ceramics':0,'furniture':0,'glass':0}
};
},
componentWillMount: function() {
this.prod_diff = {'wheat':0,'meat':0,'fish':0,'bread':0,'fruit':0,'wine':0,'beer':0,'wool':0,'cloth':0,'leather':0,'paper':0,'ceramics':0,'furniture':0,'glass':0};
},
handleM: function(res,child_new_res_diff){
var new_prod_diff = this.prod_diff;
new_prod_diff[res] = child_new_res_diff;
this.setState({prod_diff:new_prod_diff});
},
render: function(){
........
if anyone knows of a better and faster solution would ask for a hint...
Much safer and more efficient way is to keep your state as simple object with primitive values:
var PopulationCityView = React.createClass({
getInitialState: function() {
return {
wheat: 0,
meat: 0,
fish: 0,
};
},
handleM: function(res,child_new_res_diff){
var new_state = {};
new_state[res] = child_new_res_diff;
this.setState(new_state);
},
render: function() { /* your render code */ }
});
If you really have to store your values in nested object you have to remember to clone nested object before modifying it:
var PopulationCityView = React.createClass({
getInitialState: function() {
return {
prod_diff: { wheat: 0, meat: 0, fish: 0 }
};
},
handleM: function(res,child_new_res_diff){
var new_prod_diff = _.clone(this.state.prod_diff);
new_prod_diff[res] = child_new_res_diff;
this.setState({ prod_diff: new_prod_diff });
},
render: function() { /* your render code */ }
});
I've made your initial state a little smaller to simplify code examples.
Also consider using React Immutability Helpers which makes operating on nested objects inside state safer.
I forgot to add that handleM function arguments are sent by the child.
In my solution it does not work smoothly (slider that adjusts the prod_diff jams), the same effect is when I apply the solution #daniula
Now I have decided to make use of CortexJS and everything runs smoothly
I would ask to correct me if I used this library incorrectly:
PARENT
var PopulationCityView = React.createClass({
getInitialState: function() {
return {
prod_diff_C : new Cortex({'wheat':0,'meat':0,'fish':0,'bread':0,'fruit':0,'wine':0,'beer':0,'wool':0,'cloth':0,'leather':0,'paper':0,'ceramics':0,'furniture':0,'glass':0}),
};
},
componentWillUnmount: function() {
delete this.state.prod_diff_C;
},
componentDidMount: function(){
var that = this;
this.state.prod_diff_C.on("update",function (updatedRes) {that.setState({prod_diff_C: updatedRes});});
},
// handleM: function(res,child_new_res_diff){
// var new_prod_diff = this.prod_diff;
// new_prod_diff[res] = -child_new_res_diff;
// this.setState(new_prod_diff);
// },
render: function(){
var foods = {}, goods = {};
for(var g = 0; g< this.goods.length; g++){
R = this.goods[g];
goods[R] = <div style={{display:"inline-block"}}>
<CHILD_1 res_par={this.props.data.res_uses[R]} res={R} prod_diff_cortex={this.state.prod_diff_C}/>
<SLIDER prod_diff_cortex={this.state.prod_diff_C} res={R} res_have={this.props.data.res_uses[R][0]} res_need={this.props.data.res_uses[R][1]} />
</div>
}
}
return ( .... )
}
})
CHILD_1
var CHILD_1 = React.createClass({
render: function(){
var val = this.props.res_par[3] + this.props.prod_diff_cortex[this.props.res].getValue()
return (
<div className='population-production-upkeep'>
{val}
</div>
)
}
})
SLIDER
var SLIDER= React.createClass({
......
handleMouseDown: function(event){
var start_val = this.props.res_have + this.props.prod_diff_cortex[this.props.res].getValue()
this.val_start = start_val;
this.res_diff_start = this.props.prod_diff_cortex[this.props.res].getValue()
this.touched = 1;
this.pos_start_x = event.screenX;
this.prev_pos_x = this.width_step * start_val;
event.stopPropagation();
event.preventDefault();
},
handleMouseMove: function(event){
if(this.touched) {
var x_diff = event.screenX - this.pos_start_x ;
var x = this.prev_pos_x + x_diff;
if (x < 0) x = 0;
if (x > this.state.max_pos_x) x = this.state.max_pos_x;
var stor = Math.round(x* 100 / this.width_step ) / 100
var new_res_diff = this.res_diff_start + stor - this.val_start;
this.props.prod_diff_cortex[this.props.res].set(new_res_diff)
}
},
......
render: function() {
var val = Math.round((this.props.res_have+this.props.prod_diff_cortex[this.props.res].getValue())*100)/100;
return (
..../* slider render */
);
}
});
Having trouble understanding where I'm going wrong with this (if it's me at all), I've got my (first) gulp file, and it's working fine:
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var del = require('del');
var sourcemaps = require('gulp-sourcemaps');
var concat = require('gulp-concat');
var handlebars = require('gulp-handlebars');
var wrap = require('gulp-wrap');
var declare = require('gulp-declare');
gulp.task('default', ['clean', 'minify-external', 'minify-internal']);
gulp.task('clean', function() {
del(['build/js/'], function(err){ });
});
gulp.task('minify-external', function() {
return gulp.src([
'bower_components/jquery/dist/jquery.js',
'bower_components/handlebars/handlebars.js',
'bower_components/ember/ember.js',
'bower_components/ember-data/ember-data.js',
])
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(concat('scripts.min.js'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('build/js/'));
});
gulp.task('minify-internal', function() {
return gulp.src('src/js/**/*.js')
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(concat('lib.min.js'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('build/js//'));
});
gulp.watch('src/js/**/*.js', ['minify-internal']);
Next I'm trying to add the handlebars pre-compilation into it:
//above omitted for brevity
gulp.task('default', ['clean', 'minify-external', 'minify-internal']);
//...
gulp.task('templates', function() {
return gulp.src('src/templates/**/*.hbs')
.pipe(handlebars())
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(declare({
namespace: 'Todos.templates',
noRedeclare: true, // Avoid duplicate declarations
}))
.pipe(concat('templates.min.js'))
.pipe(gulp.dest('build/js/'));
});
And the script now fails:
Error: EEXIST, mkdir '[BUILD PATH]/build/js'
Seems to be specific to the templates task, as the other two minify-x tasks run fine. I've attempted async and sync running (that is removing the return statements from tasks). Am I missing something on how streams interact here? Is it normal to output from multiple tasks to the same folder?