273
Vote

Allow package resource folders to be configurable

description

I <3 Nuget. But one thing I don't like is that it forces things like JavaScripts to be in one location. I keep my website organized a specific way, and I don't want my scripts in that folder. So it would be nice if certain folders could be configurable to drop items in an alternate location.

file attachments

comments

JeffHandley wrote Feb 8, 2012 at 8:32 PM

Interesting idea for sure.

JeffHandley wrote Mar 16, 2012 at 6:38 PM

An idea:

One could create a MyPackageName.config within the .nuget folder, specifying a mapping of where files should be installed. During package installation, we'd respect the mappings in place.

Going further, we could have UI around defining the mappings by folder or file.

balexandre77 wrote Oct 14, 2012 at 8:57 PM

This will be lovely as when using multiple libraries e tend to create folders for each library, an example is attached to this comment

ParaSwarm wrote Nov 11, 2012 at 2:29 AM

I would love to include stuff like jQuery via NuGet if I could control the script location.

bhuvak wrote Dec 1, 2012 at 12:15 AM

Amateur wrote Dec 3, 2012 at 8:10 PM

Any updates as to when or if this may be investigated in to? I think its something that needs to be looked, as projects loose structure when JavaScript files for example are added to folders which may go against the natural structure of the project.

bartmax wrote Jan 4, 2013 at 1:29 PM

PLEASE!

I guess something will be great to MAP into the 'client|user-side' so existing packages will still work (not sure how they are created) but imagine that you can do a mapping like:

~/Scripts => ~/Content/Scripts

then when installing files you can 'parse the output directory and if it's ~/Scripts* change to ~/Content/Scripts*

JeffHandley wrote Jan 23, 2013 at 8:35 PM

Triage: moved into 2.3 due to high vote count.
This is not a guarantee that it will be completed in 2.3 though.

bhuvak wrote Feb 2, 2013 at 12:39 AM

dotnetjunky wrote Feb 4, 2013 at 4:32 PM

We won't be able to do this in 2.3. Move to 2.4

roblang wrote Mar 13, 2013 at 3:53 PM

Now in March 2013 and this feature is becoming more pressing. Would love to add to create a series of resource destinations per project in a nuget.config file.

dotnetjunky wrote Apr 11, 2013 at 5:16 PM

koistya wrote May 22, 2013 at 11:53 PM

How about this:

Image

We don't even need an interface for this for the first time.

koistya wrote Jun 16, 2013 at 4:12 PM

Having mapping info inside packages.config as opposed to nuget.config would allow installing packages from different vendors exactly as you need them. Different package vendors may have different folder structures. For example one package installs scrips to /Scripts root folder another package installs scripts into /Scripts/{Vendor} folder making your overall project structure inconsistent.

Instead vendors could just be forced to use /Scripts, /Styles, /Images or /Content folders for their assets and consumers would map these folders to their real-world project structures.

dotcom wrote Aug 15, 2013 at 8:42 AM

+1 for the idea from koistya, above.

bartmax wrote Aug 15, 2013 at 3:41 PM

I think the best would be to have unopinionated folder structure.
Something like I define that packages install on /Modules folder.
Then, each package install all the necessary items in /Modules/{package}/ and from there anything the package owner decides.
Example por jquery:

/Modules/jQuery/scripts
/Modules/jQuery/styles
/Modules/jQuery/styles/themes
/Modules/jQuery/images/

for bootstrap:

/Modules/Bootstrap/Less/{version}/
/Modules/Bootstrap/Scripts/
/Modules/Bootstrap/Styles/
/Modules/Glyphicons/Styles/
/Modules/Glyphicons/Fonts/

for knockout could be:

/Modules/knockoutjs/

It all depends on package owner, and still the structure is easy to manage, update, delete, etc.
In this scenario, package owner can include any files into it's package folder without messing the project at all.

Also, it would be great if user can change 'package name' installation, so I can install SomeNamePackage into /Modules/MyNamePackage for that package.

to continue with the example above, I may configure jQuery to install in /Module/TheAwesomejQueryFramework/ being this completely optional.

Packages that requires some files to be placed on a specific folder like glimpse.axd should be able to do so.

I think this gives the best of both worlds, package owners and users have freedom to structure their folders as they wish.

You won't be able to have /Scripts/jquery.js and /Content/Styles/jquery.css but there's not real benefit / use to have jQuery.js in one folder and jQuery.css on another.

The idea is not mine, BOWER (http://bower.io/) is currently doing this and I think it makes lot more sense to me.

koistya wrote Aug 27, 2013 at 10:39 PM

Also, keep in mind that there could be much more file types than simply .css, .less, .js ... We need some generic solution to configure where exactly content files are going to be installed / restored.

Image

koistya wrote Aug 31, 2013 at 9:19 AM

/Scripts/knockout.js > /Scripts/knockout.min.js
/Scripts/knockout.debug.js > /Scripts/knockout.js

koistya wrote Aug 31, 2013 at 10:31 AM

Also having an ability to skip some files during a restore would be beneficial. Consider a scenario where you want to install Bootstrap 3 library, but you don't need any of its .js files because you're using AngularJS..
/Scripts/bootstrap/*.js > null

enorl76 wrote Sep 16, 2013 at 2:26 PM

Upvoted. My organizations' standard is ~/Assets/js.

A redirect for, for instance the jQuery nuget package, would be grand.

I would recommend redirect nodes WITHIN the package reference nodes:

<package [...]>
<redirect source="/Scripts/*" target="/Assets/js/" />
<redirect source="/images/*" target="/Assets/images/" />
</package>

The problem could be introduced though that Nuget would now be responsible for "rewriting" the internal paths of JS librarys/CSS/etc... UG!

koistya wrote Nov 2, 2013 at 4:21 PM

Having an ability to redirect individual files is essential, as well as to ignore some files.
<package id="Twitter.Bootstrap.Less" version="3.0.1" targetFramework="net45">
  ...
  <redirect source="/Content/bootstrap/type.less" target="/Styles/core.type.less" />
  <redirect source="/Content/bootstrap/grid.less" target="/Styles/core.grid.less" />
  ...
  <redirect source="/Content/fonts/*.*" target="/Fonts/" />
  ...
  <ignore source="/Scripts/*.js" />
</package>

spiderM9 wrote Nov 8, 2013 at 9:22 PM

Please do not implement this to be at the solution file level. It is too presumptuous to presume that solution files are even being used to build applications.

I like the <redirect...> above, assuming that it can be placed in a file that is discovered the same way that the NuGet.config file is discovered, by walking up the source tree until a file with a particular name or file extension is discovered. If I have 600 project files and need to hand curate the packages.config file for each one of them, well, forget it.

andresraieste wrote Dec 4, 2013 at 5:37 PM

I wouldn't make this overly complex. I really like Bower's solution, as it's unopinionated as also stated earlier here. It's a tried and praised solution which yes does have it's quirks, but it works best.

Therefore, I would add an optional attribute to <packages> tag in packages.config, something like this:
<?xml version="1.0" encoding="utf-8"?>
<packages defaultassetdir="Assets/Vendor">
  <package id="bootstrap" version="3.0.0" targetFramework="net451" />
</packages>
In which case there is a possibility to install components to a custom directory, e.g. Assets/Vendor like in the example above.

Per file configuration (overrides) on the other hand is yes more flexible, but on the other hand I think package management should be only about package management and not about introducing another layer of difficulty to the project. It could be misused a lot and might (or rather will) easily break in package upgrade scenarios, for example.

And as the talk started about having a choice about "Contents" and "Scripts" folder, I'd say that all sane developers anyway use minification and bundling, therefore the package target attribute solution works very well for that reason.

andresraieste wrote Dec 4, 2013 at 5:58 PM

Oh, never mind, just understood that optional attribute to <packages> tag wouldn't work at all for any other package than JS/CSS packages.

fejesjoco wrote Feb 20 at 12:56 PM

My colleagues and I don't really like that Nuget copies physical files (instead of references) into our projects at all. Storing them virtually code solve this problem as well. See https://nuget.codeplex.com/workitem/3903

enorl76 wrote Feb 20 at 1:54 PM

@fejesjoco: Your desire (for references instead of physical files) is technically out-of-scope for this particular request. You could keep your request more aligned with this one by adding the request for a better naming scheme, and then that parlays into you having a better naming scheme that should then override the package producer's naming scheme.

phil_ke wrote Mar 19 at 8:46 AM

How come this simple fix is not in place yet? It just completely destroys the folder structure of existing projects.

koistya wrote Mar 19 at 9:35 AM

As a workaround you can have client-side NuGet packages installed on a solution level (as opposed to a web application project) and have your build script copy required libraries to website's output folder. If you're working on a non-trivial web app, most likely you already have a client-side build system in place, also this way your source control system will be free of any 3rd party libraries. If you're new to client-side build systems, take a look at http://gulpjs.com and Gulp.js NuGet package.

Haggis777 wrote Apr 2 at 8:50 PM

This feature is the only reason I haven't embraced nuget for my web projects. I can't stand having everything dumped into one directory. Its just sloppy.

jvanderstad wrote Today at 12:38 AM

@Haggis777.. I agree..

I just want a very clean folder structure. No random subdirs..
But I just love the update function..

so... big upvote!