I want to take advantage of .min and .debug versions of js and css files.
Consider this bundle for example:
bundles.Add(
new ScriptBundle("~/scripts/vendor")
.Include("~/scripts/jquery-{version}.js")
.Include("~/scripts/knockout-{version}.debug.js")
.Include("~/scripts/knockout-{version}.min.js")
.Include("~/scripts/knockout-{version}.js")
What is the correct mechanism to take advantage of each file. I mean how set some setting to make ASP.NET smart enough to use .min on final releases and .debug while debugging?
Just use .Include("~/scripts/knockout-{version}.js") and ASP.NET will use ~/scripts/knockout-{version}.min.js in production and ~/scripts/knockout-{version}.js when debugging
You can have the bundler switch between debug and non-debug files if you group them with a wildcard. For example:
bundles.Add(
new ScriptBundle("~/scripts/vendor")
.Include("~/scripts/jquery-{version}.js")
.Include("~/scripts/knockout-*")
Then include in knockout-version.debug.js and knockout-version.js in your ~/scripts/ path.
The bundler will use the debug version if you're in debug mode, or minify the non-debug version and use it if optimizations are enabled.
Related
I'm using Typescript such that there are many differences in Release Mode and Debug Mode.in the Debug Mode i use http://localhost:port/ basic URL. However, in Release Mode I have to use https://www.example.com/
Main problem
it makes me change URLs in Release Mode and Debug Mode Repeatedly. Indeed, There are other parameters that I have to change in Release Mode and Debug Mode manually which may Cause errors to misconfiguring.
What I am looking for
avoiding manually configuration in Release Mode and Debug Mode
Clues and assumptions
there may be a way using Macros in Typescript likewise something that we would use in MsBuild or WebConfig like $(ConfigurationName) And $(ProjectDir)
Best desired solution that I'm looking for
Easiest Solution in which doesn't need to learn Extra and doesn't change project Architecture.IF I have to use webpack, please put complete details around it.
Project framework
Asp.net .Net Framework or Asp.Net Core
Minimal reproduce able code
Consider you ONLY want to change this URL
const URL = http://localhost:port/
To
const URL = https://www.example.com/
in the Release Mode
Possible hard solutions
as #Kaca992 suggested webpack can resolve the issue by using
mode: 'development' and mode: 'production' like:
module.exports = {
mode: 'development'
};
production and development mode extra information
But the above solution has these Cons:
Takes time to learn webpack
Needs to be familiar with the basics concepts of npm
Needs to be familiar with concepts of bundling and minification
Needs working with modules (Import/Export)
You would have to use a environment variable and do checks based on that. You could create a helper method like this:
export function isProduction() {
return process && process.env && process.env.NODE_ENV === 'production';
}
Just be careful that most bundlers cant remove this code (it needs to be an inline check for it to be removed in compile time). If you are using something like webpack you can easily include the NODE_ENV variable using https://webpack.js.org/plugins/define-plugin/ .
This is also an excelent read into the topic: https://overreacted.io/how-does-the-development-mode-work/
Also a good way of dealing with this if you have alot of different setups would be to group all of the different values in a helper module:
debug.config.ts
release.config.ts
and then in your code you use config.ts wich just re-exports based on your configuration:
import * as debug from debug.config.ts;
import * as release from release.config.ts;
const config = isProduction() ? release : debug;
export default config;
I have a huge web application that bundles and minifies a huge amount of javascript and css files.
When we release a new version, we notice that at the first request of each page (controller + view) the software takes a lot of time to respond. So, I started to search a little bit and find out Bundle Caching and it seems when some .js or .css files are changed, the bundle will create a new token. But I have some doubts about it:
When exactly the join and minification of the files is made? It is when it is called at the first time on a view?
There is a possibility that when the software is build, the files will be joined and minified during that process, so when at the first time the virtual path is called, this process already had occurred and cached?
If the slowly problem about my application is not the bundling and minification of the files, what could be?
Thank you.
Note: I'm talking about the process in a production environment. So,
thinks like putting debug=false in the web.config I already have.
1) I would not bet on this one, but I am pretty sure that this needs to be done upfront provided that the version of the bundle is appended to the path as a query string parameter. Since this value is the hash of the bundle result, this needs to be done before any bundle can be downloaded in order for ASP.NET to even be able to add this parameter when you do something like this:
#Url.Content("~/bundles/yourbundle")
Whether it is calculated the first time the bundle url is rendered into the view or at app startup is something I don't know. I still post this answer because I believe I can give you useful information for the 2) and 3) points.
2) It is possible to bundle your files beforehand. You can either use some Gulp or Grunt task, use the Bundler & Minifier extension, or any tool of your preference. In that case, however, you are not required (or even advised1) to use virtual paths as these tools produce physical files. However, you will need to make sure yourself that they are versioned properly so whenever you change some input file, the clients will be forced to download the new one instead of using the one in their cache.
3) Keep in mind that C# is not compiled to machine code. Initial slowness can, and usually is, caused by something called JITting (which is explained in greater detail here), that is, the process of transforming the IL code into machine code. This is a rather lazy process in that it basically happens just before the actual execution of your code. If, for example, you have a method A, it does not get transformed to machine code up until it is actually invoked. Therefore, the first access of every controller/action is slower than subsequent ones (because after the first run, the resulting machine code is kept).
You can also configure your project to compile your views which will cause your app to be slightly faster at the cost of making the build process slower.
1 It is advisable to use physical paths if the files are actually physically present on the disk because like that, you can skip the virtual path resolving process altogether thus making script loading to be a little bit faster.
Bundling and minification is enabled or disabled by setting the value of the debug attribute in the compilation Element in the Web.config file. In the following XML, debug is set to true so bundling and minification is disabled.+
XML
<system.web>
<compilation debug="true" />
<!-- Lines removed for clarity. -->
</system.web>
To enable bundling and minification, set the debug value to "false". You can override the Web.config setting with the EnableOptimizations property on the BundleTable class. The following code enables bundling and minification and overrides any setting in the Web.config file.
C#
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
// Code removed for clarity.
BundleTable.EnableOptimizations = true;
}
Unless EnableOptimizations is true or the debug attribute in the compilation Element in the Web.config file is set to false, files will not be bundled or minified. Additionally, the .min version of files will not be used, the full debug versions will be selected. EnableOptimizations overrides the debug attribute in the compilation Element in the Web.config file
We're using System.Web.Optimization bundling to bundle & compress our JS and CSS.
We also use a custom IBundleTransform implementation in addition to to the existing JsMinify and CssMinify to do some fancy stuff to the JS (replacement of certain placeholders) before sending it to the browser.
Everything works fine as long as we're running in Release mode, because then the bundling and optimizing kicks in. But in Debug mode (which is nice for debugging ;) it seems to completely ignore all the specified IBundleTransform (makes sense in most use-cases, I guess).
Is there any way to always run our own IBundleTransform, even in Debug mode, but run the other (default) bundling algorithms (JsMinify, CssMinify) only when I really want to optimize (in Release mode)?
So the debug/release magic is controlled via the Scripts/Styles helpers. The behavior to not apply any transforms is baked into the implementation of these helpers, so if you want to do this, the best workaround might just be to have a debug/release version of each bundle and always enable bundling via BundleTable.EnableOptimizations = true.
if (!HttpContext.Current.IsDebuggingEnabled)
BundleTable.EnableOptimizations = true;
I have the following ScriptBundle defined in BundleConfig.cs-
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/js/yepnope").Include(
"~/Scripts/yepnope.{version}.js"));
}
}
It isn't in fact the only bundle, but that is all in there that is pertinent to the question - the rest is just other bundle definitions.
When in "debug" mode as set in the web.config-
<compilation debug="true" targetFramework="4.5">
Both the full and minified versions of the script are sent to the browser-
<script src="/Scripts/yepnope.1.5.4-min.js"></script>
<script src="/Scripts/yepnope.1.5.4.js"></script>
The script is added using the HTML helper like so-
#section HeadScripts
{
#Scripts.Render("~/js/yepnope")
}
This is an MVC4 project running in Visual Studio 2012 on Windows 7 Professional 64-bit.
Whatever I do I cannot get the {version} wildcard to behave as described in the Microsoft documentation-
Note: Unless EnableOptimizations is true or the debug attribute in the
compilation Element in the Web.config file is set to false, files
will not be bundled or minified. Additionally, the .min version of
files will not be used, the full debug versions will be selected.
For ASP.NET MVC 4, this means with a debug configuration, the file
jquery-1.7.1.js will be added to the bundle. In a release
configuration, jquery-1.7.1.min.js will be added. 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.
The {version} wild card matching shown above is used to
automatically create a jQuery bundle with the appropriate version of
jQuery in your Scripts folder. In this example, using a wild card
provides the following benefits:
Allows you to use NuGet to update to a newer jQuery version without
changing the preceding bundling code or jQuery references in your view
pages.
Automatically selects the full version for debug configurations
and the ".min" version for release builds.
If I add "EnableOptimizations" it seems to behave as expected.
Has anyone else noticed this or found a solution?
MVC4 only knows how to handle a .min.js file. It doesn't recognize -min.js (with a dash).
The way I typically do this, with easy success, is to get rid of any .min.js or -min.js files provided by libraries that provide both a .js and either a .min.js or -min.js. By default, MVC will automatically minify any bundled .js files when you deploy your website, so there's no need to use the provided .min.js or -min.js files.
This isn't necessarily a direct answer to your particular question - it's a way to circumvent the problem entirely.
Is there any native compression (for javascript/css files) available in ASP.NET?
Try Chirpy. It mashes, minifies, and validates your javascript, stylesheet, and dotless files.
You can use YUI Compressor or Google Closure Compiler.
http://chirpy.codeplex.com/
Or, for more info, check out:
http://www.weirdlover.com/2010/05/22/visual-studio-add-in-for-dotless-js-and-css-files/
In the appendix of Professional ASP.NET 3.5 Scott Hanselman talks about Packer for .NET. This will integrate with MSBuild and pack javascript files for production deployments etc.
You could use Packer.
This utlity supports JavaScript compression and /or "minifying", and CSS "minifying".
It's available as a command line utility or also as an MSBuild task.
This way you can integrate it into your build process / Visual Studio project.
There is Gzip/Deflate compression support in IIS compatible with all modern browsers except IE6. For IIS 7 check this page: http://www.iis.net/ConfigReference/system.webServer/httpCompression
Further to other answers and comments, you can use Yahoo!'s YUI Compressor and make it an MSBuild Task to integration it into your build and deployment process.
Try StyleManager for CSS combination and minification. It uses YUI Compressor under-the-hood.
Its usage is a lot like asp.net's ScriptManager, so it's quick to get used to. It's easy to add to your project too, only takes a minute.
Most importantly - it combines your CSS files too. So instead of having like 10 CSS files to download it'll just be 1, which will also be compressed etc.
I have written something to do this for me, you can download it here:
http://www.picnet.com.au/blogs/Guido/post/2009/12/10/Javascript-runtime-compilation-using-AspNet-and-Googles-Closure-Compiler.aspx
It uses Google's closure compiler which is pretty awesome.
Thanks
Guido
Here is my way:
Use MVC.
Process js|css content via MVC controller's actions.
Combine multiple files into one.
Minify and obfuscate script|css on fly before it stored in cache.
Cache results.
Use CacheDependency.
Enable gzip for dynamic content.
Enable gzip before cache feature.
Everything can be done just by adding custom attributes on action methods, using ASP.NET MVC Js/Css Composer/Compressor.
Sample:
public class JsController : Controller
{
[Utility.Processors.JsCompress]
[OutputCache(Duration = 3600)]
public ActionResult Jquery()
{
return View();
}
}
You can derive from CustomTextPostProcessingAttribute and make your own postprocessing for any type of text content, you need.
I just learned something today: you can run JavaScript via windows console. I'm a fan of cssmin.js; so, this plus windows console = win! All you have to do is download cssmin.js, put it in a folder on your web project and add the following post-build event in Visual Studio:
type "$(ProjectDir)css\*.css" | cscript //NoLogo "$(SolutionDir)tools\cssmin.js" > "$(ProjectDir)css\core.min.css"
Doing this keeps you from having to edit your project as ajaxmin would have you to do.