How to set proper base for the input files for gulp-concat-css? - css

I am using gulp-concat-css to combine a selected list of CSS into one. My project folder structure look like this:
[]Project Folder
gulpfile.js
---[]public
------[]assets
---------[]libs (All bower install libraries such as bootstrap will be placed here)
---------[]css (All my custom CSS including the combined CSS will be placed here)
Now, my gulp task look something like this:
gulp.task('concatcss', function() {
return gulp.src(['public/assets/libs/bootstrap/dist/css/bootstrap.min.css',
'public/assets/libs/angular-motion/dist/angular-motion.min.css',
'public/assets/libs/bootstrap-additions/dist/bootstrap-additions.min.css',
'public/assets/libs/blueimp-file-upload/css/jquery.fileupload.css',
'public/assets/css/mycustom.css'])
.pipe(concatCss("css/all.css").on('error', standardHandler))
.pipe(minifyCss().on('error', standardHandler))
.pipe(gulp.dest('public/assets'));
});
The problem is the final output come with the wrong url rebase. This cause the CSS URL is pointing to the wrong path of files. For example, the original URL from the bootstrap.min.css is url('../fonts/glyphicons-halflings-regular.woff'). Now, the combined CSS come with the URL of url(../../fonts/glyphicons-halflings-regular.woff), which is wrong. It should be url(../libs/bootstrap/dist/fonts/glyphicons-halflings-regular.woff)
According to gulp-concat-css documentation, it says "for a proper import inlining and url rebase, make sure you set the proper base for the input files".
How can I set the proper base for the input files to get the correct url rebase?

You have to set the base as option in gulp.src like this { base: 'public/assets' }:
gulp.task('concatcss', function() {
return gulp.src(['public/assets/libs/bootstrap/dist/css/bootstrap.min.css',
'public/assets/libs/angular-motion/dist/angular-motion.min.css',
'public/assets/libs/bootstrap-additions/dist/bootstrap-additions.min.css',
'public/assets/libs/blueimp-file-upload/css/jquery.fileupload.css',
'public/assets/css/mycustom.css'], { base: 'public/assets' })
.pipe(concatCss("css/all.css").on('error', standardHandler))
.pipe(minifyCss().on('error', standardHandler))
.pipe(gulp.dest('public/assets'));
});

Related

Add all CSS files in a folder to nuxt.config

In my Nuxt project I have a folder assets/scss/globals/ with a lot of files which should be globally included.
Now in my nuxt.config file I can only include each file by manually like so:
// Global CSS: https://go.nuxtjs.dev/config-css
css: ['./assets/scss/globals/resets.scss'],
What I would need is something like this:
css: ['./assets/scss/globals/*.scss'],
But this doesn't work.
I have the styled-resources package installed as well for variable and mixin definition and there it works:
styleResources: {
scss: ['./assets/scss/variables/*.scss']
},
But the documentation clearly says to not include styles here:
Do not import actual styles. Use this module only to import variables, mixins, functions (et cetera) as they won't exist in the actual build. Importing actual styles will include them in every component and will also make your build/HMR magnitudes slower. Do not do this!
Is what I try to do any different from what the warning in styled-resources says?
CSS option in nuxt.config.js requires an array of files, If you do not want to specify them manually one by one you can simply create a function that returns them like below
Function in nuxt.config.js or import as a util
const styleFiles = (path) => {
const fs = require('fs')
const files = fs.readdirSync(path)
return files.map((i) => path + i)
}
Then use it like so
css: styleFiles('src/assets/scss/globals'),

Injecting SCSS variables with Node and Gulp

I want compile different css files based on different sass variables.
Im trying to use Gulp to achieve this
gulp.task('var 1', function() {
gulp.src(['styles/vars/var1.scss','styles/client.scss'])
.pipe(sass().on('error', sass.logError))
.pipe(concat('clientWithVar1.css'))
.pipe(gulp.dest('./public/'))
});
It doesnt seem to work and im getting a Sass error that a variable doesnt exist.
How can i achieve this? Any help is appreciated
You can try this way:
You have this dir structure:
- tmp (folder)
- _var1.scss
- _var2.scss
- client.scss
In client.scss add: #import "./tmp/var.scss
and add gulp task below, so you just copy and rename scss file with variables that you need and then you can compile your main scss file
var rename = require('gulp-rename');
gulp.task('copy', function() {
return gulp.src('./styles/_var1.scss')
.pipe(rename('var.scss'))
.pipe(gulp.dest('./styles/tmp'));
})
Assuming you've got a directory structure something like this:
vars/var1.scss
vars/var2.scss
vars/var3.scss
vars/var4.scss
styles/1/client.scss
styles/2/client.scss
styles/3/client.scss
styles/4/client.scss
And in each client.scss file you have a corresponding #import statement (e.g. #import "../../vars/var1/.scss";), you should be able to generate all stylesheets with a single task:
gulp.task('sass', function() {
gulp.src('styles/**/client.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./public/'))
});
I think this should end up with public/1/client.css, public/2/client.css etc, but you may have to tweak the gulp.dest line to suit.

How to switch css file when using Webpack to load css?

I use gulp to compile my sass file to css files, and reference the css file in my html. The project support theme switch. For example, I have 3 css theme files:
red.css
yellow.css
blue.css
I can currently switch the theme css like this:
var styleDom = $('#theme-style');
var newHref = 'styles/themes/' + themeName + '.css';
if (styleDom.attr('href') !== newHref) {
styleDom.attr('href', newHref);
}
Now I want to use webpack to load the css file.
require('styles/themes/red.css');
It seems work well, but I cannot find a way to switch the theme css file now, does anyone have a solution?
Your approach doesn’t need to change. Just use Extract Text plugin to save out the CSS files. You’ll need to make multiple entry points to create multiple CSS files.
OR
More ideally, (the approach I would take) make your CSS switch based on a different html or body class and just change the class. It won’t add much overhead, and it will be a more ideal UX when changing themes.
You'll need to use a combination of webpacks style-loader and file-loader (second example ) and use require.ensure (second example "dynamic imports") to accomplish this:
function switchTheme(name) {
// Remove the current theme stylesheet
// Note: it is important that your theme css always is the last
// <link/> tag within the <head/>
$('head link[rel="stylesheet"]').last().remove();
// Since webpack needs all filePaths at build-time
// you can't dynamically build the filePath
switch(name) {
case 'red':
// With require.ensure, it is possible to tell webpack
// to only load the module (css) when require is actually called
return require.ensure([], function () {
require('style-loader/url!file-loader!styles/themes/red.css');
});
case 'yellow':
return require.ensure([], function () {
require('style-loader/url!file-loader!styles/themes/yellow.css');
});
case 'blue':
return require.ensure([], function () {
require('style-loader/url!file-loader!styles/themes/blue.css');
});
default:
throw new Error('Unknown theme "' + name + '"');
}
}
Then a call like switchTheme('blue') should do the trick.
And you might have to check your current webpack.config.js, in case you already have configured a loader for .css files.

gulp concat JS libraries CSS

I am using gulp concat to combine all JavaScript libraries CSS file into one. My gulp task looks something like this:
gulp.task('concatcss', function() {
return gulp.src('assets/libs/**/*.css')
.pipe(concatCss("all.css").on('error', standardHandler))
.pipe(minifyCss().on('error', standardHandler))
.pipe(gulp.dest('dist'));
});
It does work to combine all CSS into one. However, the problem is as the path is changed, any CSS linked file such as url("../fonts/glyphicons-halflings-regular.woff") will fail to load.
How can I overcome the issue? Is there anyway for it to automatically change the path based on the new output CSS file location?
You need to set concatcss options rebaseUrls to false, its true by default
rebaseUrls: (default true) Adjust any relative URL to the location of the target file.
Example:
concatCss(targetFile, {rebaseUrls:false})
In your own case:
gulp.task('concatcss', function() {
return gulp.src('assets/libs/**/*.css')
.pipe(concatCss("all.css", {rebaseUrls:false}).on('error', standardHandler))
.pipe(minifyCss().on('error', standardHandler))
.pipe(gulp.dest('dist'));
});
Other Options (since 2.1.0)
inlineImports: (default true) Inline any local import statement found
rebaseUrls: (default true) Adjust any relative URL to the location of the target file.
includePaths: (default []) Include additional paths when inlining imports
NB:
for a proper import inlining and url rebase, make sure you set the proper base for the input files.
You have to add the base option to gulp.src like this: { base: 'dist' }
Your code reworked:
gulp.task('concatcss', function() {
return gulp.src('assets/libs/**/*.css', { base: 'dist'})
.pipe(concatCss("all.css").on('error', standardHandler))
.pipe(minifyCss().on('error', standardHandler))
.pipe(gulp.dest('dist'));
});

Inlining data-urls with Stylus and Gulp

Currently I have a stylus file that imports another stylus file. This second file uses the URL function like this, and I want it to be inlined (e.g. to a base 64 data-url). However this isn't working when run through my gulp pipeline
lines.styl:
vertical-img = 'vertical.svg';
#import "../tree";
tree.styl
background-image: url(vertical-img)
What I want to get as a result is:
background-image: url('data:image/svg+xml;utf8,<svg>[...]</svg>');
But I get this:
background-image: url("vertical.svg")
And my gulpfile is as follows:
return gulp.src('src/css/*/*.styl')
.pipe(gstylus({
set: ['resolve url']
}))
.pipe(rename(function (file) {
file.dirname = "";
file.extname = ".css";
}))
.pipe(gulp.dest(DEST))
Basically it seems like the 'resolve url' option isn't being passed to stylus. I'm aware that I need it, since it says in the Stylus Docs that:
By default Stylus doesn’t resolve the urls in imported .styl files, so if you’d happen to have a foo.styl with #import "bar/bar.styl" which would have url("baz.png"), it would be url("baz.png") too in a resulting CSS.
But you can alter this behavior by using --resolve-url (or just -r) CLI option to get url("bar/baz.png") in your resulting CSS.
The correct option for image inlining is url (not resolve url) see http://learnboost.github.io/stylus/docs/functions.url.html. To use it in gulp-stylus you should pass url option to options object (see https://github.com/jenius/accord/blob/master/docs/stylus.md#url). For example:
return gulp.src('src/css/*/*.styl')
.pipe(gstylus({
url: { name: 'url', limit: false }
}))
.pipe(rename(function (file) {
file.dirname = "";
file.extname = ".css";
}))
.pipe(gulp.dest(DEST))

Resources