I am currently using PHP minify to combine and compress the static files (CSS and JS). With PHP minify it is very easy to develop and deploy. Because:
Say there are two files: a.js and b.js and we combine and minify them in ab.js. Now its enough for me to include only one script tag:
<script type="text/javascript" src="http://static.example.com/min/g=ab&v=7"></script>
With this flexibility I can develop in a.js and b.js and at the same time test the final minified version without changing the include tag above. I don't even need to change while releasing.
But now I want to move my static files to CDN server where PHP won't be there, so I guess I have to use YUI compressor to minify and combine before uploading. Now If I am combining a.js and b.js with YUI compressor, I have to change the include tag which I used to develop.
So when developing I've to use:
<script type="text/javascript" src="http://static.example.com/a.js"></script>
<script type="text/javascript" src="http://static.example.com/b.js"></script>
And when uploading I've to use:
<script type="text/javascript" src="http://static.example.com/ab.min.js"></script>
Then it becomes a problem because, the two lines has to be combined into one. Whats your setup to manage this?
Specify the base URL to ab.min.js (i.e. http://static.example.com/) in a config file. In the production config, use the CDN location. In your development config, use the automatically minified location.
Looks like you're comfortable with using different base URLs for development and production, but that combining two lines into one is your problem.
If this is the case, perhaps you want to split this step in two.
Combine a.js and b.js manually into ab.js, but don't minify. You only need to do this once. Now during development you can work directly on the source code in ab.js.
Before uploading, typically as an automated step in your build process, use YUI compressor to minify ab.js.
If you want to keep a.js and b.js separated, then the above will not work for you and you probably need some kind of preprocessor that will modify the script tags in your source code as required.
Related
I'm a bit new to Symfony and I'm don't know what to use for my static file management. I have read about Assets component and the Assetics bundle.
I know that Assets just includes the files and Assetics is a bit smarter as it can combine files and compress images. But I already use compass to minify and combine the css files so therefore Assetics is not really required.
Version control so the url of the static files change to by pass browser cache, is done by both.
Assetics is removed from 2.8 or higher, does this mean it is not best practice anymore?
I need to generate urls on three places:
Twig -> Easy to do with both
Controller -> Found only a way to do this with Assets
In css files -> Believe it is with both not possible
Wat would be the best to use in my case, any advise?
Assetic can be seen as a way to easily apply filters and compile your assets. The asset component basically is used to manage URL generation. As you said, both nicely are integrated in Twig via extensions, and controllers via the services.
Our application uses compass too, but Assetic makes sure that the compiling happens at the right moment without the need of compass watch at the commandline.
Think most of your questions are answered on:
http://symfony.com/doc/current/cookbook/assetic/asset_management.html
and
http://symfony.com/doc/current/components/asset/introduction.html
I've been using the RjFrontendBundle to run the front-end CSS/JS build, and also copy other static content into place from Bower/NPM/local sources. It provides a VersionStrategyInterface for the Assets component that creates, and uses unique filenames in production (renaming the files with an embedded hash, via the GulpJS rev-all package). In dev, it uses the normal filename.
Within CSS files, you can still reference CSS/JS, via a url() function, and the pipeline will rename them appropriately in dev and live.
The GulpJS build tool is used to minify and otherwise prepare the plain files. It comes with a setup console command to build the initial gulpfile.js and can also watch and rebuild files, updating the browser as they are changed, which helps with front-end development workflow.
The trend is to use standalone front end tools such as gulp/grunt/sass instead of assetic. The reasons are (probably) as follows:
gulp / grunt are independent from the framework, providing the same workflow for the front end guy no matter what underlying framework is used for the backend.
assetic has a different workflow than most of the modern tools. It assumes that you will write your script/css includes in the templates. Migrating from assetic to gulp could be a pain for large project.
as your project grows, assetic can become kind of slowish... As that happens, you will stop pulling your assets from the controller and start generating them the way gulp or grunt does. In this scenario, gulp and grunt are just better tools.
assetic lacks some important features, such as including processed assets into HTML code (inline). Because of the way assetic works (twig tags), it might be difficult to overcome this.
As for generating the URLs: assets are just files in the filesystem. Write a function or twig extension to generate URLs to those files.
As asked previously in Have Grunt include different Javascript files in development and production and Have Grunt generate index.html for different setups
I want expanded assets includes for development:
<script src="js/lib-1.js"></script>
<script src="js/lib-2.js"></script>
<script src="js/lib-3.js"></script>
...
And for production or staging:
<script src="js/all-files-in-one.js"></script>
However, I don't want to synchronize my include code in two places. For most of the available answers, I have to specify the list of files in grunt task first and then replicate the include code again in the html. The closest solution I could find is this answer: https://stackoverflow.com/a/21488659/515585, in which I only need to maintain an array of files in the grunt task. And all the answers requires a daunting amount of setup to make it work.
An even better solution would allow me to use sprocket syntax to require other asset files right in the context of the code (instead of using a build file) a la Rails asset pipeline. And expand them with a single switch of variable, so I could debug each individual file in development. I've looked at the grunt-sprockets-directives, but I don't see it offer the expanding option. Maybe it does?
I would like to not use asset pipeline from my backend framework, and I am asking for any front end build tools, not just grunt specifically. Gulp, Yeoman, or even better Broccoli.js answers are also appreciated.
I want some expert advice on ASP.NET MVC Bundling and Minification. I have in my project script files that have both unminified (.js) and minified versions (.min.js). I have included them in my script bundle as follows:
bundles.Add(new ScriptBundle("~/bundles/layout").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/lib/errorhandling.js",
"~/Scripts/lib/errorhandling.min.js",
"~/Scripts/vendor/modernizr.custom.js",
"~/Scripts/vendor/modernizr.custom.min.js",
"~/Scripts/toastr.js",
"~/Scripts/toastr.min.js"));
It seems that the bundle indeed contains only once each script file, not twice. I have confirmed this both for development and production. (As a side note, in development, that is, when debug=true, the bundles are not rendered but the files are included as separate script tags. This is the desired behaviour for me, as well.)
My questions are:
(1) Is this the best and recommended way to include already minified files for production setup and unminified files for development?
(2) Does ASP.NET try to minify the whole bundle in production (even though it is already minified)? If yes, what is the best way to prevent ASP.NET from trying to minify the bundle?
Thanks in advance!
There is no need to specifically include the minified versions in your script bundle. By default, MVC will search for a matching file with .min.js and include that (not entirely sure if it trys to minify further). If not, it creates a minified version. You can test this by adding the following to BundleConfig.cs
using System.Web.Optimization;
then adding the following at the end to override debug=true in development
BundleTable.EnableOptimizations = true;
From MS documentation
The bundling framework follows several common conventions such as:
Selecting “.min” file for release when “FileX.min.js” and “FileX.js”
exist.
Selecting the non “.min” version for debug.
Ignoring “-vsdoc” files (such as jquery-1.7.1-vsdoc.js), which are used only by
IntelliSense.
Minification, or not, the bundling feature is useful to for logical groupings of scripts and css that go together, and as a single place to control things. It also generates unique URLs, so eliminates browser cache problems.
If you use ScriptBundle, the engine will try to minify, (except when you set debug=true as you've shown).
You can turn off minification, but retain bundling, by just using Bundle() instead of ScriptBundle(). See Martin's answer here:
ASP.NET Bundles how to disable minification
As an aside, using pre-minified files with Bundle() as opposed to ScriptBundle(), will preserve the license headers. With jquery's MIT license, it at least stipulates that it should not be removed. I'm not sure how to interpret the fact that the default Microsoft MVC template uses ScriptBundle().
TL;DR: IItemTransform isn't getting executed when a minified file already exists in the same folder as the original (non-minified) file.
Problem explanation
I'm having this issue mainly because of CSS relative image references. If you used IItemTransform with Javascript files, the same applies.
This is what I'm using:
I'm using Visual Studio with Web Essentials addin to have support for LESS files
I'm writing LESS files and have Web Essentials addin automatically minify files on save
I'm also using bundling and minification in my project
When creating CSS bundles I'm using CssRewriteUrlTransform to make CSS URLs absolute (i.e. background images) so that images still work after bundling several CSS files together
Nothing unusual here so far, but it doesn't work.
What seems to be the problem?
The way that bundling and minification works is it tries to avoid excessive processing. This means that when a minified file exists in the same folder as the original one it won't run its own minification and rather serve existing file.
This would be all right as long as it would at least run transforms over those preexisting minified files. But it doesn't. So I end up with relative URLs in a bundle which breaks pretty much all those resources.
Workarounds
Always provide absolute paths in LESS files
Disable file minification on save in Web Essentials settings
Refer to minified files when defining my bundles because they don't have a minified version (*.min.css doens't have a *.min.min.css) so minifier actually picks up the file and minifies while also running transformations over it.
From the standpoint of my development process and tools used (and configured the way they are) this looks like a bug. If those files would be the result of the same minification process this wouldn't be a bug at all as transformations would be executed when minification would execute. It's true that such functionality doesn't exist and likely never will as app would need write permissions to make it work. Outcome: this is a bug. Existing minified files should be processed through transformations before being cached.
Question
Is it possible to somehow convince bundling and minification to either:
not use existing minified file versions
run transformations over existing minified versions
Have you considered using Grunt? http://gruntjs.com/
It has a learning curve, but, the information pool is huge. The issues that you are having with web essentials wouldn't be a problem with grunt.
I'm using it in VS, now, to minify, bundle and transpile both css and javascript as well as reorganize files into a deployment directory. Once you've set up a directory structure, a grunt file could very easily be reused.
With the add-on in VS (linked, below), you can right click on the grunt file and select the grunt tasks to run from a popup menu.
https://visualstudiogallery.msdn.microsoft.com/dcbc5325-79ef-4b72-960e-0a51ee33a0ff
Grunt "tasks" as they are called can be created by downloading various plugins i.e. https://www.npmjs.com/package/grunt-contrib-less.
I have never used LESS or web essentials, so please take this post for what it is worth (not much.) Could you add a pre-build command to simply delete the old files, then do a rebuild when you need to update the CSS.
Drupal has an option to "aggregate" (that is, to combine) multiple js or css files into one, to reduce the number of files going over the network.
Does Meteor have something similar?
Obviously for development it is nicer to have the files all separate. But on production it would be great to have them bundled (and minified).
Yes.
Meteor uses separate files on the development server and combines and minifies js and css files on the production server.
For an example view the source of http://meteor.com.
As a bonus, Meteor has Smart Packages that compile various preprocessors, including:
LESS
Stylus
CoffeeScript
By using the Smart Packages preprocessors, you are free to write the code or styles in your preferred language and Meteor will convert it to javascript or css, on demand.