Intro
This time, I will try esbuild to bundle my client-side TypeScript files.
Because I have used Webpack to bundle files, and I will replace them.
Base project
Index.cshtml
<div>
<div id="message_div"></div>
</div>
<script src="/js/index.page.js"></script>
<script>Page.init("hello");</script>
index.page.ts
import { IndexView } from "./index.view";
let view: IndexView;
export function init(message: string) {
view = new IndexView();
view.updateMessage(message);
}
index.view.ts
export class IndexView {
private messageDiv: HTMLElement;
public constructor() {
this.messageDiv = document.getElementById("message_div") as HTMLElement;
}
public updateMessage(message: string): void {
this.messageDiv.textContent = message;
}
}
Bundling files
I can bundle the TypeScript files by command.
(On Windows, I have to change execution policy to run PowerShell scripts first)
./node_modules/.bin/esbuild ./ts/index.page.ts --bundle --outfile=./wwwroot/js/index.page.js
I also can execute it as a JavaScript file.
indexbuild.mjs
import * as esbuild from 'esbuild';
await esbuild.build({
entryPoints: ['ts/index.page.ts'],
bundle: true,
minify: false,
outfile: 'wwwroot/js/index.page.js',
});
I can execute this by Node.js.
node ./esbuilds/indexbuild.mjs
Calling functions from outside of TypeScript
After bundling the files, I will get an exception because "Page is not defined".
The bundled file like below.
index.page.js
"use strict";
(() => {
// ts/index.view.ts
var IndexView = class {
constructor() {
this.messageDiv = document.getElementById("message_div");
}
updateMessage(message) {
this.messageDiv.textContent = message;
}
};
// ts/index.page.ts
var view;
function init(message) {
view = new IndexView();
view.updateMessage(message);
}
})();
To call the function from outside of the TypeScript, I should declare them as global.
index.page.ts
...
(window as any).init = (message: string) => {
view = new IndexView();
view.updateMessage(message);
}
Index.cshtml
...
<script>init("hello");</script>
Add type declaration
To remove "as any", I will add type declaration files.
global.d.ts
declare global {
interface Window {
Page: IndexPageApi,
};
}
export interface IndexPageApi {
init: (message: string) => void,
}
tsconfig.json
{
"compilerOptions": {
/* Language and Environment */
"target": "es2016",
/* Modules */
"module": "commonjs",
"baseUrl": "./",
"paths": {
"*":["*", "./ts/types/*"]
},
/* Emit */
"noEmit": true,
/* Interop Constraints */
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
/* Type Checking */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"useUnknownInCatchVariables": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"exactOptionalPropertyTypes": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"allowUnusedLabels": true,
"allowUnreachableCode": true,
/* Completeness */
"skipLibCheck": true
}
}
index.page.ts
...
window.Page = {
init(message: string) {
view = new IndexView();
view.updateMessage(message);
}
}
Index.cshtml
...
<script>Page.init("hello");</script>
Top comments (0)