Rider EAP update: File watchers

One cool thing about Rider is that we can tap into the rich plugin ecosystem the IntelliJ platform brings. There are community plugins, and several JetBrains plugins as well. One of those was recently made available to work with Rider EAP: the File Watchers plugin, which executes tasks on file modifications.

But… why would we want this? One example could be “watching” TypeScript files for modifications and then transpile TypeScript to JavaScript automatically. Or watch CSS, LESS or JavaScript and bundle & minify them whenever we make a change. Let’s look at an example.

Sample project

As a sample project, let’s use a simple ASP.NET Core project (clone from here). In package.json, a development dependency on TypeScript was added so we can invoke the TypeScript transpiler.

What we want to achieve is that whenever we edit a .ts file, the TypeScript transpiler is invoked and our code is translated into proper JavaScript which we can use in our web application. File Watchers to the rescue!

Transpiling TypeScript using the File Watchers plugin

First things first… Installing the File Watchers plugin. From the settings, open Plugins and Install JetBrains plugin… In the list of plugins, find File Watchers and install it.

After a restart, we can now configure our TypeScript file watcher. Again from the settings, find Tools | File Watchers, and add a new file watcher. There are several things we have to configure. In broad strokes: which files do we want to watch? And which command do we want to execute?

Let’s start with configuring the files to watch. First of all, we have to configure the file type. Rider knows about TypeScript files, so we can select TypeScript from the list. If you’re using an unknown type, head over to the Editor | File types settings first.

We also have to configure the scope for our file watcher. Do we want Rider to check for changes in TypeScript files in all project files? Just in open files? Or in the entire solution and its subfolders? Or a custom scope? This last option is quite interesting: we could create a scope that is specific to just the wwwroot flder, for example. This would ensure that the file watcher only triggers when a file in the wwwroot folder is updated. Note the checkbox at the bottom which allows us to share this scope with team members.

Next up: the program to execute. We installed the TypeScript transpiler from NPM (via package.json), so the executable will be under node_modules\.bin\tsc.cmd (or node_modules/.bin/tsc). We can configure this as the program to execute.

As for arguments, we can specify the arguments we’d normally specify when invoking the TypeScript compiler. The file watcher also supports macro’s here (e.g. $FilePath$), which will be replaced by the TypeScript file path when the program is run. The arguments here will transpile somefile.ts into somefile.ts.js.

There are some other options as well, for example we can specify the output path we want to refresh, or display the console when there is an error in executing our program.

When we now save our file watcher configuration, the TypeScript transpiler will be triggered whenever we make a change to a TypeScript file under the wwwroot folder of our project.

Invoke a file watcher from a run/debug configuration

So far, our file watcher is only invoked when we are making changes. How can we make sure all of our TypeScript files are transpiled when we start debugging? Rider can run all configured file watchers when we run or debug our application. Edit the run/debug configuration (Run | Edit Configurations…) and add “Run File Watchers” as a before launch action:

If we now run our application, Rider will first make sure file watchers are executed, ensuring all of our TypeScript files are transpiled.

File watcher support in Rider is not yet where we want it to be. There’s still some configuration involved, and we’d like this all to become as smooth as possible. For example when working in a TypeScript file, Rider should be able to configure the TypeScript transpiler with the click of a button. Work in progress!