1

I'm working on a website and I use ASP.NET 5 CLR (rc1-final x64). I want to have my wwwroot folder 'clean'. I feel everything that should exist in wwwroot should be added on build or through tasks (for example through Grunt). I'm using Grunt for this, and this works fine with JavaScript and CSS files.

Now I'm at that point of adding images to my website. Right now my .gitignore says to exclude the wwwroot. I don't know how to move images from outside the wwwroot to inside it. Is there any good way to move files to the wwwroot? I really want my wwwroot 'clean' without any libraries. I have those outside of the wwwroot, so I don't accidentally serve unwanted files.

I want to move them from: [Application Root]/static/img to wwwroot/img.

Currently I have the following grunt tasks:

  • grunt-contrib-concat
  • grunt-contrib-cssmin
  • grunt-contrib-uglify

I think this may be very in-efficient because on build we need to move all the files every time.

Is there any way to do this better / more efficiently?

EDIT #1: Yeah, so I read the documentation: http://docs.asp.net/en/latest/fundamentals/static-files.html. I could actually just pass in a parameter to the app.UseStaticFiles() method like this:

app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(@"D:\Source\WebApplication1\src\WebApplication1\MyStaticFiles"),
        RequestPath = new PathString("/StaticFiles")
    });

Here the PhysicalFileProvider contains the absolute path. Is it possible to use a relative path here?

EDIT #2: Actually this works:

public void Configure(IApplicationBuilder app, IHostingEnvironment environment, ILoggerFactory loggerFactory, IApplicationEnvironment appEnvironment)
{
    app.UseIISPlatformHandler();
    app.UseDeveloperExceptionPage();

    app.UseMvcWithDefaultRoute()
        .UseStaticFiles()
        .UseStaticFiles(new StaticFileOptions
        {
            FileProvider = new PhysicalFileProvider(string.Concat(appEnvironment.ApplicationBasePath,"/static/images")),
            RequestPath = new PathString("/img")
        });
}

Here we add the UseStaticFiles middleware twice to serve the default, which is wwwroot. We will also serve files from within the solution where the images are.

However, I don't know if there would be any performance or security problems or other problems by adding this middleware twice. You need to be careful in what you add in this folder. Directory Browsing should atleast not be enabled.

7
  • Just curious, why is wwwroot not source-controlled and why don't you put the images in your wwwroot? Are these images, static or dynamic (like product images, etc..)?
    – Dealdiane
    Commented Dec 21, 2015 at 7:19
  • That's because I have my combined and minified files (CSS and JavaScript) inside the wwwroot. I keep all my source files outside of the wwwroot. And yes, these images are static. Commented Dec 21, 2015 at 8:16
  • We have the same scenario as you. We have our combined and ugly stylesheets and scripts in our wwwroot but we never commit the minified and concatenated scripts. There's a restriction in-place so that devs don't accidentally commit them. The scripts are minified and concatenated on the build server. Same goes with optimizing the images. This is "clean" enough for us. I'm not saying this is the recommended approach. All I'm saying is that sometimes we tend to overcomplicate things when simple solutions exist.
    – Dealdiane
    Commented Dec 21, 2015 at 20:16
  • OK. What's the restriction? Is it in the SCM? Where are your static images? Also, I added a possible solution in my edit (2) in the question. Commented Dec 21, 2015 at 20:34
  • The restriction is in the source-control and through server side hooks in git or svn. Static images are in wwwroot
    – Dealdiane
    Commented Dec 22, 2015 at 1:08

1 Answer 1

2

Are you sure you want to keep wwwroot "clean"?

You cannot easily reference static content outside of wwwroot so doesn't it make more sense to keep the static files below wwwroot and just segregate them into sub folders for dev vs production and then just use publishexclude in project.json to leave out the dev stuff.

Myself, I only want to run grunt tasks prior to publishing to produce the production set of files, then I want to leave the dev versions of the files out of publishing. I do not want to run grunt just to move files so I can use them during development and I don't want to run grunt every time I edit the dev/src versions of my js files.

The problem of that approach becomes more obvious if you pull in something like ckeditor which is a huge number of files that I don't want to copy or move around the file system much, at most I would move them once pre-publish to clean out any extra files as I move it to a production folder.

Back in MVC 5 there was no concept of separating the static files from the code, the web app just served files out of the same root app directory that also had server side code. At that time having static files in a /Content folder or js in other folders made sense. But trying to keep static assets outside of wwwroot in MVC6/aspnet5 seems to me to be working against the grain of the wood.

By keeping all static assets including the dev versions of them below wwwroot I have an easy workflow where I can just edit a js file and refresh the page as discussed in this question. This feels like I'm working with the framework and not against it.

7
  • I totally see your point. Now I also see why they chose to move bower and node modules from outside to inside the wwwroot. Every time I want to change something in my CSS or JavaScript files, I need to run grunt. This is actually something I don't want to do. I want to run them when publishing, as you're saying. I guess when it comes to Source Control, we will need to exclude some folders from the wwwroot, like: node_modules, generated files, bower_components etc. I'm currently using Git, and I guess I would just add these folders to my .gitignore? How do you handle these kind of problems? Commented Dec 26, 2015 at 8:27
  • yes, exactly, in my projects I'm using gitignore to exclude the dev stuff that comes from npm/bower. I put my custom dev js stuff in another folder that I do want to go into the repo. I also exclude my production js folder from gitignore since that is where things get processed to. and I use publishexclude from project.json to make sure only the production stuff is published. so all of it goes below wwwroot but orgnized into sub folders. Commented Dec 26, 2015 at 16:47
  • Are you still using this method or have you found a better alternative? It sounds like you have wwwroot\dev\node_modules and reference the static content directly so you don't need to copy every time? So when you publish the folder structure changes and you may need to update any references? Or do you maintain the same folder structure and, for example, exclude all of node_modules except the specific files/folders you need? Commented Apr 10, 2017 at 1:07
  • in vs project templates .bowerrc file points to wwwroot/lib like an alias for bower_components, so I exclude that from git and from publish output, but use direct links to that stuff during dev and process it into wwwroot/js for production. I'm not currently using node_modules, but if I were I would do it the same way, it would be wwwroot/node_modules and I would exclude that from git and from publish and process just what I need from there into wwwroot/js. not saying that is the only good approach but it makes sense to me Commented Apr 10, 2017 at 13:18
  • 1
    @NelsonRothermel just tried the spa samples they keep node_modules outside of wwwroot, and all source code out of there and only process files into there with webpack. They have a ClientApp folder also outside of wwwroot where source code/typescript goes. so maybe a different approach is better for spa, but my old approach seems ok for mvc, not really right or wrong just depends on how much client side code there is and personal preferences Commented Apr 10, 2017 at 14:04

Not the answer you're looking for? Browse other questions tagged or ask your own question.