The sky is the limit! The idea is to have everything available. Since Blazor is relatively new, there aren’t many packages, but don’t worry. I will show you how to include NPM packages with your Blazor Hybrid app and make everything bulletproof by adding TypeScript. Since Microsoft does not natively support .ts
or .js
files, we’ll include that support. Microsoft will be jealous! 😄
Requirement
- For the purpose of this tutorial let's clone this repo branch
Setup
-
Navigate to
MyBlazorHybridApp
and create a new directory namednpm
. -
Open a new terminal in that directory or
cd
into it. -
Create a
package.json
file:npm init -y
-
Install necessary packages:
npm install typescript ts-loader webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env --save-dev
-
Initialize a TypeScript configuration file:
npx tsc --init
-
Create a new file named
webpack.config.js
and add the following content:const path = require('path'); const fs = require('fs'); function findFiles(dir, extensions, fileList = []) { const files = fs.readdirSync(dir); files.forEach((file) => { const fullPath = path.join(dir, file); const stat = fs.statSync(fullPath); if (stat.isDirectory()) { findFiles(fullPath, extensions, fileList); } else if (extensions.includes(path.extname(file).toLowerCase())) { fileList.push(fullPath); } }); return fileList; } module.exports = (env, argv) => { const mode = argv.mode || 'development'; const entry = [ ...findFiles(path.resolve(__dirname, '../Views'), ['.ts', '.js', '.razor.ts', '.razor.js']), './src/index.ts', ]; return { mode, devtool: mode === 'development' ? 'source-map' : false, entry, output: { filename: 'index.bundle.js', path: path.resolve(__dirname, '../wwwroot/js'), }, module: { rules: [ { test: /\.ts$/, use: 'ts-loader', exclude: /node_modules/, }, { test: /\.js$/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] }, }, exclude: /node_modules/, }, ], }, resolve: { extensions: ['.ts', '.js'] }, devServer: { static: path.resolve(__dirname, '../wwwroot'), compress: true, port: 9000, }, }; };
-
Create a
src
directory inside thenpm
folder and add anindex.ts
file with the following content:console.log("Hello from TypeScript");
-
Update the
tsconfig.json
file with the following:{ "compilerOptions": { "target": "es6", "module": "es6", "strict": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "skipLibCheck": true, "sourceMap": true }, "include": ["src/**/*.ts"], "exclude": ["node_modules"] }
-
Add the following scripts to
package.json
:"scripts": { "build": "webpack --mode production", "build-dev": "webpack --mode development", "debug": "webpack serve" },
Consuming the Script
-
Add the
index.bundle.js
script to your app:- For
BlazorHybridApp.Web
, add the following towwwroot/index.html
:<script src="_content/MyBlazorHybridApp/js/index.bundle.js"></script>
- For
BlazorHybridApp.Maui
, add the same script towwwroot/index.html
.
- For
-
Modify the
MyBlazorHybridApp.csproj
file to automate the build process:<Target Name="NpmBuild" AfterTargets="Compile"> <Exec Command="npm install" WorkingDirectory="npm" /> <Exec Command="npm run build-dev" WorkingDirectory="npm" Condition="'$(Configuration)' == 'Debug'" /> <Exec Command="npm run build" WorkingDirectory="npm" Condition="'$(Configuration)' == 'Release'" /> </Target>
Testing
-
Add a new file named
Home.razor.js
in theViews
directory with the following content:// Show alert message window.showAlert = (message) => { alert(message); };
-
Update the
home.razor.cs
file:using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; namespace MyBlazorHybridApp.Views; public partial class Home { [Inject] private IJSRuntime JS { get; set; } = default!; private async Task TriggerAlert() { // Call JavaScript function from Blazor await JS.InvokeVoidAsync("showAlert", "Button clicked from Razor component!"); } }
-
Add a button in
home.razor
to trigger the alert:<button @onclick="TriggerAlert">Click Me</button>
Run your app and test the functionality. If everything was set up correctly, clicking the button should display an alert.