Gulp bundle minification breaks Bootstrap Glyphicon CSS content - css

I'm using Gulp to bundle all my dependencies CSS files, including Bootstrap into on file.
However when I minify the bundled file I loose the bootstrap unicode.
So for a non-minify bundle I can see the glyphicon styling:
.glyphicon-star:before {
content: "\e006";
}
But in the minified bundle the glyphicon styling becomes this:
.glyphicon-star:before{content:""}
My gulp code is the following:
var gulp = require("gulp"),
concat = require("gulp-concat"),
cssmin = require("gulp-cssmin");
...
gulp.task("min:css", function () {
var tasks = getBundles(regex.css).map(function (bundle) {
return gulp.src(bundle.inputFiles, { base: "." })
.pipe(concat(bundle.outputFileName))
.pipe(cssmin())
.pipe(gulp.dest("."));
});
return merge(tasks);
});
Any idea why this happens?

Okay, I found the root of the issue and it's not to do with gulp at all. To elaborate more, my setup for web development is VS2015 and in it they have an extension that will help bundle and minify the files and that extension is what causes the glyphicon to break.
One way to get around this issue is to configure the bundleconfig.json to create a separate minify file like this:
{
"outputFileName": "core/lib/dependencies.css",
"inputFiles": [
"core/lib/bootstrap/css/bootstrap.css"...
],
"minify": {
"enabled": false
}
},
{
"outputFileName": "core/lib/dependencies.min.css",
"inputFiles": [
"core/lib/bootstrap/css/bootstrap.min.css"...
],
"minify": {
"enabled": false
}
},
So just to recap - VS2015 will break glyphicon should you decide to bundle all your thirdparty css libraries!

Related

Gulp & Foundation 6 not compiling

I am trying to use foundation sites in my project so I downloaded it using bower.
I have a gulp.config.js file which has the following code:
module.exports = function() {
// PATHS TO JS AND SASS
var GETPATHS = {
VENDOR: [
'bower_components/jquery/dist/jquery.min.js'
],
JS: [
'bower_components/foundation-sites/js/foundation.core.js',
'src/assets/**/*.js'
],
SASS: [
'bower_components/foundation-sites/scss',
'src/assets/scss/components'
]
}
return GETPATHS;
}
and my gulpfile itself has this (SASS):
gulp.task('sass', function() {
return gulp.src('src/assets/scss/app.scss')
.pipe(sass({ includePaths: config.SASS }))
.pipe(autoprefixer())
.pipe(cssnano())
.pipe(gulp.dest('_build/assets/css'))
.pipe(browserSync.stream());
});
and here's my app.scss file
#import "foundation";
Now, the problem is I don't know why app.css (after getting compiled) is showing an empty file. The import "foundation" doesn't seem to work. Any help is appreciated as I am quite new to this. Thanks!
I suggest installing one of the Foundation Sites templates or using the foundation cli to bootstrap a project and get the needed file with all imports.
foundation.scss just contains the mixins.
You can see an example for the right config at https://github.com/zurb/foundation-zurb-template/blob/master/src/assets/scss/app.scss and https://github.com/zurb/foundation-sites-template/blob/master/scss/app.scss
Also see Gulp & Foundation 6 not compiling

Include 3rd party css in ionic2

How to include a 3rd party css in ionic2? I guess it is probably linked to webpack config but I can't find any example anywhere, does someone know? for example, adding font-awesome css file after npm install font-awesome
For those who are interested in this, you can just add the files in the build process in the ionic.config.js like:
module.exports = {
...
sass: {
src: [
'app/theme/app.+(ios|md).scss',
'node_modules/font-awesome/scss/font-awesome.scss'
],
dest: 'www/build/css',
include: [
'node_modules/ionic-framework',
'node_modules/ionicons/dist/scss',
'node_modules/font-awesome/scss'
]
},
fonts: {
src: [
'node_modules/ionic-framework/fonts/**/*.+(ttf|woff|woff2)',
'node_modules/font-awesome/fonts/*.+(ttf|woff|woff2)'
],
dest: 'www/build/fonts'
}
...
}
This will compile font-awesome.css under www/build/css and fonts under www/build/fonts
ionic.config.js has been deprecated.
The correct answer is now:
npm install font-awesome
Then edit your gulpfile.js to add options to the sass and fonts tasks:
gulp.task('sass', function(){
return buildSass({
sassOptions: {
includePaths: [
'node_modules/ionic-angular',
'node_modules/ionicons/dist/scss',
'node_modules/font-awesome/scss'
]
}
});
});
gulp.task('fonts', function(){
return copyFonts({
src: [
'node_modules/ionic-angular/fonts/**/*.+(ttf|woff|woff2)',
'node_modules/font-awesome/fonts/**/*.+(eot|ttf|woff|woff2|svg)'
]
});
});
You can find more information on the gulp tasks here: https://github.com/driftyco/ionic-gulp-tasks.
Then you should be able to #import "font-awesome" in your app/theme/app.core.scss file and use it in your project wherever.
You can normally put css files in the index.html page and just use the css classes wherever you want. By default, your components are not completely isolated from the outside world so you should be able to use lets say bootstrap without any problems

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.

With Webpack, is it possible to generate CSS only, excluding the output.js?

I'm using Webpack with the extract-text-webpack-plugin.
In my project, I have some build scripts. One of the build scripts is supposed to bundle and minify CSS only. As I'm using Webpack for the other scripts, I found it a good idea to use Webpack even when I only want to bundle and minify CSS.
It's working fine, except that I can't get rid of the output.js file. I don't want the resulting webpack output file. I just want the CSS for this particular script.
Is there a way to get rid of the resulting JS? If not, do you suggest any other tool specific for handling CSS? Thanks.
There is an easy way, no extra tool is required.
There is an easy way and you don't need extra libraries except which you are already using: webpack with the extract-text-webpack-plugin.
In short:
Make the output js and css file have identical name, then the css file will override js file.
A real example (webpack 2.x):
import path from 'path'
import ExtractTextPlugin from 'extract-text-webpack-plugin'
const config = {
target: 'web',
entry: {
'one': './src/one.css',
'two': './src/two.css'
},
output: {
path: path.join(__dirname, './dist/'),
filename: '[name].css' // output js file name is identical to css file name
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader'
})
}
]
},
plugins: [
new ExtractTextPlugin('[name].css') // css file will override generated js file
]
}
Unfortunately, that is currently not possible by design. webpack started as a JavaScript bundler which is capable of handling other "web modules", such as CSS and HTML. JavaScript is chosen as base language, because it can host all the other languages simply as strings. The extract-text-webpack-plugin is just extracting these strings as standalone file (thus the name).
You're probably better off with PostCSS which provides various plugins to post-process CSS effectively.
One solution is to execute webpack with the Node API and control the output with the memory-fs option. Just tell it to ignore the resulting js-file. Set the output.path to "/" in webpackConfig.
var compiler = webpack(webpackConfig);
var mfs = new MemoryFS();
compiler.outputFileSystem = mfs;
compiler.run(function(err, stats) {
if(stats.hasErrors()) { throw(stats.toString()); }
mfs.readdirSync("/").forEach(function (f) {
if(f === ("app.js")) { return; } // ignore js-file
fs.writeFileSync(destination + f, mfs.readFileSync("/" + f));
})
});
You can clean up your dist folder for any unwanted assets after the done is triggered. This can be easily achieved with the event-hooks-webpack-plugin
//
plugins: [
new EventHooksPlugin({
'done': () => {
// delete unwanted assets
}
})
]
Good Luck...

Ignore package target path when using grunt-bower

I'm experimenting with grunt/bower for a project and I have the following content structure:
content
css
js
I've got grunt/bower working on my own files, but I'm trying to incorporate jquery now and the bower task keeps putting jquery in content/js/dist/jquery.js where I'd rather have content/js/jquery.js. In other words, I want to strip / ignore the dist folder when copying the file. So far, my task looks like this:
bower: {
install: {},
dev: {
dest: 'Content',
js_dest: 'Content/js',
less_dest: 'Content/css',
css_dest: 'Content/css',
options: {
packageSpecific: {
"jquery": {
dest: 'Content/js'
}
}
}
}
},
How can I tell the bower task to copy the dist/jquery.js from the jquery package file to the specific path content/js/jquery.js in my app?
You can use the keepExpandedHierarchy option (flattened output structure) in order to achieve this behavior. You can set is specifically on for jquery:
bower: {
install: {},
dev: {
dest: 'Content',
js_dest: 'Content/js',
less_dest: 'Content/css',
css_dest: 'Content/css',
options: {
packageSpecific: {
'jquery': {
keepExpandedHierarchy: false
}
}
}
}
}
When running grunt bower the jquery.js file is copied to Content\js\jquery.js:
>grunt bower
Running "bower:install" (bower) task
Running "bower:dev" (bower) task
Content\js\jquery.js copied.
Done, without errors.

Resources