How to combine postcss / autoprefixer with LESS - less

I have a site for which I use custom LESS stylesheets and they include Bootstrap LESS stylesheets. It is all compiled to the final style.css file with a style.css.map sourcemap.
This is how my Gulpfile looks:
var gulp = require('gulp');
var less = require('gulp-less-sourcemap');
var mySite = '.';
gulp.task('less', function () {
gulp.src(mySite + '/css/**.less')
.pipe(less())
.pipe(gulp.dest(mySite + '/css'));
});
Now I'd like to add autoprefixer. This is what I've tried but it doesn't work:
var gulp = require('gulp');
var less = require('gulp-less-sourcemap');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer-core');
var mySite = '.';
gulp.task('less', function () {
gulp.src(mySite + '/css/**.less')
.pipe(less())
.pipe(postcss([autoprefixer({ browsers: ['last 2 version'] })]))
.pipe(gulp.dest(mySite + '/css'));
});
It's because I am piping the generated sourcemaps into postcss and it cannot handle it. So I've tried this:
var gulp = require('gulp');
var less = require('gulp-less-sourcemap');
var postcss = require('gulp-postcss');
var autoprefixer = require('autoprefixer-core');
var mySite = '.';
gulp.task('less', function () {
gulp.src(mySite + '/css/**.less')
.pipe(less())
.pipe(postcss([autoprefixer({ browsers: ['last 2 version'] })]))
.pipe(gulp.dest(mySite + '/css'));
gulp.src(mySite + '/css/**.css')
.pipe(postcss([autoprefixer({ browsers: ['last 2 version'] })]))
.pipe(gulp.dest(mySite + '/css'));
});
However, the prefixes are still not added. Maybe it's because the Bootstrap's CSS is already prefixed and it's somehow a problem for postcss?
How to make this work?

According to the Gulp-Less Readme,
If you are using version 1.3.7 or higher you will have the ability to
use a growing set LESS plugins, potentially simplifying your build
steps.
And the code they suggest using would look like this.
var LessPluginAutoPrefix = require('less-plugin-autoprefix'),
autoprefix= new LessPluginAutoPrefix({browsers: ["last 2 versions"]});
gulp.src('./less/**/*.less')
.pipe(less({
plugins: [autoprefix]
}))
.pipe(gulp.dest('./public/css'));

Related

reading ID3 tag in NativeScript + Vue

I am trying to read id3 tags of mp3 files in my project but it seems all the node plugins has a dependency on fs ,
since I get this error: TypeError: fs.exists is not a function
so How can I read id3 tags in NativeScript?
{N} !== Node, You will have to fetch the meta data in native iOS / Android way. Use nativescript-media-metadata-retriever plugin.
tns plugin add nativescript-media-metadata-retriever
You could try nativescript-nodeify, but I remember having problem afterwards with with bundling.
Also, I used this back in NativeScript 4. I don't know if this still works in NS 6.
I share my usage of this module in sake of noobies like me, who can waste their times just for a misunderstanding :))
requires:
import { MediaMetadataRetriever } from "nativescript-media-metadata-retriever";
const imageSourceModule = require( "tns-core-modules/image-source" );
const fs = require("tns-core-modules/file-system");
and the code:
// ------- init MediaMetadataRetriever
let mmr = new MediaMetadataRetriever();
mmr.setDataSource( newValue );
mmr.getEmbeddedPicture()
.then( ( args ) => {
// ------- show the albumArt on bgIMG
var albumArt = this.$refs.bgIMG.nativeView;
var img = new imageSourceModule.ImageSource();
// ------- setNativeSource is a **Methods** of imageSourceModule
img.setNativeSource( args );
albumArt.set( "src" , img );
console.log("ImageSource set...");
// ------- save the albumArt in root of SDCARD
// ------- fromNativeSource is a **Function** of imageSourceModule
let imageSource = imageSourceModule.fromNativeSource( args );
console.log("Here");
let fileName = "test.png";
const root = android.os.Environment.getExternalStorageDirectory().getAbsolutePath().toString();
let path = fs.path.join( root , fileName);
let saved = imageSource.saveToFile(path, "png");
if (saved) {
console.log("Image saved successfully!");
}
} );

Gulp sass not compiling for loop with #{$i} tag

Having a problem with Gulp sass, it's not compiling my file.
Unknown word You tried to parse SCSS with the standard CSS parser; try again with the postcss-scss parser
Code css:
#for $i from 1 through 12 {
.col-#{$i} {
-ms-flex-preferred-size: (100% / 12) * $i;
-webkit-flex-basis: (100% / 12) * $i;
flex-basis: (100% / 12) * $i;
max-width: (100% / 12) * $i;
}
}
Code gulp:
gulp.task( 'sass', function() {
return gulp.src( SOURCEPATHS.sassSource )
.pipe( autoprefixer({ browsers: ['last 2 versions']} ) )
.pipe( sass({ includePaths: ['node_modules'] }, { outputStyle: 'compressed' }).on('error', sass.logError) )
.pipe( mmq({ log: false }) )
.pipe( cssmin() )
.pipe( rename({suffix: '.min'}) )
.pipe( gulp.dest(APPPATH.css) );
});
Error with this tag #{$i} - without this - gulp compile css file.
There could be a problem? I have read a lot about gulp-postcss - And try with it, but the result is the same - ERROR
.pipe( autoprefixer({ browsers: ['last 2 versions']} ) )
Need to set after sass
As per #TheDancingCode's comment, the fix for me was to run AutoPrefixer after SASS.
"Run autoprefixer and other postcss plugins after sass"
gulp.task("sass", function () {
return gulp.src([`${paths.scss}**/*.scss`, `!${paths.scss}vendor/**/*`])
.pipe(sourcemaps.init())
.pipe(sass.sync().on('error', sass.logError))
.pipe(autoprefixer())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(paths.contentRoot));
This seems obvious to me now, since SASS may be applying variables to property values. If so, they can contain values which may need to be vendor-prefixed. Hence the requirement.

How to correctly get gulp.src globs from a variable?

Given the following Gulp setup
const { src, dest } = require('gulp');
var zip = require('gulp-zip');
var pkgDist = 'packages/';
function pkg(done) {
src(['./**', '!node_modules/**', '!vendor/**', '!.gitignore', '!*.json', '!*.lock'], {base: '..'})
.pipe(zip('archive.zip'))
.pipe(dest(pkgDist))
done();
};
exports.pkg = pkg;
how can I modify it in order to get src globs from a variable, i.e. pkgSrc, something like this:
[...]
var pkgSrc = <what to put here?>;
[...]
src(pkgSrc)
[...]
I've tried to use this var pkgSrc = " ['./**', '!node_modules/**', '!vendor/**', '!.gitignore', '!*.json', '!*.lock'], {base: '..'} "; but it doesn't work.
If it's easier, I'm also open to solutions that result into this src([pkgSrc], {base: '..'})
You can go with just:
var pkgSrc = ['./**', '!node_modules/**', '!vendor/**', '!.gitignore', '!*.json', '!*.lock']
gulp.src first argument can be a string or an array, so now it is an array above.
The second argument is an object of options. Include the options sepearately: {base: '..'} so
src(pkgSrc, {base: '..'})

Can Gulp change LESS variables?

I'm looking to toggle IE8 mode in my LESS files and automated the file generation in Gulp.
This is where I stopped in what to pass gulp-less (minus a bunch of stuff):
var IE = true;
var LESSConfig = {
plugins: [ ... ],
paths: LESSpath,
ie8compat: IE, //may as well toggle this
// Set in variables.less, #ie:false; - used in mixin & CSS guards
// many variations tried
// globalVars: [ { "ie":IE } ],
modifyVars:{ "ie":IE }
};
...
.pipe( less ( LESSConfig ) )
Is variable modification not supported in Gulp?
I'd like to avoid using gulp-modify et al if I can. I'd like to keep the build system fairly abstracted from the source files.
modifyVars is working for me now:
...
var LESSConfig = {
paths: paths.LESSImportPaths,
plugins: [
LESSGroupMediaQueries,
LESSautoprefix
],
modifyVars: {
ie: 'false'
}
};
var LESSConfigIE = {
paths: paths.LESSImportPaths,
modifyVars: {
ie: 'true'
}
};
function processLESS (src, IE, dest){
return gulp.src(src)
.pipe( $.if( IE, $.less( LESSConfigIE ), $.less( LESSConfig ) ) )
.pipe( $.if( IE, $.rename(function(path) { path.basename += "-ie"; }) ) )
.pipe( gulp.dest(dest) )
}
// build base.css files
gulp.task('base', function() {
return processLESS( paths.Base + '/*.less', false, paths.dest );
});
// build base-ie.css files for IE
gulp.task('baseIE', function() {
return processLESS( paths.Base + '/*.less', true, paths.dest );
});
Since I could not get this to work with gulp-lessand it became apparent to me that the application of globalVars and modifyVars are both broken, I came up with a different solution.
You can use gulp-append-prepend to write your variables into the file before gulp-less processes it. A little less elegant but, on the plus side, it actually works.
Something like this:
gulp.src('main.less')
.pipe(gap.prependText('#some-global-var: "foo";'))
.pipe(gap.appendText('#some-modify-var: "bar";'))
.pipe(less())
.pipe(gulp.dest('./dest/'));
Nowadays (2019) this problem seems to be fixed.
However it cost me still a lot of time to get it running.
Here is what I did:
gulp.task('lessVariants', ['less'], function() {
return gulp.src('less/styles.less', {base:'less/'})
.pipe(less({modifyVars:{'#color1': '#535859'}))
.pipe(less({modifyVars:{'#color2': '#ff0000'}))
.pipe(less({modifyVars:{'#color3': '#ccffcc'}))
.pipe(rename('styles.modified.css'))
.pipe(cleanCSS())
.pipe(gulp.dest(distFolder + 'css'))
})
This did not work. Only the last variable was modified. I changed it as follows to get it working:
gulp.task('lessVariants', ['less'], function() {
return gulp.src('less/styles.less', {base:'less/'})
.pipe(less({modifyVars: {
'#color1': '#535859',
'#color2': '#ff0000',
'#color3': '#ccffcc',
}}))
.pipe(rename('styles.variant.css'))
.pipe(cleanCSS())
.pipe(gulp.dest(distFolder + 'css'))
})

compiling lesscss files by phantomJS

hej I got idea to compile lesscss files while building my project with maven.
looking at lesscss site it is possible to compile those files referencing them in head section of html file like this
<link rel="stylesheet/less" type="text/css" href="styles.less">
<script src="less.js" type="text/javascript"></script>
phantom's script can access any file on local hard drive so it should be possible to loop over *.less files. now the question is how to compile those files and save them back with css extension.
the pity is that command line is available only when installed to node (or maybe I wrong??)
thanks for any hint
well after giving it a second try I created this script
console.log('*********************************************************************');
console.log('executing script ' + phantom.scriptName);
console.log('phantomJS version ' + phantom.version.major + '.' + phantom.version.minor + '.' + phantom.version.patch);
console.log('*********************************************************************');
console.log('looks for less files under src/main/webapp/* and src/main/resources/*');
console.log('to change this pass root directory as script parameter');
console.log('example Usage: phantomjs-less.js src/main/resources/css');
console.log('*********************************************************************');
var root_directory = null;
if (phantom.args.length !== 0) {
root_directory = phantom.args[0];
}
console.log('injecting less script');
phantom.injectJs('src/main/webapp/js/less-1.2.2.js');
var parser = new(less.Parser);
var searchLessIn = function(root, fs) {
console.log('look for less in ' + root);
if (fs.isDirectory(root)) {
var files = fs.list(root);
for (var index = 2; index < files.length; index ++ ) {
searchLessIn(root + '/' + files[index], fs);
}
} else {
if (root.substr(-5) === '.less'){
parseLess(root, fs);
}
}
console.log('exit ' + root);
};
var parseLess = function(file, fs) {
console.log('parse less file : ' + file);
var opened = fs.read(file);
console.log(opened);
parser.parse(opened, function (err, tree) {
if (err) { return console.error(err); }
console.log(tree.toCSS());
});
};
var fs = require('fs');
console.log('*********************************************************************');
console.log('current root directory =' + fs.workingDirectory);
var root = fs.workingDirectory + '/src/main/webapp/css';
console.log('look for less files under ' + root);
if (!fs.exists(root)) {
console.log(root + ' directory doesnt exists')
phantom.exit(1);
}
searchLessIn(root, fs);
phantom.exit(0);
it should print parsed css to console
try lesscss maven plugin https://github.com/marceloverdijk/lesscss-maven-plugin
it uses rhino, so instead of 100ms it'll take 3000ms, but it works and all you do is put some xml into pom.xml