I’m sure I’m overlooking something obvious, but I have a Razor Class Library where I’m compiling my MVC views, and also writing my client-side stuff in Typescript compiled down to a single Javascript file. I have a web project that consumes the RCL. When I change a .cshtml view in the RCL, the web project dutifully acknowledges the change and refreshes the browser. However, when I change a .ts file, which triggers the Typescript compiler and outputs a .js file, it does not refresh the browser in the dependent web project.
Now, I might be over-complicating it. My RCL project looks like this:
/Client
--/src
----tsconfig.json
----tsfiles.ts
--/dist/outputfile.js
/wwwroot
--/dist/outputfile.js
I have a gulpfile that copies from /Client/dist
to /wwwroot/dist
. My tsconfig.json
looks like this:
{
"compileOnSave": true,
"compilerOptions": {
"target": "es6",
"sourceMap": true,
"outFile": "../dist/Client.js",
"experimentalDecorators": true,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
}
}
I’m stuck because I don’t understand the underlying magic. Changing any .cshtml
file in the RCL will trigger a hot reload in the browser viewing the web project that references the RCL. Nothing happens at all when I update a .ts
file, and obviously the gulp file doesn’t fire either. I have to rebuild the web project to get the latest junk.
The outcome that I would like is that saving a .ts
file in the RCL would trigger the same hot reload in the browser as a change in a .cshtml
file. My RCL has the following in the .csproj
.
<TypescriptOutDir>wwwroot</TypescriptOutDir>
<StaticWebAssetBasePath Condition="$(StaticWebAssetBasePath) == ''">/</StaticWebAssetBasePath>
<ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
CompileTypeScript;
$(ResolveCurrentProjectStaticWebAssetsInputs)
</ResolveCurrentProjectStaticWebAssetsInputsDependsOn>
To be clear, when I manually rebuild the web project, the files in the wwwroot
of the RCL are visible as expected in the web app that references the RCL project. They’re in the right place to be used, it’s just the hot reload isn’t happening. It makes the separate project reference really hard to work with.
EDIT: Interesting thing, I added a throw-away code line in a .cshtml file, and if I save, it triggers the update. If I have a gulp file alter the file and save, it does not trigger the update. So it seems the plumbing is in VS 2022 itself. Changing CSS files won’t trigger it either, though in both cases it does if it’s in the running project instead of the dependent RCL.
2
Answers
As it turns out, I was already close to a solution. The key is to make sure that the
tsconfig
compiles on save, and outputs to thewwwroot
folder. I can't confirm it, but I saw a post in transit that said you need an<AssignTargetPathsDependsOn>CompileTypeScript;$(AssignTargetPathsDependsOn)</AssignTargetPathsDependsOn>
in your project file.Regardless, I was editing Typescript files in an RCL and got reload of the consuming web project was working.
Visual studio would by default trigger the hotreload if your JS files are in the wwwroot folder (no special action needed).
So you can do one of the following:
Change the tsconfig.json outFile from
"outFile": "../dist/Client.js"
to"outFile": "../../wwwroot/dist/Client.js"
. No gulp task is needed.Or you can have a watch task in gulp that watches Client/dist/Client.js and copies it to wwwroot/dist/Client.js
See this article about how to make gulp watch file changes:
https://gulpjs.com/docs/en/getting-started/watching-files/