No transpilation on IIS production server - reactjs.net

First off, a lot of this technology is new to me, so I apologize for the noob question. Also, this is my first post to SO (after years of reading), so forgive the formatting.
I have a web application that I am running via MSVS 2017. I am writing my front end with React.js. After installing the appropriate packages via nuget, I have something that works when I run both the debug and release versions on my local dev machine (using iisexpress).
However, after I commit my source changes, and it gets pushed to the test server (IIS), the app runs fine. But, the JSX files that are returned from the test server are not transpiled. I just get the raw JSX file. Whereas, on my local machine, the returned file is transpiled.
I have a ReactConfig.cs file with a single static Configure method, where I have a call to add my JSX file via ReactSiteConfiguration.Configuration.AddScript, but that appears to be unnecessary because I still get a transpiled result even when it is commented out. At the top of my ReactConfig.cs file I have seomthing similar to:
[assembly: webActivatorEx.PreApplicationStartMethod(typeof(MyApp.Api.Controllers.MyController), "AutoMapperStart")]
So, then I am left with the question of how is the transpiling occuring on my dev machine, but not the deployment machine.
In my web.config file, I have tried both:
<httpHandlers>
<add verb="GET" path="*.jsx" type="React.Web.BabelHandlerFactory, React.Web" />
</httpHandlers>
and
<remove name="Babel" /><add name="Babel" verb="GET" path="*.jsx" type="React.Web.BabelHandlerFactory, React.Web" preCondition="integratedMode" /></handlers>
But neither seems to make a difference on the deployed server.
If anyone has suggestions of what I should look at next, it would be greatly appreciated.
Update:
I notice the relevant item that is allowing my dev environment to do the transpilation is the second code section above in my web.config file. However, that I don't see the same lines on the server. Are web.config file typically 'hand edited' per deployment, perhaps?

So, here is what I eventually figured out that worked for me.
First, yes, the web.config file is deployed with as a template. And then hand configured as necessary.
Second, and more importantly, there are two parts to getting the server to render JSX to pure JS.
I needed the following in the web.config file:
<system.webServer>
<handlers>
<remove name="Babel" />
<add name="Babel" verb="GET" path="*.jsx"
type="React.Web.BabelHandlerFactory, React.Web"
preCondition="integratedMode"/>
</handlers>
</system.webServer>
And finally, in the assemblyBinding section:
<dependentAssembly>
<assemblyIdentity name="JavaScriptEngineSwitcher.Core" publicKeyToken="c608b2a8cc9e4472" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.9.0" newVersion="2.4.9.0" />
</dependentAssembly>

Related

Could not load file or assembly 'Microsoft.AspNet.Web.Optimization.WebForms' or one of its dependencies. The system cannot find the file specified

I can't find anything to resolve this and have tried multiple things.
Task: I am trying to add bundles to an old existing web project. I have added everything I need I believe as I have done the same in a new project and it works.
<webopt:BundleReference runat="server" Path="~/bundles/masterstyle" />
This seems to be where the issue has started with this line above. I installed via nuget the web optimization webforms package which fixed the squiggly line under webopt. However, now, I am getting 2 issues.
BundleReference has a squiggly line saying "Element
'BundleReference' is not a known element/ This can occur if there is
a complication error in the Web site, or the web.config file is
missing".
It also can't seem to find the package I have just installed which
is "Could not load file or assembly
'Microsoft.AspNet.Web.Optimization.WebForms' or one of its
dependencies. The system cannot find the file specified".
If anyone can help resolve this, it would be greatly appreciated. Been stuck on it for 4 hours now.
Here is the likely relevant stuff in my web.config file:
<pages>
<namespaces>
<add namespace="System.Web.Optimization"/>
</namespaces>
<tagMapping>
<add tagType="System.Web.UI.HtmlControls.HtmlForm" mappedTagType="we3.Site.Form" />
</tagMapping>
<controls>
<add assembly="Microsoft.AspNet.Web.Optimization.WebForms" namespace="Microsoft.AspNet.Web.Optimization.WebForms" tagPrefix="webopt"/>
</controls>
</pages>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.0" />
Install it from nugget: https://www.nuget.org/packages/Microsoft.AspNet.Web.Optimization.WebForms/
Install-Package Microsoft.AspNet.Web.Optimization.WebForms
Or you can manually download it from: https://www.nuget.org/api/v2/package/Microsoft.AspNet.Web.Optimization.WebForms/1.1.3
and add it as reference to your project (unzip first the .nupkg file)
Installing the package Microsoft.AspNet.Web.Optimization is what resolved this for me.
Install-Package Microsoft.AspNet.Web.Optimization

Dotless HttpHandler with VS2013 Preview

I have just installed the Visual Studio 2013 preview and run up my site. I've noticed that the less files which are used in my site are not being correctly transformed to css and are coming down as blank CSS files.
It appears something is going wrong inside the dotless httphandler as when I force minification for the bundle everything works correctly.
web.config
<section name="dotless" type="dotless.Core.configuration.DotlessConfigurationSectionHandler, dotless.Core" />
...
<httpHandlers>
<add path="*.less" verb="GET" type="dotless.Core.LessCssHttpHandler, dotless.Core" />
</httpHandlers>
...
<handlers>
<add name="dotless" path="*.less" verb="GET" type="dotless.Core.LessCssHttpHandler,dotless.Core" resourceType="File" preCondition="" />
</handlers>
The issue appears to go away if I force minification eg. System.Web.Optimization.BundleTable.EnableOptimizations = false; which suggests something is different in the way it processes the HTTP handler
Try putting handleWebCompression="false" in the configuration for dotless (in the web config)
<dotless minifyCss="false" cache="true" web="false" handleWebCompression="false" />

Why is msbuild duplicating entries in web.config transformations?

I am using web.config transformations to insert entries into the web.config for certain build configurations.
E.g. my Web.Test.config has this entry:
<elmah>
<errorMail from="me#me.com" to="me#me.com" async="false" smtpPort="25" smtpServer="mail" subject="test.senegal.co.uk Exception" xdt:Transform="Insert" />
</elmah>
This works absolutely fine building from visual studio.
However when creating a deployment package using msbuild, the entry is duplicated in the web.config. This obviously causes an exception.
Any ideas?
UPDATE
My "master" config is Web.Master.config not Web.config. The web.config file gets overwritten on build in visual studio. I think it must have something to do with this.
What I think is happening is msbuild is transforming web.config rather than using the Web.Master.config.
The question is how to tell it to use the right master.
I added /p:TransformWebConfigEnabled=false to the msbuild parameters, as my web.config was already being transformed in a BeforeBuild target like so:
<Target Name="BeforeBuild">
<TransformXml Source="$(MSBuildProjectDirectory)\Web.Master.config" Transform="$(MSBuildProjectDirectory)\Web.$(Configuration).config" Destination="$(MSBuildProjectDirectory)\Web.config" />
</Target>
In my case duplication was caused by xdt:Transform="Insert". If remove it from Web..config and leave the rest it will work properly, e.g.:
<!-- doesn't work -->
<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="My"
xdt:Transform="Insert" />
vs.
<!-- works -->
<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="My"
/>

Sub-folder web.config namespaces remove broken in 4.0?

Similar to this question
I am porting a web application to 4.0. It has a root web.config that adds a namespace:
<namespaces>
<add namespace="Insignia.Catalog2"/>
...
</namespaces>
There is a sub-folder to this app with its own web.config:
<namespaces>
<remove namespace="Insignia.Catalog2"/>
<add namespace="Insignia.Catalog"/>
</namespaces>
.Catalog and .Catalog2 have overlapping class names. This worked great in ASP.NET 2.0 thru 3.5 but seems broken in 4.0 - that is, I now get compiler errors about the colliding class names.
Well I figured it out. While the 'remove' tag WAS removing .Catalog2, another DLL had changed to include a reference to that namespace. Using a control from that other DLL brought .Catalog2 along with it! Fixing the reference solved the problem.

NServiceBus persisting subscriptions in Pub/Sub sample

I want to figure out how I to set up the Pub/Sub sample from NServiceBus to work in the case of publisher malfunction.
When I start the samples and accidentaly close the Subscribers, if I restart everything works fine.
If however I kill the publisher and the subscriptions continue to work, if I restart the publisher, then it doesn't seem to know it has subscribers and doesn't post any messages.
I added the config entry
<MsmqSubscriptionStorageConfig Queue="subscriptions"/>
but it seems to not function... I miss something. I googled about MsmqSubscriptionStorageConfig and DbSubscriptionStorageConfig but i didn't find a solution.
Could someone point me in the right direction ?
I found that a couple additional steps are required in order to get this working with the Pub/Sub sample under .Net 4.0, using a SQLite subscription storage system.
Combining the previous suggestions with the new ones, here are the required changes, all of which apply to the MyPublisher project.
Add a reference to System.Data.SQLite. Be sure to choose the version that matches your desired architecture (x86/x64). These items can be found in the 'binaries' folder.
In the App.config file, add the following as a new configSection element:
<section name="DBSubscriptionStorageConfig"
type="NServiceBus.Config.DBSubscriptionStorageConfig, NServiceBus.Core" />
In the App.config file add, the following as a new configuration element:
<DBSubscriptionStorageConfig>
<NHibernateProperties>
<add Key="connection.provider"
Value="NHibernate.Connection.DriverConnectionProvider"/>
<add Key="connection.driver_class"
Value="NHibernate.Driver.SQLite20Driver"/>
<add Key="connection.connection_string"
Value="Data Source=.\Subscriptions.sqlite;Version=3;New=True;"/>
<add Key="dialect"
Value="NHibernate.Dialect.SQLiteDialect"/>
</NHibernateProperties>
</DBSubscriptionStorageConfig>
Add this chunk of XML to the configuration section of the NServiceBus.Host.exe.config file:
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0"/>
</startup>
You need to change the profile of the publisher to production.
See http://docs.particular.net/nservicebus/hosting/nservicebus-host/profiles
For debugging this way, go to the properties of the publisher project, into the Debug tab, and put in NServiceBus.Production in the Command line arguments of the Start Options section.