How do you share scripts among multiple projects in one solution?

asp.net Mvcasp.net Mvc-3

asp.net Mvc Problem Overview


In case the question wasn't clear. I have 3 MVC projects in one Solution. Every time I create a new project it adds the "Scripts" folder with all the .js files I'll ever need. I don't want to have this created every time for every application. Is there a way to reference scripts from a central folder in the solution so all applications/projects can share one common script folder with all the scripts common among them?

Edit: Please explain the pros and cons of doing this if there are any...now I'm curious.

asp.net Mvc Solutions


Solution 1 - asp.net Mvc

Here is what I would recommend:

Right click the solution and create a New Solution Folder called Common Javascript Files (or whatever you feel like calling it.

New Solution Folder

Common Javascript Files Solution Folder

Right click on the Solution, click Open Folder in Windows Explorer, or navigate there manually for other versions of Visual Studio :(

Open Folder In Windows Explorer

In the solution directory, create a directory with the same name as the solution folder (solution folders do not normally match directories at the source code level but this will for sanity sake).

Common Javascript Files Directory

In this new directory, add files that need to be shared between solutions.

Add Javascript Files To Directory

In Visual Studio, click the solution folder and select Add - Existing Item.

Visual Studio Add - Existing Itme

In the file selection dialog, navigate to the directory previous created, select the file(s) added to the directory and click Add.

Select Files To Add

Solution Folder Files

In each Project that needs a shared file, right click on the project (or directory within the project) and click Add - Existing Item.

Project Add Existing Item

Navigate to the shared Directory, Select the files and click the drop down arrow then click Add As Link.

Add As Link

Now the files in the projects are essentially short cuts to the files in the Solution Folder. But they are treated as actual files in the project (this includes .CS or Visual Basic files, they will be compiled as files that actually exist in the project).

Linked Files

PROS

  • Files are truly shared across projects at Design time
  • Only the files needed for each project can be added, it's not all or nothing
  • Does not require any configuration in IIS (virtual directory etc)
  • If the solution is in TFS Source control, you can add the Directory to the TFS Source and the shared files will be source controlled.
  • Editing a file by selecting it in the Project, will edit the actual file.
  • Deleting a Linked file does not delete the file.
  • This is not limited to JS files, linked files can be ANY file you might need (Images, Css, Xml, CS, CSHTML, etc)

CONS

  • Each deployment gets it's own file.

  • There is a small learning curve when understanding that Solution Folders are not Directories that exist in a Solution Directory.

Solution 2 - asp.net Mvc

The best thing to do, imo, is to roll your own CDN... Basically just create another site in IIS and give it it's own binding, e.g. "http://cdn.somedomain.com"

Then store all of your css/js/fonts/shared images etc on the CDN site and link to them from your other sites.

Doing so solves 2 problems,

  1. All of your stuff is shared when it needs to be and you only have to manage 1 revision per file.
  2. Your users browsers can cache them in 1 single location instead of downloading copies of your stuff for every site that uses them..

I added this answer because I see a lot of people referrencing creating virtual directories. While that does indeed share the files, it creates multiple download paths for them which is an extreme waste of bandwidth. Why make your users download jquery.js (1 * number of sites) when you can allow them to download it once on (cdn.somedomain.com).

Also when I say waste of bandwidth, I'm not just talking about server bandwidth, I'm talking about mobile users on data plans... As an example, I hit our companies HR site (insuance etc) on my phone the other day and it consumed 25mb right out the gate, downloaded jquery and a bunch of stuff 5 times each... On a 2gb a month data plan, websites that do that really annoy me.

Solution 3 - asp.net Mvc

Here it goes, IMO the best and easiest solution, I spent a week trying to find best and easiest way which always had more cons than pros:

Resources(DLL)
  Shared
    images
      image.png
    css
      shared.css
    scripts
      jquery.js


MvcApp1
  Images
  Content
  Shared <- We want to get files from above dll here
  ...

MvcApp2
  Images
  Content
  Shared <- We want to get files from above dll here
  ...

Add following to MvcApp1 -> Project -> MvcApp1 Properties -> Build events -> post build event:

start xcopy "$(SolutionDir)Resources\Shared\*" "$(SolutionDir)MvcApp1\Shared" /r /s /i /y

Here is explanation on what it does: https://stackoverflow.com/questions/16761730/including-build-action-content-files-directory-from-referenced-assembly-at-same/16762763#16762763

Do the same for MvcApp2. Now after every build fresh static files will be copied to your app and you can access files like "~/Shared/css/site.css"

If you want you can adjust the above command to copy scripts from .dll to scripts folder of every app, that way you could move some scripts to .dll without having to change any paths,here is example:

If you want to copy only scripts from Resources/Shared/scripts into MvcApp1/scripts after each build:

start xcopy "$(SolutionDir)Resources\Shared\Scripts\*" "$(SolutionDir)MvcApp1\Scripts" /r /s /i /y

Solution 4 - asp.net Mvc

This is a late answer but Microsoft has added a project type called Shared Project starting Visual Studio 2013 Update 2 that can do exactly what you wan't without having to link files.

> The shared project reference shows up under the References node in the > Solution Explorer, but the code and assets in the shared project are > treated as if they were files linked into the main project.

"In previous versions of Visual Studio, you could share source code between projects by Add -> Existing Item and then choosing to Link. But this was kind of clunky and each separate source file had to be selected individually. With the move to supporting multiple disparate platforms (iOS, Android, etc), they decided to make it easier to share source between projects by adding the concept of Shared Projects."

https://blogs.msdn.microsoft.com/somasegar/2014/04/02/visual-studio-2013-update-2-rc-windows-phone-8-1-tools-shared-projects-and-universal-windows-apps/

Info from this thread:

https://stackoverflow.com/questions/30634753/what-is-the-difference-between-a-shared-project-and-a-class-library-in-visual-st

https://stackoverflow.com/a/30638495/3850405

Solution 5 - asp.net Mvc

A suggestion that will allow you to debug your scripts without re-compiling the project:

  • Pick one "master" project (which you will use for debugging) and add the physical files to it
  • Use "Add As Link" feature as described in Eric's answer to add the script files to the other projects in solution
  • Use CopyLinkedContentFiles task on Build, as suggested in Mac's comment to copy the files over to the second over to your additional projects

This way you can modify the scripts in the "master" project without restarting the debugger, which to me makes the world of difference.

Solution 6 - asp.net Mvc

In IIS create a virtual folder pointing to the same scripts folder for each of the 3 applications. Then you'll only need to keep them in a single application. There are other alternatives, but it really depends on how your applications are structured.

Edit

A scarier idea is to use Areas. In a common area have a scripts directory with the scripts set to be compiled. Then serve them up yourself by getting them out of the dll. This might be a good idea if you foresee the common Area having more functionality later.

Solution 7 - asp.net Mvc

Most of the files that are included by default are also available via various CDN's.

If you're not adding your own custom scripts, you may not even need a scripts directory.

Microsoft's CDN for scripts: http://www.asp.net/ajaxlibrary/cdn.ashx

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEKetView Question on Stackoverflow
Solution 1 - asp.net MvcErik PhilipsView Answer on Stackoverflow
Solution 2 - asp.net MvcRyan MannView Answer on Stackoverflow
Solution 3 - asp.net MvcformatcView Answer on Stackoverflow
Solution 4 - asp.net MvcOgglasView Answer on Stackoverflow
Solution 5 - asp.net MvcDivineOpsView Answer on Stackoverflow
Solution 6 - asp.net MvcYuriy FaktorovichView Answer on Stackoverflow
Solution 7 - asp.net MvcjbrunkenView Answer on Stackoverflow