My grunt script generated by yeoman concats and minifies js files through useminPrepare, concat, and uglifyjs.
This is working great, but there is one js script that I do not want it to minify. How do I specify that in the grunt file?
What you can do it's to put the files you don't want to minify outside of the build script, for example:
<!-- build:js js/app.js -->
<script src="js/app.js"></script>
<script src="js/minifythis.js"></script>
<script src="js/models/minifythis.js"></script>
<!-- endbuild -->
<script src="js/do-not-minify-this.js"></script>
I spent days looking for a solution to a problem similar to yours, and then I found a different question that has a answer that may fit solve your problem, as it solved mine: https://stackoverflow.com/a/24819171/785985
The solution is to define custom blocks to be processed by Grunt. Then you can specify one block with ['concat'] and another with ['concat', 'uglifyjs'].
If you choose to exclude the files from the minification tag per the item from John Locke, don't forget to manually copy those files to the 'dist' dir. Normally, when you minify files the resultant minified library is copied to the dist dir. But since you're not minifying them, you have to copy them yourself.
For example, I didn't want to compress the user scripts in my app to make it easier for people to examine the code online. After editing my 'index.html' to remove them from the tag:
'<!-- build:js({.tmp,app}) scripts/scripts.js -->'
I had to add the following to the copy step of my Gruntfile:
copy: {
dist: {
files: [
...
{ // manually copy all the files you are not minimizing:
expand: true,
cwd: '<%= yeoman.app %>/scripts/',
src:"{,*/}*.js",
dest:"<%= yeoman.dist %>/scripts/"
}
]
},
...
},
The syntax for copying files is very prickly in Grunt. It took me a couple of tries to get it right.
Just need to set a minimize option of that script to false in Gruntfile.js.
optimization: {
minimize: false
}
Related
webpack doc for loading css:
https://webpack.js.org/guides/asset-management/#loading-css1
The webpack doc asks to import the CSS files from the Javascript code and to then run extract-text-webpack-plugin to extract the CSS.
--> with webpack, why should one import CSS files from JS source code and not build CSS in isolation like the tradition did?
By not importing CSS from Javascript, I mean that the webpack config for CSS has no ".js" extension, and it parses the CSS/SCSS files directly.
There are benefits of not importing CSS from javascript:
(objective fact). If one wants to build only CSS, it will be faster if the bundler does not need to parse the Javascript source code. Besides, one can run the bundlers for CSS and Javscript in parallel by using parallel-webpack.
(subjective, based on tradition, but most important in my opinion). SASS building in isolation has been the tradition for years. Therefore, we can achieve better HTML semantics and maintainability. Importing CSS from JS is virtual and may lead to neglect the generated separate CSS bundle.
(objective fact) One can split more the config files for CSS and Javascript, for more clarity.
I'm more a traditionalist than most as i've been doing this for over 15 years, but I would say the new way to separate concerns is better than the traditional way.
In the old thinking we use to separate layout from styling from functionality (html from css from js). This is more 'vertical' and made knowing where files are easy, but made finding specific code to do with 'features' hard. I.e. a button might be made up of a small button section within /src/shop-front.html, a few lines of code within /src/css/shop-front.css and then the enhanced functionality would live somewhere in /src/js/shop-front.js
The new way of thinking is to separate concerns by components. So now you would have your shop-front, but this would be made from /src/components/button/ and all files will live in the same place. Including the js file which includes the css as mentioned.
The benefit being, if you decide to swap button for fancy-button all you do is change the shop-front import button from 'button' to import button from 'fancy-button'. all old code will be removed automatically. no need to try to digest and change code in multiple places.
To address your concerns:
true, node-sass is fast, but I would say the difference between that and going via webpack is negligible and the improvement in dev experience (as mentioned above) is worth any extra ms
This point does apply as the way the css/sass is built does not change just because we require it from a js file. I guess you mean if you were to use css modules, but this is a choice, you don't have to. I use sass and apply class names as i would normally.
In webpack config, you could split the js config from the css config if you wanted to. I wouldn't argue that this would make things any clearer though. the config is so small, it's not worth worrying about.
My folder structure is nice and easy to reason with:
This is a basic config for simple scss imports
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { SRC, DIST } = require('./src/config/paths');
module.exports = {
devtool: 'source-map',
cache: true,
context: SRC,
entry: {
app: [`${SRC}/client-entry.js`]
},
output: {
path: DIST,
filename: '[name]-[chunkhash].js',
publicPath: '/'
},
plugins: [
new ExtractTextPlugin('[name]-[contenthash].css'),
],
resolve: {
modules: ['node_modules', SRC],
extensions: ['.js', '.jsx', '.scss']
},
module: {
rules: [
{
test: /\.jsx?$/,
include: [/src/],
loader: 'babel-loader',
options: {
cacheDirectory: true
}
},
{
test: /\.s?css$/,
include: [/src/],
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader']
})
}
]
}
};
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
I'm learning grunt and it's wonderful!
background:
My project is built using SASS (.scss), and I use grunt's compass plugin to compile multiple .scss into a single .CSS on output.
problem:
I am using a jQuery plugin which has a .css file associated with it. I want my Grunt to do as follows:
Compile *.SCSS into frontend.css
when done, concat plugin.css onto the end of frontend.css
minify frontend.css.
I have tried adding a concat rule for my CSS, which runs after the grunt compass compiling. The concat rule is shown below.
concat: {
css: {
src: ['www/assets/css/frontend.css',
'bower_components/bootstrap-datepicker/css/plugin.css'],
dest: 'www/assets/css/frontend.css'
}
}
Here is what the grunt task looks like:
grunt.registerTask('default', ['newer:concat:vendors', 'copy', 'uglify', 'compass:dist', 'newer:concat:css', 'newer:cssmin', 'newer:imagemin']);
Here are a list of the Grunt plugins I am using:
// Load Grunt Tasks
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-newer');
if I call concat:css, plugin.css is concatenated, however each time I run the task it is added on again, again, and again, so multiple copies of the same CSS are being inserted into the file.
if I call newer:concat:css, the file is not ever concatenated onto frontend.css.
Any help much appreciated!
The easiest solution would be to use grunt-contrib-clean, which can simply delete the file on every build:
clean: {
css: ['www/assets/css/frontend.css']
}
Or without installing a plugin:
grunt.registerTask('clean:css', function () {
grunt.file.delete('www/assets/css/frontend.css');
});
Does anybody know the best approach for versioning static content such as .html, .js, .cc, etc. when using ASP.NET and angularjs.
So far the only thing I found is manipulating Etag in custom httpmodule.
Any ideas?
Take a look at Bundling and Minification in ASP.Net
http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
This will add versioning to your .jS and .CSS assets. It is a good starting point and can be extended with plugins or custom configuration/code to fit your needs.
There are plugins that support TypeScript, CoffeeScript, Less and Sass.
The other benefit to this is that as well as versioning your assets, this will bundle them together to reduce requests -- and minify them to reduce size.
You can use Grunt to build your js, css etc. All you need to do asset versioning is use grunt-filerev and grunt-usemin plugins.
The first one will version files in the file system and the second one will update all static references throughout html and css to the versioned files.
I have done the same in a web.api / angularjs project using something as simple as:
filerev: {
options: {
encoding: 'utf8',
algorithm: 'md5',
length: 8
},
all: {
src: [
'<%= project.dist %>/scripts/spa.min.js',
'<%= project.dist %>/images/**/*.{jpg,jpeg,gif,png,svg,ico}',
'<%= project.dist %>/styles/spa.min.css'
]
},
},
usemin: {
html: 'index.html',
css: 'Content/**/*.css'
},
Note: the above does revisioning. If you need to add a version number you can take a look at grunt-version (I am doing revisioning with a banner on top of generated files with version and timestamp instead)
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"
}
}
}