Using npm packages with Blazor
Blazor is an amazing Web UI Framework since you can now use C# on front end web applications. However, there are times when you still need to use modern JS libraries especially ones provided via npm
So how do you use JS modules provided via npm
?
Prerequisites:
- .NET Core 3.0 is installed
- NodeJS is installed
Let’s build a Blazor application from scratch:
$ dotnet new blazorserverside --auth Individual
This will create a new Blazor application.
Let’s try to run this:
$ dotnet run
It’s working as expected.
For the npm
module that we are going to use, we’ll use moment
which is a simple module for handling time in JS.
Let’s create a folder named JsLib
in our Blazor application:
We’ll now initialize a new npm
project inside the JsLib
folder:
$ cd JsLib
$ npm init
Just leave an empty response to the questions. We’re not gonna focus on them.
Create a new directory src
inside the JsLib
folder and create a new file named index.js
:
The index.js
will serve as the “root” for exposing the libraries that we are gonna be using.
We’ll now add moment
via npm. Execute this in the JsLib
directory:
$ npm install moment
The package.json
should now contain the following:
Next, we’ll create a new file called time_lib.js
in the src
folder:
Add the following code:
We’ll now call it in the index.js
and expose a function that the Blazor
app can call:
In the above example, the JsInterop
for Blazor
will be calling the GetCurrentTime()
function.
We’ll now use webpack
to bundle our library and put the output inside the wwwroot/js
in out Blazor
application.
Go to the JsLib
folder and run this command:
$ npm install webpack webpack-cli
This will add the dependencies to webpack
and webpack-cli
which we’ll be using to bundle our library. The dependencies folder should now include webpack
and webpack-cli
:
Now we’ll create the webpack.config.js
inside the JsLib
folder which will handle the configurations for webpack
:
Add the following contents inside the webpack.config.js
:
The configuration above will tell webpack
to do the following:
- Use babel-loader since we are using ES6 syntax.
- Name the bundled library
my_lib.js
and set the root library that will be attached towindow
(for client-side) and name it asMyLib
. More on to this later on. - Place the bundled library to
wwwroot/js
.
Now we’ll update the package.json
to add a build
that will call webpack
.
Add this to the “scripts” section in the package.json
:
"build": "webpack --mode production"
The package.json
will now look like this:
Since we used ES6
syntax, we need to add babel
dependencies. Run this command on the JsLib
folder:
$ npm install babel-loader @babel/core --save-dev
This will add the needed babel
dependencies for webpack
to properly bundle our library. The resulting package.json
will now be:
Let’s now build our library using this command:
$ npm run build
This will build the library and output our bundle to the wwwroot/js
folder:
As you can see, our my_lib.js
is now in the wwwroot/js
folder of our Blazor application.
Let’s now use our library on our Blazor
application :)
We’ll start with adding our library to the JS files used by our Blazor
application. In _Host.cshtml
, add the following line:
<script src="js/my_lib.js"></script>
The body of _Host.cshtml
should look something like this:
Let’s run our Blazor
application first and see that our library is actually there. After running, open the browser (mine is Chrome) and see that the window
actually has our library:
The reason why window
actually got MyLib
is because of library
property in the output
of webpack.config.js
.
Since this is now part of the window
, we can now call it in our Blazor
application :)
Create a new page in the Pages
directory and name it as Time.razor
:
Time.razor
will contain the following code:
The code above uses Blazor’s JsInterop
and invokes the MyLib.GetCurrentTime
from our library.
Run your Blazor application and navigate to /time
:
Press the button and you’ll get the result from the library that we have created :)
As you can see, we can now use npm
modules and expose them as libraries to our Blazor
application :)
Bonus:
Integrating our npm run build
to our dotnet build
:)
Modify your .csproj
file to something similar to the one below:
The idea from that one was copied from the react-redux
template. The short summary is that npm
calls are integrated to dotnet’s build command.
On publish, the library is copied over to the wwwroot/js
folder so no need to configure anything for releases.
Here’s a sample dist
folder after running dotnet publish -o dist
:
As you can see, the my_lib.js
is first copied to the source directory so that when dotnet builds it, it’s already there.
Note that there are still tons of optimizations that can be done here. But at least we can see that npm
modules can be used as libraries for Blazor applications :)