Using r.js to concatenate CSS - css

I'm working on a project using require.js and plan to optimize it using r.js. The optimization for javascript files is built in as part of the require configration automatically.
What I would like is to split the CSS into several different files, e.g. head.css, body.css, main.css, etc. When r.js runs, it should concatenate these into a single file. The HTML would have:
<link rel=stylesheet type=text/css href=css/main.css>
A problem is that during development, the files will still be split up. I'd like to keep them split and don't want to have to redo the optimization every time -- even if it can be done automatically.
I'd also like to be able to keep the HTML with just the one stylesheet reference even in development. What would be the optimal way to do this?
There are several possibilities that I can see, each with potential problems:
Have main.css use #import to include all other CSS files.
Not automatic -- have to edit main.css for each file. That's not a big deal since the number of files will be relatively small and probably all known very early on.
r.js does not optimize this
Use require-css
This seems to be geared more towards AMD loading of CSS -- I'd rather load all the CSS up front
Same issues with automatic loading of CSS files as the other option
Create my own script that calls r.js without CSS optimization, concatenate all of the CSS files and minify appropriately.
I'm sure there's someone out there who has done this better than I will

I use grunt-contrib-cssmin which works great. You can also pass arguments to grunt, so you can have grunt:dist combine all your css and plain grunt will leave them separate.
module.exports = function (grunt) {
grunt.initConfig({
cssmin: {
add_banner: {
options: {
banner: '/* My minified css file */'
},
files: {
'dist/css/dist.min.css': ["bower_components/bootstrap/dist/css/bootstrap.css", "tmp/css/dist.css"]
}
}
}
})
}
Grunt getting started.
There is also a requirejs script for grunt. The setup looks like this:
requirejs: {
compile: {
options: {
baseUrl: "path/to/base",
mainConfigFile: "path/to/config.js",
out: "path/to/optimized.js"
}
}
}

Related

Proper way to add SASS to .NET 6 Blazor application?

So I've been searching a bit and it seems like using Delegate.SassBuilder is a good way to add SASS to your Blazor project. It detects any .scss files and builds them into .css files in the same directory.
It works as expected, however, I'm looking for more customization regarding "code behind" files, but with CSS files instead (not sure what the right term is except "code behind but for css"). By default, your Blazor application will contain files such as this:
So you have a .razor file, and then you have a .razor.css file. In index.html, it adds <link href="projectname.styles.css" rel="stylesheet" /> automatically, which handles these styles.
However, if I rename that .css file to .scss and build the application, I end up with this result:
It works, but I have to build it first, then run the application. Quite annoying. What's also annoying is that the files are no longer nested. I would like to see something like this instead:
What would be even better, is that the .css file is hidden and I just have to deal with the .scss files. I honestly don't care what the .css file contains, as it has been minified and so on.
There must be a better way, but I can't really find it.
Okay, so it seems like I have two options:
A) Create a .filenesting.json file and have this as the content as the extensionToExtension (might need to be modified a bit):
"extensionToExtension": {
"add": {
".razor.css": [ ".razor.scss" ],
".razor.css.map": [ ".razor.css" ],
".css": [ ".scss" ],
".razor.scss": [ ".razor" ],
".cs": [ ".cshtml", ".razor" ]
}
}
B) Somehow get <None Remove="**/*.razor.css" /> inside .csproj to work. As it is right now, the engine that handles CSS isolation does not look at excluded files.
For now I'll stick with option A, because that seems to work:

What is the current best way to handle a CSS entry file in Webpack?

This should be simple, but I'm kind of stumped over how complex it's turning out to be.
What I would like to do is have a simple reference to my CSS in my Webpack config's entry list:
entry: {
'app.js': './src/app/index.js',
'app.css': './src/app/app.css',
},
output: {
filename: 'web/[name]',
},
app.css can import other files through the standard CSS syntax: #import url('./morestuff.css'); I would like these to be inlined as Webpack does for JS imports.
I would like that to be exported as normal. For the config above that means outputting it into 'dist/web/app.css'.
I don't want:
To import/require CSS in my JS
To have it output a JS file that either includes the CSS as a string, or dynamically loads the CSS file itself
To do any HTML rewriting
What I've tried/considered:
Using css-loader outputs JS instead of CSS.
Using css-loader along with mini-css-extract-plugin will import/concat the files as I'd like, but the actual entrypoint output file is JS, and the CSS file it makes is in the wrong folder and renamed to app.css.css. If I try mini-css-extract-plugin without css-loader then it can't handle # characters (I think it's trying to load the file as JS.)
Using the sequence of loaders ['file-loader', 'extract-loader', 'css-loader'] as indicated in the extract-loader documentation, but it behaves as above (except the CSS is output with a hashed filename.)
Lots of old SO questions refer to extract-text-webpack-plugin, but that is now an archived project.
style-loader is about HTML rewriting, not what I want.
Now this may not be the "proper" way to handle CSS in Webpack, which does seem to be based on importing everything from your JS, but it's surely a common enough pattern. Any ideas?

Include pdf.worker.js in one minified JS file

PDF.js needs file named pdf.worker.js. That's fine if you include PDF.js into your HTML like <script type="text/javascript" src="plugins/pdfjs-dist/build/pdf.js"></script>
PDF.js will look in that very place where pdf.js is stored (in my case, plugins/pdfjs-dist/build/) for its worker file. However, in my case, I'd like to concatenate and minify all of my JavaScript dependencies into one file. (Via Grunt.)
How do I do that for that pdf.worker.js file? How can I include it into my one-and-only JS file?
So, far what I do in Grunt is
copy: {
build: {
files: [
{ src: 'src/plugins/pdfjs-dist/build/pdf.worker.js',
dest: 'dist/name_of_my_app.worker.js'
}
]
}
}
That works, but it's far from an elegant solution. Aside from looking ugly and the necessity of an additional file, there is a high chance that someone might rename name_of_my_app into something else, overlooking that copy process and thus breaking PDF.js

Nggettext globalization + grunt automization + jade templates

I found this super informative and useful article about globalization using angular's gettext directive and grunt. Problem is, it seems to extract from .html files only and I can't really get it running with jade.
I am using Node.js for my server, together with Express.js, so I convert my .jade files to .html files on the fly, on each user request. I really like the way express and jade fit together, so I am searching for a solution, which extracts translations from those jade files.
For now I tried changing the grunt task snippet to:
grunt.initConfig({
nggettext_extract: {
pot: {
files: {
'po/template.pot': ['**/*.jade']
}
}
}
});
And also adding the translation directive as I do for all other angular directives, e.g.:
h3(translate) About
To add jade file support to angular-gettext you would need to modify extract.js in the angular-gettext-tools project because that is what is actually scanning and extracting the text. It doesn't look like a trivial change.
I would suggest a different approach. See if you can generate html for all the jade files as part of a build process and then run the angular-gettext tools against that. Then you continue to develop as you like but you do not to need to add jade support to angular-gettext.

How can I customise Bootstrap without losing the changes?

I'm using Bower to manage Bootstrap and would like to make some changes (colours, font size etc) to the default Bootstrap look and feel. Here's my workflow:
Edit bower_components/bootstrap/less/variables.less
Recompile bootstrap using grunt build
The problem is that I want to be able to upgrade bootstrap when a new version comes out and presumably I'll lose my changes to variables.less.
Is there a way I can keep my changes outside of bower_components and also avoid having bower_components in source control since it's 122MB?
you can create a variables-custom.less and import it into theme.less like this:
//
// Load core variables and mixins
// --------------------------------------------------
#import "variables.less";
//import custom-variables after variables so the values will override.
#import "custom-variables.less"; //only has variables that have changed.
#import "mixins.less";
IMO this is a little bit better than the first solution because you wont have to load two (almost) identical CSS files on the client.
I'm sorry I cant help you with what to to about Bower and your source control as I do not use Bower
Here's the solution which worked for me:
Use bower to install all UI packages e.g. bower install bootstrap chosen
Create a separate folder less which contains all the LESS modifications. This article was very helpful here.
Here's my less/styles.less file:
#import "../bower_components/bootstrap/less/bootstrap.less";
#import "../bower_components/bootstrap-chosen/bootstrap-chosen.less";
//My custom variables - overrides the bootstrap variables file
#import "variables-custom.less";
Use grunt to monitor changes within the less folder and compile them into .css
Here's my Gruntfile.js (thanks to this answer):
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
paths: ["./less"],
yuicompress: true
},
files: {
"./static/css/styles.css": "./less/styles.less"
}
}
},
watch: {
files: "./less/*",
tasks: ["less"]
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
};
This is indeed the best customization method. You create a theme.less and pull in original Bootstrap files (which can get upgraded in the future) and in the same file you call your own custom overrides. Either you #import them from a custom file which is not in the Bower directory or you just write your custom rules in your theme.less itself. You'll find this technique explained in this tutorial as well.
With Grunt, custom setups can get tricky. But with Brunch it's a piece of cake (yes!) and all pretty much goes automatically. Your grandma could do it.
As for avoiding the inclusion of bower_components in source control: with Git it's easy. You just check-in your bower.json but make sure to add /bower_components to your .gitignore file.
You should just create your own style sheet, use both with your custom one listed secondly. That way you can make changes but not change bootstrap at all.
Also, when you update, you keep your style sheet the same.
This allows you to change bits and pieces of Bootstrap but not actually changing the file, you're overriding it.
To be clear, your second CSS file would be SIGNIFICANTLY smaller... Only putting things your needed to change in it.

Resources