how to rewrite relative url in minified css with cssmin? - css

I've been looking for a solution to my issue and I've found posts with similar problems, but not the same. I have the following folder structure:
js
└── GUIFramework
├── external
└── WaspFramework
├── Core
└── GUI
└── Controls
└── WaspMask
├── css
│ └── WaspMask.css
└── resources
└── default_loader_circle.gif
Inside WaspMask.css file I have this rule:
.wasp-loader-default {
background-image: url("../resources/default_loader_circle.gif");
}
Well, I've tried to minify it (combined with other css files) with cssmin plugin. My gruntfile is placed in WaspFramework folder, and I want generate the minified css there. The gruntfile file looks like this:
module.exports = function (grunt) {
var _sources = grunt.file.readJSON('./sources.json');
var _filesCSS = _sources.css;
grunt.initConfig({
cssmin: {
wasp: {
options: {
keepSpecialComments: 0
},
files: {
'wasp-bundle.min.css': _filesCSS
}
}
}
});
// load plugins
grunt.loadNpmTasks('grunt-contrib-cssmin');
// register at least this one task
grunt.registerTask('default', ['cssmin']);
};
In _filesCSS I have the paths of all the files to minify and combine, WaspMask.css included.
My problem is that with this configuration of cssmin, the url of the wasp-loader-default class hasn't changed so, obviously, the output file can't find the image. I've tried changing the cssmin options, adding the root property:
options: {
keepSpecialComments: 0,
root: '.',
},
It changes the url to /GUI/Controls/WaspMask/resources/default_loader_circle.gif, but it doesn't work because of the first slash of the path. I would need to get a relative path to the output file (GUI/Controls/WaspMask/resources/default_loader_circle.gif should work) because my application is published under a virtual directory. So I can't use a full path from the root of the application. I've even tried to set other values to root but some of them change the url to a full path and others add the first slash to the returned path.
Any idea about how to solve this?

After being looking for a solution to my problem, I've found the property I need in this issue of the 'cssmin' plugin:
https://github.com/gruntjs/grunt-contrib-cssmin/pull/47
Although I've found a little issue while I was compressing the 'bootstrap.css' file in my vendor's bundle file. This issue and a possible solution (basically, setting "noAdvanced" property to true in the task's options) is explained deeply in the post I did yesterday:
https://github.com/gruntjs/grunt-contrib-cssmin/issues/103
EDIT:
Here is my grunt file:
module.exports = function (grunt) {
var conf = grunt.file.readJSON('sources.json');
grunt.initConfig({
cssmin: {
options: {
keepSpecialComments: 0,
target: 'commonDir',
noAdvanced: true
},
test: {
files: {
'test.min.css': conf.css
}
}
}
});
// load plugins
grunt.loadNpmTasks('grunt-contrib-cssmin');
// register at least this one task
grunt.registerTask('default', ['cssmin']);
};
The target property is the common physical directory to all the files to minify (I load those files through a json file which contains their paths).
noAdvanced property is the option I use to avoid the problem I've explained with bootstrap.css, although in the last comment by #XhmikosR posted in https://github.com/gruntjs/grunt-contrib-cssmin/issues/103, he says that there is a patch to fix it. I've not checked it yet.

Related

Vue CLI Run separate CSS build?

I'm trying to run a completely separate css/sass build to a specific file.
So I have a folder in my src like:
/src
/sass
./index.sass
./btn.sass
./etc.sass
I'm trying to get it to output to a specific file like "build.css" or whatever which would just end up in the default build directory of "dist" as "dist/build.css".
Been trying to play with vue.config.js and chainWebpack but totally lost here.
Any suggestions how to accomplish this?
One way to do this is to add a Webpack entry that points to the Sass file you want to bundle (using configureWebpack.entry):
// vue.config.js
const { defineConfig } = require('#vue/cli-service')
module.exports = defineConfig({
⋮
configureWebpack: {
entry: {
app: './src/main.js',
extCss: './src/sass/index.sass', 👈
},
},
})
This has a downside as it also generates a .js file that is effectively a no-op. You'd have to delete that manually as a cleanup step:
dist/css/app.css
dist/css/extCss.css # CSS bundle of Sass output
dist/js/app.js
dist/js/chunk-vendors.js
dist/js/extCss.js # no-op file (delete me)
Also delete the <script src="/js/extCss.js"></script> from dist/index.html.

Using GruntJS to delete old files

Hello people of the world. I've been trying to automate my grunt workspace for a static web app. An example of my file structure is below. My current grunt setup watches for changes in files in the src folder, and if there is a change, it processes and updates only the files that have changed using grunt-newer, and puts them in the minified folder.
Let's say that I delete styles.scss from the src folder. Then I also need the corresponding styles.css to get deleted. Is there any way that I can automate this with Grunt? As shown in the problem above, I also need it to know that styles.css in the minified folder corresponds to styles.scss in the src folder.
File structure:
src
styles.scss
index.haml
minified
styles.css
file.html
Edit: Something like this: https://github.com/tschaub/grunt-newer/issues/15
Note that there is no solution to that issue
You can do something like this on your GruntFile:
sass: {
dist: {
files: {
'style/style.css' : 'sass/style.scss'
}
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['clean','sass'],
options: {
event: ['deleted'],
},
}
},
clean: {
dist: {
files: [{
src: [
'dist/*.css'
]
}]
}
}
As it, if you delete (and only deleted) a .saas file, your dist folder will be automaticly cleaned and your sass file rebuild.
It use:
grunt watch: https://github.com/gruntjs/grunt-contrib-watch
grunt saas: https://github.com/gruntjs/grunt-contrib-sass
grunt clean: https://github.com/gruntjs/grunt-contrib-clean
A nice tutorial: http://ryanchristiani.com/getting-started-with-grunt-and-sass/
Hope this help!

sass file not compiled by gulp

I want to switch from less to sass so I installed gulp-sass with npm and modified my gulpfile to compile sass instead of less (nothing else changed). Sadly gulp doesn't compile my .scss file to css and after googling and trying all i could think of it still doesn't compile. Here are all the informations I can show you:
gulpfile.js
// GULP CONFIG
// REQUIRES
// general
var gulp = require('gulp');
// css
var sass = require('gulp-sass');
var minifycss = require('gulp-minify-css');
var autoprefixer = require('gulp-autoprefixer');
var rename = require("gulp-rename");
// watch
var watch = require('gulp-watch');
// TASKS
// css
gulp.task('css', function() {
gulp.src('style.css') // get the 'all-import' css-file
// .pipe(sass({includePaths: ['./styles']}))
// .pipe(sass().on('error', sass.logError))
.pipe(sass()) // sass to css
.pipe(autoprefixer('last 2 version', { cascade: false })) // autoprefix
.pipe(minifycss()) // minify
.pipe(rename('style.min.css')) // rename to style.min.css
.pipe(gulp.dest('')); // output to root
});
// watch
gulp.task('watch', function() {
gulp.watch('styles/*', ['css']);
});
// RUN DEFAULT
gulp.task('default', ['watch']);
related Folders & Files
├── style.min.css
├── style.css (with #import styles/style.scss)
│ └── styles
│ ├── style.scss
terminal response:
starting gulp:
[10:19:14] Starting 'watch'...
[10:19:14] Finished 'watch' after 11 ms
[10:19:14] Starting 'default'...
[10:19:14] Finished 'default' after 20 μs
after saving style.scss
[10:19:20] Starting 'css'...
[10:19:20] Finished 'css' after 15 ms
style.scss (content on purpose of testing obviously)
$color: #99cc00;
body {
background-color: $color;
.sub {
color: $color;
}
}
style.min.css after running through gulp
$color:#9c0;body{background-color:$color;.sub{color:$color}
You are not telling gulp to watch for sass file. On this line:
gulp.src('style.css')
You are specifying a css file, not a scss file. Change it to :
gulp.src('style.scss') // update, s missing
Also, there is no output route specified. This line:
.pipe(gulp.dest(''));
Should contain your destiny route, and its currently empty.
So, for the root route, something like this should work:
.pipe(gulp.dest('./')); // or whatever route you want
Anyway, your file structure is a bit weird.
In my opinion, you should create different folders for sass files and compiled ones.
Hope this puts you on the right track.

With Grunt, how can I compile all *.less files, if I have global mixins and constants?

I want to organize my HTML, JS, and LESS by module. I'm already using Grunt to compile *.js and *.html from my source folders.
So I configured grunt as follows:
grunt.initConfig({
less: {
ALL: {
files: { 'compiled.css': '**/*.less' }
}
}
}
But this runs into a major problem: constants and mixins from my /helper/*.less files are not accessible to other .less files.
It seems like grunt-contrib-less compiles each individual .less file, and then combines the output, but doesn't compile anything "globally".
The only solution I can think of is to create and maintain a master.less that #imports each individual .less file. But I'm trying to achieve an extremely modular build process, and I don't have to list any HTML or JS files, so I'm really hoping to find a *.less solution too!
Thanks to #seven-phases-max for the following answer!
less-plugin-glob
Allows you to use wildcards in #import statements! Works perfectly!
// master.less
#import "helpers/**/*.less";
#import "modules/**/*.less";
And all you need to add to your Grunt configuration is the plugins option:
// Gruntfile.js
grunt.initConfig({
less: {
'MASTER': {
src: 'master.less',
dest: 'master.css',
options: {
plugins: [ require('less-plugin-glob') ]
}
}
}
});
And, don't forget, npm install less-plugin-glob.
Here's one way to achieve an effortless development experience.
However, it requires a generated file and a custom task.
Auto-generate the master.less file
Create a task that generates master.less by writing an #import statement for each *.less file:
grunt.registerTask('generate-master-less', '', function() {
generateFileList({
srcCwd: 'modules',
src: '**/*.less',
dest: 'less/master.less',
header: '// THIS FILE IS AUTOMATICALLY GENERATED BY grunt generate-master-less\n',
footer: '// THIS FILE IS AUTOMATICALLY GENERATED BY grunt generate-master-less\n',
template: '#import "<%= filename %>";\n',
join: ''
});
});
function generateFileList(options) {
var _ = grunt.util._;
var files = grunt.file.expand({ cwd: options.srcCwd }, options.src);
var results = files.map(function (filename) {
return _.template(options.template, { 'filename': filename });
});
var result = options.header + results.join(options.join) + options.footer;
grunt.file.write(options.dest, result);
}
Then, use grunt-contrib-less to just build master.less.

Add grunt task to linemanjs application.js

I want to add a grunt task (specifically angular-template) to my lineman application.js file. There is some documentation found here and here. However, it just tells me to add the grunt task to loadNpmTasks. The problem is that from a fresh project created using lineman, my application.js file does not have a loadNpmTasks array, nor do the comments point out where I should put it. Both examples I have found in the documentations do not show what the application.js file should look like in it's entirety.
The application.js file should look something like this (obviously the src/dest options are not configured correctly:
module.exports = function(lineman) {
return {
loadNpmTasks:['grunt-angular-templates'],
ngtemplates: {
app: {
src: '**.html',
dest: 'templates.js'
}
}
};
};
Then to run the task:
lineman grunt ngtemplates

Resources