如何在一个解决方案中的多个项目之间共享脚本?

以防问题不清楚。我有3个 MVC 项目在一个解决方案。每次我创建一个新项目时,它都会添加“ Scripts”文件夹。我需要的 JS 文件。我不希望每次都为每个应用程序创建这个。是否有办法从解决方案中的中心文件夹引用脚本,以便所有应用程序/项目可以共享一个公共脚本文件夹和它们之间的所有公共脚本?

编辑: 请解释这样做的利弊,如果有任何... 现在我很好奇。

41767 次浏览

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.

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

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.

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: Including Build action content files directory from referenced assembly at same level as bin directory

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

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.

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.

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:

What is the difference between a Shared Project and a Class Library in Visual Studio 2015?

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