aspnet / MvcPrecompilation

[Archived] Tooling that allows compilation of MVC Razor views as part of build and publish. Project moved to https://github.com/aspnet/AspNetCore
Other
42 stars 15 forks source link

Improve support for precompilation of razor views in class libraries (embedded ui) #214

Closed evil-shrike closed 6 years ago

evil-shrike commented 7 years ago

As continue of https://github.com/aspnet/MvcPrecompilation/issues/187

The problem: I need a class library with embedded UI. Currently it's hard implement such setup when a class library in a solution contains pre-compilable razor views. Lloading views from embedded resource is another option and it works fine.

At the end of the mentioned discussion (#187) there was posted a link to blog post about how to implement embedded UI - https://dzone.com/articles/self-contained-ui-running-one-aspnet-core-mvc-site It seems to work well. But looks hacky, too much cleaver things should be done in csproj. Another problem it's not documented in official docs.

So this issue is an suggestion to have more simplified approach for "embedded UI", i.e. keeping razor views in class libraries and automatically compile and deploy them.

Some nuances which should be elaborated:

Currently (aspnetcore2.0) we have to do the following (thanks to @dasMulli for describing it in this comment - https://github.com/aspnet/MVCPrecompilation/issues/71#issuecomment-282494937)

1.

        <MvcRazorCompileOnPublish>true</MvcRazorCompileOnPublish>
  1. <Target Name="SetMvcRazorOutputPath">
        <PropertyGroup>
            <MvcRazorOutputPath>$(OutputPath)</MvcRazorOutputPath>
        </PropertyGroup>
    </Target>
    <Target Name="_MvcRazorPrecompileOnBuild" DependsOnTargets="SetMvcRazorOutputPath;MvcRazorPrecompile" AfterTargets="Build" Condition=" '$(IsCrossTargetingBuild)' != 'true' " />
    <Target Name="IncludePrecompiledViewsInPublishOutput" DependsOnTargets="_MvcRazorPrecompileOnBuild" BeforeTargets="PrepareForPublish" Condition=" '$(IsCrossTargetingBuild)' != 'true' ">
        <ItemGroup>
            <_PrecompiledViewsOutput Include="$(MvcRazorOutputPath)$(MSBuildProjectName).PrecompiledViews.dll" />
            <_PrecompiledViewsOutput Include="$(MvcRazorOutputPath)$(MSBuildProjectName).PrecompiledViews.pdb" />
            <ContentWithTargetPath Include="@(_PrecompiledViewsOutput->'%(FullPath)')" RelativePath="%(_PrecompiledViewsOutput.Identity)" TargetPath="%(_PrecompiledViewsOutput.Filename)%(_PrecompiledViewsOutput.Extension)" CopyToPublishDirectory="PreserveNewest" />
        </ItemGroup>
    </Target>

Off the top of my head I'd suggest to introduce MvcRazorCompile=true.

CGollhardt commented 6 years ago

I would propose, we have a PrecompileRazorViewsAndMerge property group element, which automaticly precompiles the Views on every Compilation and merge them with the output class library.

Not sure, how hard this would be to implement, but this would be very easy to use and document.

nfplee commented 6 years ago

I agree the class library shouldn't need to be "runnable". A simple class library like Orchard Core modules looks a lot cleaner.

I also think there should be a way to specify a view prefix e.g. "~/Areas/Blog". This way we can just have a Views directory within the root of the library.

IEvangelist commented 6 years ago

I agree with this and would like to further propose that the precompiled views be part of the build step. Currently they are only available from either the Visual Studio (MSBuild) publish command or the dotnet publish command. This is kind of a fundamental misuse of the publish command.

If I take a step back and imagine that I have zero experience or knowledge with how these commands would work I might describe them as follows:

It is my belief that by making the publish step responsible for compilation -- we are making things more complicated for DevOps and less flexible. I'm working on a fortune 500 company / enterprise project right now that has a need to have a web appliciation (that produces an .exe) be packed up and we need its *.PrecompiledViews.dll as well in the NuGet package.

The steps to make this happen in Team City are starting to look like insanity. Something like this right now:

  1. build
  2. publish to local folder
  3. copy *.PrecompiledViews.dll
  4. pack --no-build
  5. publish package to artifactory

I'd much rather go:

  1. build
  2. pack
  3. publish package to artifcatory
manigandham commented 6 years ago

@IEvangelist Agree strongly with this, that should be the default or with an easy flag to enable. Compilation is part of build, whether it's code or views. We've run into plenty of issues where devs check in code that builds but ends up with errors during publish.

mkArtakMSFT commented 6 years ago

This issue was moved to aspnet/Razor#1809