4

I am using ASP.NET MVC 5 to develop my website. I'm using Grunt to minify my CSS and JS. Everything works fine, but I need to change the route source of my files if I'm making a publish (release mode) or I'm debugging (I need to read my CSS and JS clearly).

Something like this:

[Debug Mode]

<script src="scripts/myscript.js"></script>

[Relase Mode or Public Mode]

<script src="dist/myscript.min.js"></script>

I have read this post on StackOverflow(Razor view engine, how to enter preprocessor(#if debug)) and I don't like the proposed solution because I think (not sure) that the loaded Razon View is going to check always in Production Server if it's in release or debug mode and I think that it's not necessary.

Can someone confirm if I am right? Will I will need make the changes manually? Any other solution?

Thanks!! Regards!!

Community
  • 1
  • 1
chemitaxis
  • 13,889
  • 17
  • 74
  • 125
  • Consider writing a static helper function that returns the script URL path, which reads from the web.config file (and is appropriately transformed by the build configuration) – Lunster Feb 08 '15 at 22:36
  • But I work with a a lot of files... about 20 JS and more than 10 css in debug mode... – chemitaxis Feb 08 '15 at 22:37
  • You might only need the helper return a string partial URL, so 'scripts/' in debug and 'dist/' in release. May not help in your specific situation, but I've seen similar things work. – Lunster Feb 08 '15 at 22:41
  • Thanks @IanL but it's not going to work for me ;) I have different folders... – chemitaxis Feb 08 '15 at 22:42
  • Any reason why you don't use Bundles and have MVC do all this out of the box? –  Feb 08 '15 at 22:54
  • Because I minify the files with Grunt... Can you show me how bundles can help me? Thanks – chemitaxis Feb 08 '15 at 22:56
  • And I'm using bower for take the JS and CSS too :) – chemitaxis Feb 08 '15 at 23:00
  • 2
    Best you read the [documentation](http://www.asp.net/mvc/overview/performance/bundling-and-minification). When using bundles, the non-minified versions will be used in debug mode. In release mode, if no corresponding -min- file exist, the files will be minified. If a -min- file does exist, it will be used. –  Feb 08 '15 at 23:03
  • Can I concat files with bundles? Thank you so much!! – chemitaxis Feb 08 '15 at 23:07
  • 1
    What do you mean by _concat files_? A bundle can include multiple files, for example `bundles.Add(new ScriptBundle("~/bundles/myScripts").Include("~/Scripts/myFirstScript.js", "~/Scripts/mySecondScript.js"));` In the view you use `@Scripts.Render("~/bundles/myScripts")` In debug mode those 2 files will be rendered. In release mode, they will be minified by the framework, but if the `Scripts` folder also includes `myFirstScript-min.js` and `mySecondScript-min.js`, then those minified files will used instead. –  Feb 08 '15 at 23:30
  • Ok, these files will be rendered.., but i will have one or two files? I need to have just one minified file to best performance request... (Last question ;)) – chemitaxis Feb 08 '15 at 23:53
  • If you mean you have 2 or more un-minified files and then you create 1 single minified file, then no, it wont work. But I suspect you wont get any better performance by doing that anyway. One of the many features of bundling is that all the files defined in a Bundle are combined into one file (in release mode) as explained in the documentation –  Feb 09 '15 at 01:09

2 Answers2

6

One way you could accomplish this is to just check for debug mode in the http context.

@if (HttpContext.Current.IsDebuggingEnabled)
{
    <script src="scripts/myscript.js"></script>
}
else
{
    <script src="dist/myscript.min.js"></script>
}
jamesSampica
  • 12,230
  • 3
  • 63
  • 85
0

UPDATED ANSWER

Thanks to Shoe I learned about the existence of environment tag helpers, so instead of my old answer where I achieved the same manually, we can now use it like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"]</title>
    <environment include="Development">
        <link rel="stylesheet" href="~/css/sasw.css" asp-append-version="true" />
    </environment>
    <environment exclude="Development">
        <!-- Google Analytics here for example -->
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>

OLD ANSWER A solution for Razor pages that should also work with Razor views (dotnet core 3.1+) could be to inject the IWebHostEnvironment and to render conditionally depending on the current environment (defined by the global variable ASPNETCORE_ENVIRONMENT) At your _Layout.cshtml

@using Microsoft.Extensions.Hosting
@inject Microsoft.AspNetCore.Hosting.IWebHostEnvironment Env
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"]</title>
    @if (Env.IsDevelopment())
    {
        <link rel="stylesheet" href="~/css/sasw.css" asp-append-version="true" />
    }
    else
    {
        <!-- Google Analytics here for example -->
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    }
</head>

This solution plays nicely with the bundle and minification policy defined at bundleconfig.json

In my case the bundleconfig.json looks like this:

[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/sasw.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "wwwroot/js/sasw.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    },
    "sourceMap": false
  }
]

and I have added a nuget called BuildBundlerMinifier that minifies & bundles automatically the js and css placing the minified version in the same folder as the original one.

PS: Remember to ignore (e.g: at .gitignore) *.min.js and *.min.css if you follow the same approach, to let the build process generate a new one each time without committing it to source control.

diegosasw
  • 13,734
  • 16
  • 95
  • 159